Completed
Branch BUG-10911-php-7.2 (fa9379)
by
unknown
45:02 queued 34:20
created
core/admin/EE_Admin_Page.core.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
      * this method simply verifies a given route and makes sure its an actual route available for the loaded page
898 898
      *
899 899
      * @param  string $route the route name we're verifying
900
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
900
+     * @return boolean (bool|Exception)      we'll throw an exception if this isn't a valid route.
901 901
      * @throws EE_Error
902 902
      */
903 903
     protected function _verify_route($route)
@@ -4039,7 +4039,7 @@  discard block
 block discarded – undo
4039 4039
 
4040 4040
 
4041 4041
     /**
4042
-     * @return mixed
4042
+     * @return string[]
4043 4043
      */
4044 4044
     public function default_espresso_metaboxes()
4045 4045
     {
@@ -4059,7 +4059,7 @@  discard block
 block discarded – undo
4059 4059
 
4060 4060
 
4061 4061
     /**
4062
-     * @return mixed
4062
+     * @return string
4063 4063
      */
4064 4064
     public function wp_page_slug()
4065 4065
     {
Please login to merge, or discard this patch.
Indentation   +4098 added lines, -4098 removed lines patch added patch discarded remove patch
@@ -20,4183 +20,4183 @@
 block discarded – undo
20 20
 {
21 21
 
22 22
 
23
-    //set in _init_page_props()
24
-    public $page_slug;
23
+	//set in _init_page_props()
24
+	public $page_slug;
25 25
 
26
-    public $page_label;
26
+	public $page_label;
27 27
 
28
-    public $page_folder;
28
+	public $page_folder;
29 29
 
30
-    //set in define_page_props()
31
-    protected $_admin_base_url;
30
+	//set in define_page_props()
31
+	protected $_admin_base_url;
32 32
 
33
-    protected $_admin_base_path;
33
+	protected $_admin_base_path;
34 34
 
35
-    protected $_admin_page_title;
35
+	protected $_admin_page_title;
36 36
 
37
-    protected $_labels;
37
+	protected $_labels;
38 38
 
39 39
 
40
-    //set early within EE_Admin_Init
41
-    protected $_wp_page_slug;
40
+	//set early within EE_Admin_Init
41
+	protected $_wp_page_slug;
42 42
 
43
-    //navtabs
44
-    protected $_nav_tabs;
43
+	//navtabs
44
+	protected $_nav_tabs;
45 45
 
46
-    protected $_default_nav_tab_name;
46
+	protected $_default_nav_tab_name;
47 47
 
48
-    /**
49
-     * @var array $_help_tour
50
-     */
51
-    protected $_help_tour = array();
48
+	/**
49
+	 * @var array $_help_tour
50
+	 */
51
+	protected $_help_tour = array();
52 52
 
53 53
 
54
-    //template variables (used by templates)
55
-    protected $_template_path;
54
+	//template variables (used by templates)
55
+	protected $_template_path;
56 56
 
57
-    protected $_column_template_path;
57
+	protected $_column_template_path;
58 58
 
59
-    /**
60
-     * @var array $_template_args
61
-     */
62
-    protected $_template_args = array();
59
+	/**
60
+	 * @var array $_template_args
61
+	 */
62
+	protected $_template_args = array();
63 63
 
64
-    /**
65
-     * this will hold the list table object for a given view.
66
-     *
67
-     * @var EE_Admin_List_Table $_list_table_object
68
-     */
69
-    protected $_list_table_object;
64
+	/**
65
+	 * this will hold the list table object for a given view.
66
+	 *
67
+	 * @var EE_Admin_List_Table $_list_table_object
68
+	 */
69
+	protected $_list_table_object;
70 70
 
71
-    //bools
72
-    protected $_is_UI_request = null; //this starts at null so we can have no header routes progress through two states.
71
+	//bools
72
+	protected $_is_UI_request = null; //this starts at null so we can have no header routes progress through two states.
73 73
 
74
-    protected $_routing;
74
+	protected $_routing;
75 75
 
76
-    //list table args
77
-    protected $_view;
76
+	//list table args
77
+	protected $_view;
78 78
 
79
-    protected $_views;
79
+	protected $_views;
80 80
 
81 81
 
82
-    //action => method pairs used for routing incoming requests
83
-    protected $_page_routes;
82
+	//action => method pairs used for routing incoming requests
83
+	protected $_page_routes;
84 84
 
85
-    /**
86
-     * @var array $_page_config
87
-     */
88
-    protected $_page_config;
85
+	/**
86
+	 * @var array $_page_config
87
+	 */
88
+	protected $_page_config;
89 89
 
90
-    /**
91
-     * the current page route and route config
92
-     *
93
-     * @var string $_route
94
-     */
95
-    protected $_route;
90
+	/**
91
+	 * the current page route and route config
92
+	 *
93
+	 * @var string $_route
94
+	 */
95
+	protected $_route;
96 96
 
97
-    /**
98
-     * @var string $_cpt_route
99
-     */
100
-    protected $_cpt_route;
97
+	/**
98
+	 * @var string $_cpt_route
99
+	 */
100
+	protected $_cpt_route;
101 101
 
102
-    /**
103
-     * @var array $_route_config
104
-     */
105
-    protected $_route_config;
102
+	/**
103
+	 * @var array $_route_config
104
+	 */
105
+	protected $_route_config;
106 106
 
107
-    /**
108
-     * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
109
-     * actions.
110
-     *
111
-     * @since 4.6.x
112
-     * @var array.
113
-     */
114
-    protected $_default_route_query_args;
115
-
116
-    //set via request page and action args.
117
-    protected $_current_page;
107
+	/**
108
+	 * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
109
+	 * actions.
110
+	 *
111
+	 * @since 4.6.x
112
+	 * @var array.
113
+	 */
114
+	protected $_default_route_query_args;
115
+
116
+	//set via request page and action args.
117
+	protected $_current_page;
118 118
 
119
-    protected $_current_view;
119
+	protected $_current_view;
120 120
 
121
-    protected $_current_page_view_url;
121
+	protected $_current_page_view_url;
122 122
 
123
-    //sanitized request action (and nonce)
123
+	//sanitized request action (and nonce)
124 124
 
125
-    /**
126
-     * @var string $_req_action
127
-     */
128
-    protected $_req_action;
129
-
130
-    /**
131
-     * @var string $_req_nonce
132
-     */
133
-    protected $_req_nonce;
134
-
135
-    //search related
136
-    protected $_search_btn_label;
137
-
138
-    protected $_search_box_callback;
139
-
140
-    /**
141
-     * WP Current Screen object
142
-     *
143
-     * @var WP_Screen
144
-     */
145
-    protected $_current_screen;
146
-
147
-    //for holding EE_Admin_Hooks object when needed (set via set_hook_object())
148
-    protected $_hook_obj;
149
-
150
-    //for holding incoming request data
151
-    protected $_req_data;
152
-
153
-    // yes / no array for admin form fields
154
-    protected $_yes_no_values = array();
155
-
156
-    //some default things shared by all child classes
157
-    protected $_default_espresso_metaboxes;
158
-
159
-    /**
160
-     *    EE_Registry Object
161
-     *
162
-     * @var    EE_Registry
163
-     */
164
-    protected $EE = null;
165
-
166
-
167
-
168
-    /**
169
-     * This is just a property that flags whether the given route is a caffeinated route or not.
170
-     *
171
-     * @var boolean
172
-     */
173
-    protected $_is_caf = false;
174
-
175
-
176
-
177
-    /**
178
-     * @Constructor
179
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
-     * @throws EE_Error
181
-     * @throws InvalidArgumentException
182
-     * @throws ReflectionException
183
-     * @throws InvalidDataTypeException
184
-     * @throws InvalidInterfaceException
185
-     */
186
-    public function __construct($routing = true)
187
-    {
188
-        if (strpos($this->_get_dir(), 'caffeinated') !== false) {
189
-            $this->_is_caf = true;
190
-        }
191
-        $this->_yes_no_values = array(
192
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
193
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
194
-        );
195
-        //set the _req_data property.
196
-        $this->_req_data = array_merge($_GET, $_POST);
197
-        //routing enabled?
198
-        $this->_routing = $routing;
199
-        //set initial page props (child method)
200
-        $this->_init_page_props();
201
-        //set global defaults
202
-        $this->_set_defaults();
203
-        //set early because incoming requests could be ajax related and we need to register those hooks.
204
-        $this->_global_ajax_hooks();
205
-        $this->_ajax_hooks();
206
-        //other_page_hooks have to be early too.
207
-        $this->_do_other_page_hooks();
208
-        //This just allows us to have extending classes do something specific
209
-        // before the parent constructor runs _page_setup().
210
-        if (method_exists($this, '_before_page_setup')) {
211
-            $this->_before_page_setup();
212
-        }
213
-        //set up page dependencies
214
-        $this->_page_setup();
215
-    }
216
-
217
-
218
-
219
-    /**
220
-     * _init_page_props
221
-     * Child classes use to set at least the following properties:
222
-     * $page_slug.
223
-     * $page_label.
224
-     *
225
-     * @abstract
226
-     * @return void
227
-     */
228
-    abstract protected function _init_page_props();
229
-
230
-
231
-
232
-    /**
233
-     * _ajax_hooks
234
-     * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
235
-     * Note: within the ajax callback methods.
236
-     *
237
-     * @abstract
238
-     * @return void
239
-     */
240
-    abstract protected function _ajax_hooks();
241
-
242
-
243
-
244
-    /**
245
-     * _define_page_props
246
-     * child classes define page properties in here.  Must include at least:
247
-     * $_admin_base_url = base_url for all admin pages
248
-     * $_admin_page_title = default admin_page_title for admin pages
249
-     * $_labels = array of default labels for various automatically generated elements:
250
-     *    array(
251
-     *        'buttons' => array(
252
-     *            'add' => esc_html__('label for add new button'),
253
-     *            'edit' => esc_html__('label for edit button'),
254
-     *            'delete' => esc_html__('label for delete button')
255
-     *            )
256
-     *        )
257
-     *
258
-     * @abstract
259
-     * @return void
260
-     */
261
-    abstract protected function _define_page_props();
262
-
263
-
264
-
265
-    /**
266
-     * _set_page_routes
267
-     * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
268
-     * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
269
-     * have a 'default' route. Here's the format
270
-     * $this->_page_routes = array(
271
-     *        'default' => array(
272
-     *            'func' => '_default_method_handling_route',
273
-     *            'args' => array('array','of','args'),
274
-     *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
275
-     *            ajax request, backend processing)
276
-     *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
277
-     *            headers route after.  The string you enter here should match the defined route reference for a
278
-     *            headers sent route.
279
-     *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
280
-     *            this route.
281
-     *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
282
-     *            checks).
283
-     *        ),
284
-     *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
285
-     *        handling method.
286
-     *        )
287
-     * )
288
-     *
289
-     * @abstract
290
-     * @return void
291
-     */
292
-    abstract protected function _set_page_routes();
293
-
294
-
295
-
296
-    /**
297
-     * _set_page_config
298
-     * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
299
-     * array corresponds to the page_route for the loaded page. Format:
300
-     * $this->_page_config = array(
301
-     *        'default' => array(
302
-     *            'labels' => array(
303
-     *                'buttons' => array(
304
-     *                    'add' => esc_html__('label for adding item'),
305
-     *                    'edit' => esc_html__('label for editing item'),
306
-     *                    'delete' => esc_html__('label for deleting item')
307
-     *                ),
308
-     *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
309
-     *            ), //optional an array of custom labels for various automatically generated elements to use on the
310
-     *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
311
-     *            _define_page_props() method
312
-     *            'nav' => array(
313
-     *                'label' => esc_html__('Label for Tab', 'event_espresso').
314
-     *                'url' => 'http://someurl', //automatically generated UNLESS you define
315
-     *                'css_class' => 'css-class', //automatically generated UNLESS you define
316
-     *                'order' => 10, //required to indicate tab position.
317
-     *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
318
-     *                displayed then add this parameter.
319
-     *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
320
-     *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
321
-     *            metaboxes set for eventespresso admin pages.
322
-     *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
323
-     *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
324
-     *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
325
-     *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
326
-     *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
327
-     *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
328
-     *            array indicates the max number of columns (4) and the default number of columns on page load (2).
329
-     *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
330
-     *            want to display.
331
-     *            'help_tabs' => array( //this is used for adding help tabs to a page
332
-     *                'tab_id' => array(
333
-     *                    'title' => 'tab_title',
334
-     *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
335
-     *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
336
-     *                    should match a file in the admin folder's "help_tabs" dir (ie..
337
-     *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
338
-     *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
339
-     *                    attempt to use the callback which should match the name of a method in the class
340
-     *                    ),
341
-     *                'tab2_id' => array(
342
-     *                    'title' => 'tab2 title',
343
-     *                    'filename' => 'file_name_2'
344
-     *                    'callback' => 'callback_method_for_content',
345
-     *                 ),
346
-     *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
347
-     *            help tab area on an admin page. @link
348
-     *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
349
-     *            'help_tour' => array(
350
-     *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
351
-     *                in a folder for this admin page named "help_tours", a file name matching the key given here
352
-     *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
353
-     *            ),
354
-     *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
355
-     *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
356
-     *            just set
357
-     *            'require_nonce' to FALSE
358
-     *            )
359
-     * )
360
-     *
361
-     * @abstract
362
-     * @return void
363
-     */
364
-    abstract protected function _set_page_config();
365
-
366
-
367
-
368
-
369
-
370
-    /** end sample help_tour methods **/
371
-    /**
372
-     * _add_screen_options
373
-     * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
374
-     * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
375
-     * to a particular view.
376
-     *
377
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
378
-     *         see also WP_Screen object documents...
379
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
380
-     * @abstract
381
-     * @return void
382
-     */
383
-    abstract protected function _add_screen_options();
384
-
385
-
386
-
387
-    /**
388
-     * _add_feature_pointers
389
-     * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
390
-     * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
391
-     * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
392
-     * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
393
-     * extended) also see:
394
-     *
395
-     * @link   http://eamann.com/tech/wordpress-portland/
396
-     * @abstract
397
-     * @return void
398
-     */
399
-    abstract protected function _add_feature_pointers();
400
-
401
-
402
-
403
-    /**
404
-     * load_scripts_styles
405
-     * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
406
-     * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
407
-     * scripts/styles per view by putting them in a dynamic function in this format
408
-     * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
409
-     *
410
-     * @abstract
411
-     * @return void
412
-     */
413
-    abstract public function load_scripts_styles();
414
-
415
-
416
-
417
-    /**
418
-     * admin_init
419
-     * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
420
-     * all pages/views loaded by child class.
421
-     *
422
-     * @abstract
423
-     * @return void
424
-     */
425
-    abstract public function admin_init();
426
-
427
-
428
-
429
-    /**
430
-     * admin_notices
431
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
432
-     * all pages/views loaded by child class.
433
-     *
434
-     * @abstract
435
-     * @return void
436
-     */
437
-    abstract public function admin_notices();
438
-
439
-
440
-
441
-    /**
442
-     * admin_footer_scripts
443
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
444
-     * will apply to all pages/views loaded by child class.
445
-     *
446
-     * @return void
447
-     */
448
-    abstract public function admin_footer_scripts();
449
-
450
-
451
-
452
-    /**
453
-     * admin_footer
454
-     * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
455
-     * apply to all pages/views loaded by child class.
456
-     *
457
-     * @return void
458
-     */
459
-    public function admin_footer()
460
-    {
461
-    }
462
-
463
-
464
-
465
-    /**
466
-     * _global_ajax_hooks
467
-     * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
468
-     * Note: within the ajax callback methods.
469
-     *
470
-     * @abstract
471
-     * @return void
472
-     */
473
-    protected function _global_ajax_hooks()
474
-    {
475
-        //for lazy loading of metabox content
476
-        add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
477
-    }
478
-
479
-
480
-
481
-    public function ajax_metabox_content()
482
-    {
483
-        $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
484
-        $url       = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
485
-        self::cached_rss_display($contentid, $url);
486
-        wp_die();
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * _page_setup
493
-     * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
494
-     * doesn't match the object.
495
-     *
496
-     * @final
497
-     * @return void
498
-     * @throws EE_Error
499
-     * @throws InvalidArgumentException
500
-     * @throws ReflectionException
501
-     * @throws InvalidDataTypeException
502
-     * @throws InvalidInterfaceException
503
-     */
504
-    final protected function _page_setup()
505
-    {
506
-        //requires?
507
-        //admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can.  But keep in mind, not everything is available from the EE_Admin Page object at this point.
508
-        add_action('admin_init', array($this, 'admin_init_global'), 5);
509
-        //next verify if we need to load anything...
510
-        $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
511
-        $this->page_folder   = strtolower(
512
-            str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
513
-        );
514
-        global $ee_menu_slugs;
515
-        $ee_menu_slugs = (array)$ee_menu_slugs;
516
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
517
-            return;
518
-        }
519
-        // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
520
-        if (isset($this->_req_data['action2']) && $this->_req_data['action'] === -1) {
521
-            $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== -1
522
-                ? $this->_req_data['action2']
523
-                : $this->_req_data['action'];
524
-        }
525
-        // then set blank or -1 action values to 'default'
526
-        $this->_req_action = isset($this->_req_data['action'])
527
-                             && ! empty($this->_req_data['action'])
528
-                             && $this->_req_data['action'] !== -1
529
-            ? sanitize_key($this->_req_data['action'])
530
-            : 'default';
531
-        // if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
532
-        //  This covers cases where we're coming in from a list table that isn't on the default route.
533
-        $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
534
-            ? $this->_req_data['route'] : $this->_req_action;
535
-        //however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
536
-        $this->_req_action   = defined('DOING_AJAX') && isset($this->_req_data['route'])
537
-            ? $this->_req_data['route']
538
-            : $this->_req_action;
539
-        $this->_current_view = $this->_req_action;
540
-        $this->_req_nonce    = $this->_req_action . '_nonce';
541
-        $this->_define_page_props();
542
-        $this->_current_page_view_url = add_query_arg(
543
-            array('page' => $this->_current_page, 'action' => $this->_current_view),
544
-            $this->_admin_base_url
545
-        );
546
-        //default things
547
-        $this->_default_espresso_metaboxes = array(
548
-            '_espresso_news_post_box',
549
-            '_espresso_links_post_box',
550
-            '_espresso_ratings_request',
551
-            '_espresso_sponsors_post_box',
552
-        );
553
-        //set page configs
554
-        $this->_set_page_routes();
555
-        $this->_set_page_config();
556
-        //let's include any referrer data in our default_query_args for this route for "stickiness".
557
-        if (isset($this->_req_data['wp_referer'])) {
558
-            $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
559
-        }
560
-        //for caffeinated and other extended functionality.
561
-        //  If there is a _extend_page_config method
562
-        // then let's run that to modify the all the various page configuration arrays
563
-        if (method_exists($this, '_extend_page_config')) {
564
-            $this->_extend_page_config();
565
-        }
566
-        //for CPT and other extended functionality.
567
-        // If there is an _extend_page_config_for_cpt
568
-        // then let's run that to modify all the various page configuration arrays.
569
-        if (method_exists($this, '_extend_page_config_for_cpt')) {
570
-            $this->_extend_page_config_for_cpt();
571
-        }
572
-        //filter routes and page_config so addons can add their stuff. Filtering done per class
573
-        $this->_page_routes = apply_filters(
574
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
575
-            $this->_page_routes,
576
-            $this
577
-        );
578
-        $this->_page_config = apply_filters(
579
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
580
-            $this->_page_config,
581
-            $this
582
-        );
583
-        //if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
584
-        // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
585
-        if (
586
-            method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)
587
-        ) {
588
-            add_action(
589
-                'AHEE__EE_Admin_Page__route_admin_request',
590
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
591
-                10,
592
-                2
593
-            );
594
-        }
595
-        //next route only if routing enabled
596
-        if ($this->_routing && ! defined('DOING_AJAX')) {
597
-            $this->_verify_routes();
598
-            //next let's just check user_access and kill if no access
599
-            $this->check_user_access();
600
-            if ($this->_is_UI_request) {
601
-                //admin_init stuff - global, all views for this page class, specific view
602
-                add_action('admin_init', array($this, 'admin_init'), 10);
603
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
604
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
605
-                }
606
-            } else {
607
-                //hijack regular WP loading and route admin request immediately
608
-                @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
609
-                $this->route_admin_request();
610
-            }
611
-        }
612
-    }
613
-
614
-
615
-
616
-    /**
617
-     * Provides a way for related child admin pages to load stuff on the loaded admin page.
618
-     *
619
-     * @return void
620
-     * @throws ReflectionException
621
-     * @throws EE_Error
622
-     */
623
-    private function _do_other_page_hooks()
624
-    {
625
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
626
-        foreach ($registered_pages as $page) {
627
-            //now let's setup the file name and class that should be present
628
-            $classname = str_replace('.class.php', '', $page);
629
-            //autoloaders should take care of loading file
630
-            if (! class_exists($classname)) {
631
-                $error_msg[] = sprintf(
632
-                    esc_html__(
633
-                        'Something went wrong with loading the %s admin hooks page.',
634
-                        'event_espresso'
635
-                    ),
636
-                    $page
637
-                );
638
-                $error_msg[] = $error_msg[0]
639
-                               . "\r\n"
640
-                               . sprintf(
641
-                                   esc_html__(
642
-                                       'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
643
-                                       'event_espresso'
644
-                                   ),
645
-                                   $page,
646
-                                   '<br />',
647
-                                   '<strong>' . $classname . '</strong>'
648
-                               );
649
-                throw new EE_Error(implode('||', $error_msg));
650
-            }
651
-            $a = new ReflectionClass($classname);
652
-            //notice we are passing the instance of this class to the hook object.
653
-            $hookobj[] = $a->newInstance($this);
654
-        }
655
-    }
656
-
657
-
658
-
659
-    public function load_page_dependencies()
660
-    {
661
-        try {
662
-            $this->_load_page_dependencies();
663
-        } catch (EE_Error $e) {
664
-            $e->get_error();
665
-        }
666
-    }
667
-
668
-
669
-
670
-    /**
671
-     * load_page_dependencies
672
-     * loads things specific to this page class when its loaded.  Really helps with efficiency.
673
-     *
674
-     * @return void
675
-     * @throws DomainException
676
-     * @throws EE_Error
677
-     * @throws InvalidArgumentException
678
-     * @throws InvalidDataTypeException
679
-     * @throws InvalidInterfaceException
680
-     * @throws ReflectionException
681
-     */
682
-    protected function _load_page_dependencies()
683
-    {
684
-        //let's set the current_screen and screen options to override what WP set
685
-        $this->_current_screen = get_current_screen();
686
-        //load admin_notices - global, page class, and view specific
687
-        add_action('admin_notices', array($this, 'admin_notices_global'), 5);
688
-        add_action('admin_notices', array($this, 'admin_notices'), 10);
689
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
690
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
691
-        }
692
-        //load network admin_notices - global, page class, and view specific
693
-        add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
694
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
695
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
696
-        }
697
-        //this will save any per_page screen options if they are present
698
-        $this->_set_per_page_screen_options();
699
-        //setup list table properties
700
-        $this->_set_list_table();
701
-        // child classes can "register" a metabox to be automatically handled via the _page_config array property.
702
-        // However in some cases the metaboxes will need to be added within a route handling callback.
703
-        $this->_add_registered_meta_boxes();
704
-        $this->_add_screen_columns();
705
-        //add screen options - global, page child class, and view specific
706
-        $this->_add_global_screen_options();
707
-        $this->_add_screen_options();
708
-        $add_screen_options  = "_add_screen_options_{$this->_current_view}";
709
-        if (method_exists($this, $add_screen_options )) {
710
-            $this->{$add_screen_options};
711
-        }
712
-        //add help tab(s) and tours- set via page_config and qtips.
713
-        $this->_add_help_tour();
714
-        $this->_add_help_tabs();
715
-        $this->_add_qtips();
716
-        //add feature_pointers - global, page child class, and view specific
717
-        $this->_add_feature_pointers();
718
-        $this->_add_global_feature_pointers();
719
-        $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
720
-        if (method_exists($this, $add_feature_pointer )) {
721
-            $this->{$add_feature_pointer};
722
-        }
723
-        //enqueue scripts/styles - global, page class, and view specific
724
-        add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
725
-        add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
726
-        if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
727
-            add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
728
-        }
729
-        add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
730
-        // admin_print_footer_scripts - global, page child class, and view specific.
731
-        // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
732
-        // In most cases that's doing_it_wrong().  But adding hidden container elements etc.
733
-        // is a good use case. Notice the late priority we're giving these
734
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
735
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
736
-        if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
737
-            add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
738
-        }
739
-        //admin footer scripts
740
-        add_action('admin_footer', array($this, 'admin_footer_global'), 99);
741
-        add_action('admin_footer', array($this, 'admin_footer'), 100);
742
-        if (method_exists($this, "admin_footer_{$this->_current_view}")) {
743
-            add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
744
-        }
745
-        do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
746
-        //targeted hook
747
-        do_action(
748
-            "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
749
-
750
-        );
751
-    }
752
-
753
-
754
-
755
-    /**
756
-     * _set_defaults
757
-     * This sets some global defaults for class properties.
758
-     */
759
-    private function _set_defaults()
760
-    {
761
-        $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
762
-        $this->_event = $this->_template_path = $this->_column_template_path = null;
763
-        $this->_nav_tabs = $this->_views = $this->_page_routes = array();
764
-        $this->_page_config = $this->_default_route_query_args = array();
765
-        $this->_default_nav_tab_name = 'overview';
766
-        //init template args
767
-        $this->_template_args = array(
768
-            'admin_page_header'  => '',
769
-            'admin_page_content' => '',
770
-            'post_body_content'  => '',
771
-            'before_list_table'  => '',
772
-            'after_list_table'   => '',
773
-        );
774
-    }
775
-
776
-
777
-
778
-    /**
779
-     * route_admin_request
780
-     *
781
-     * @see    _route_admin_request()
782
-     * @return exception|void error
783
-     * @throws InvalidArgumentException
784
-     * @throws InvalidInterfaceException
785
-     * @throws InvalidDataTypeException
786
-     * @throws EE_Error
787
-     * @throws ReflectionException
788
-     */
789
-    public function route_admin_request()
790
-    {
791
-        try {
792
-            $this->_route_admin_request();
793
-        } catch (EE_Error $e) {
794
-            $e->get_error();
795
-        }
796
-    }
797
-
798
-
799
-
800
-    public function set_wp_page_slug($wp_page_slug)
801
-    {
802
-        $this->_wp_page_slug = $wp_page_slug;
803
-        //if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
804
-        if (is_network_admin()) {
805
-            $this->_wp_page_slug .= '-network';
806
-        }
807
-    }
808
-
809
-
810
-
811
-    /**
812
-     * _verify_routes
813
-     * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
814
-     * we know if we need to drop out.
815
-     *
816
-     * @return bool
817
-     * @throws EE_Error
818
-     */
819
-    protected function _verify_routes()
820
-    {
821
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
822
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
823
-            return false;
824
-        }
825
-        $this->_route = false;
826
-        // check that the page_routes array is not empty
827
-        if (empty($this->_page_routes)) {
828
-            // user error msg
829
-            $error_msg = sprintf(
830
-                esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
831
-                $this->_admin_page_title
832
-            );
833
-            // developer error msg
834
-            $error_msg .= '||' . $error_msg . esc_html__(
835
-                ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
836
-                'event_espresso'
837
-            );
838
-            throw new EE_Error($error_msg);
839
-        }
840
-        // and that the requested page route exists
841
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
842
-            $this->_route        = $this->_page_routes[$this->_req_action];
843
-            $this->_route_config = isset($this->_page_config[$this->_req_action])
844
-                ? $this->_page_config[$this->_req_action] : array();
845
-        } else {
846
-            // user error msg
847
-            $error_msg = sprintf(
848
-                esc_html__(
849
-                        'The requested page route does not exist for the %s admin page.',
850
-                        'event_espresso'
851
-                ),
852
-                $this->_admin_page_title
853
-            );
854
-            // developer error msg
855
-            $error_msg .= '||' . $error_msg . sprintf(
856
-                    esc_html__(
857
-                        ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
858
-                        'event_espresso'
859
-                    ),
860
-                    $this->_req_action
861
-                );
862
-            throw new EE_Error($error_msg);
863
-        }
864
-        // and that a default route exists
865
-        if (! array_key_exists('default', $this->_page_routes)) {
866
-            // user error msg
867
-            $error_msg = sprintf(
868
-                esc_html__(
869
-                        'A default page route has not been set for the % admin page.',
870
-                        'event_espresso'
871
-                ),
872
-                $this->_admin_page_title
873
-            );
874
-            // developer error msg
875
-            $error_msg .= '||' . $error_msg . esc_html__(
876
-                ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
877
-                'event_espresso'
878
-            );
879
-            throw new EE_Error($error_msg);
880
-        }
881
-        //first lets' catch if the UI request has EVER been set.
882
-        if ($this->_is_UI_request === null) {
883
-            //lets set if this is a UI request or not.
884
-            $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
885
-            //wait a minute... we might have a noheader in the route array
886
-            $this->_is_UI_request = is_array($this->_route)
887
-                                    && isset($this->_route['noheader'])
888
-                                    && $this->_route['noheader'] ? false : $this->_is_UI_request;
889
-        }
890
-        $this->_set_current_labels();
891
-        return true;
892
-    }
893
-
894
-
895
-
896
-    /**
897
-     * this method simply verifies a given route and makes sure its an actual route available for the loaded page
898
-     *
899
-     * @param  string $route the route name we're verifying
900
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
901
-     * @throws EE_Error
902
-     */
903
-    protected function _verify_route($route)
904
-    {
905
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
906
-            return true;
907
-        }
908
-        // user error msg
909
-        $error_msg = sprintf(
910
-            esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
911
-            $this->_admin_page_title
912
-        );
913
-        // developer error msg
914
-        $error_msg .= '||' . $error_msg . sprintf(
915
-                esc_html__(
916
-                    ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
917
-                    'event_espresso'
918
-                ),
919
-                $route
920
-            );
921
-        throw new EE_Error($error_msg);
922
-    }
923
-
924
-
925
-
926
-    /**
927
-     * perform nonce verification
928
-     * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
929
-     * using this method (and save retyping!)
930
-     *
931
-     * @param  string $nonce     The nonce sent
932
-     * @param  string $nonce_ref The nonce reference string (name0)
933
-     * @return void
934
-     * @throws EE_Error
935
-     */
936
-    protected function _verify_nonce($nonce, $nonce_ref)
937
-    {
938
-        // verify nonce against expected value
939
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
940
-            // these are not the droids you are looking for !!!
941
-            $msg = sprintf(
942
-                esc_html__('%sNonce Fail.%s', 'event_espresso'),
943
-                '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
944
-                '</a>'
945
-            );
946
-            if (WP_DEBUG) {
947
-                $msg .= "\n  " . sprintf(
948
-                        esc_html__(
949
-                            'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
950
-                            'event_espresso'
951
-                        ),
952
-                        __CLASS__
953
-                    );
954
-            }
955
-            if (! defined('DOING_AJAX')) {
956
-                wp_die($msg);
957
-            } else {
958
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
959
-                $this->_return_json();
960
-            }
961
-        }
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     * _route_admin_request()
968
-     * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if theres are
969
-     * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
970
-     * in the page routes and then will try to load the corresponding method.
971
-     *
972
-     * @return void
973
-     * @throws EE_Error
974
-     * @throws InvalidArgumentException
975
-     * @throws InvalidDataTypeException
976
-     * @throws InvalidInterfaceException
977
-     * @throws ReflectionException
978
-     */
979
-    protected function _route_admin_request()
980
-    {
981
-        if (! $this->_is_UI_request) {
982
-            $this->_verify_routes();
983
-        }
984
-        $nonce_check = isset($this->_route_config['require_nonce'])
985
-            ? $this->_route_config['require_nonce']
986
-            : true;
987
-        if ($this->_req_action !== 'default' && $nonce_check) {
988
-            // set nonce from post data
989
-            $nonce = isset($this->_req_data[$this->_req_nonce])
990
-                ? sanitize_text_field($this->_req_data[$this->_req_nonce])
991
-                : '';
992
-            $this->_verify_nonce($nonce, $this->_req_nonce);
993
-        }
994
-        //set the nav_tabs array but ONLY if this is  UI_request
995
-        if ($this->_is_UI_request) {
996
-            $this->_set_nav_tabs();
997
-        }
998
-        // grab callback function
999
-        $func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
1000
-        // check if callback has args
1001
-        $args      = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1002
-        $error_msg = '';
1003
-        // action right before calling route
1004
-        // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1005
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1006
-            do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1007
-        }
1008
-        // right before calling the route, let's remove _wp_http_referer from the
1009
-        // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1010
-        $_SERVER['REQUEST_URI'] = remove_query_arg(
1011
-                '_wp_http_referer',
1012
-                wp_unslash($_SERVER['REQUEST_URI'])
1013
-        );
1014
-        if (! empty($func)) {
1015
-            if (is_array($func)) {
1016
-                list($class, $method) = $func;
1017
-            } elseif (strpos($func, '::') !== false) {
1018
-                list($class, $method) = explode('::', $func);
1019
-            } else {
1020
-                $class  = $this;
1021
-                $method = $func;
1022
-            }
1023
-            if (! (is_object($class) && $class === $this)) {
1024
-                // send along this admin page object for access by addons.
1025
-                $args['admin_page_object'] = $this;
1026
-            }
1027
-            if (
1028
-                //is it a method on a class that doesn't work?
1029
-                (
1030
-                    (
1031
-                        method_exists($class, $method)
1032
-                        && call_user_func_array(array($class, $method), $args) === false
1033
-                    )
1034
-                    && (
1035
-                        //is it a standalone function that doesn't work?
1036
-                        function_exists($method)
1037
-                        && call_user_func_array(
1038
-                            $func,
1039
-                            array_merge(array('admin_page_object' => $this), $args)
1040
-                           ) === false
1041
-                    )
1042
-                )
1043
-                || (
1044
-                    //is it neither a class method NOR a standalone function?
1045
-                    ! method_exists($class, $method)
1046
-                    && ! function_exists($method)
1047
-                )
1048
-            ) {
1049
-                // user error msg
1050
-                $error_msg = esc_html__(
1051
-                    'An error occurred. The  requested page route could not be found.',
1052
-                    'event_espresso'
1053
-                );
1054
-                // developer error msg
1055
-                $error_msg .= '||';
1056
-                $error_msg .= sprintf(
1057
-                    esc_html__(
1058
-                        'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1059
-                        'event_espresso'
1060
-                    ),
1061
-                    $method
1062
-                );
1063
-            }
1064
-            if (! empty($error_msg)) {
1065
-                throw new EE_Error($error_msg);
1066
-            }
1067
-        }
1068
-        // if we've routed and this route has a no headers route AND a sent_headers_route,
1069
-        // then we need to reset the routing properties to the new route.
1070
-        //now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1071
-        if ($this->_is_UI_request === false
1072
-            && is_array($this->_route)
1073
-            && ! empty($this->_route['headers_sent_route'])
1074
-        ) {
1075
-            $this->_reset_routing_properties($this->_route['headers_sent_route']);
1076
-        }
1077
-    }
1078
-
1079
-
1080
-
1081
-    /**
1082
-     * This method just allows the resetting of page properties in the case where a no headers
1083
-     * route redirects to a headers route in its route config.
1084
-     *
1085
-     * @since   4.3.0
1086
-     * @param  string $new_route New (non header) route to redirect to.
1087
-     * @return   void
1088
-     * @throws ReflectionException
1089
-     * @throws InvalidArgumentException
1090
-     * @throws InvalidInterfaceException
1091
-     * @throws InvalidDataTypeException
1092
-     * @throws EE_Error
1093
-     */
1094
-    protected function _reset_routing_properties($new_route)
1095
-    {
1096
-        $this->_is_UI_request = true;
1097
-        //now we set the current route to whatever the headers_sent_route is set at
1098
-        $this->_req_data['action'] = $new_route;
1099
-        //rerun page setup
1100
-        $this->_page_setup();
1101
-    }
1102
-
1103
-
1104
-
1105
-    /**
1106
-     * _add_query_arg
1107
-     * adds nonce to array of arguments then calls WP add_query_arg function
1108
-     *(internally just uses EEH_URL's function with the same name)
1109
-     *
1110
-     * @param array  $args
1111
-     * @param string $url
1112
-     * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1113
-     *                                        generated url in an associative array indexed by the key 'wp_referer';
1114
-     *                                        Example usage: If the current page is:
1115
-     *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1116
-     *                                        &action=default&event_id=20&month_range=March%202015
1117
-     *                                        &_wpnonce=5467821
1118
-     *                                        and you call:
1119
-     *                                        EE_Admin_Page::add_query_args_and_nonce(
1120
-     *                                        array(
1121
-     *                                        'action' => 'resend_something',
1122
-     *                                        'page=>espresso_registrations'
1123
-     *                                        ),
1124
-     *                                        $some_url,
1125
-     *                                        true
1126
-     *                                        );
1127
-     *                                        It will produce a url in this structure:
1128
-     *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1129
-     *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1130
-     *                                        month_range]=March%202015
1131
-     * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1132
-     * @return string
1133
-     */
1134
-    public static function add_query_args_and_nonce(
1135
-        $args = array(),
1136
-        $url = '',
1137
-        $sticky = false,
1138
-        $exclude_nonce = false
1139
-    ) {
1140
-        //if there is a _wp_http_referer include the values from the request but only if sticky = true
1141
-        if ($sticky) {
1142
-            $request = $_REQUEST;
1143
-            unset($request['_wp_http_referer']);
1144
-            unset($request['wp_referer']);
1145
-            foreach ($request as $key => $value) {
1146
-                //do not add nonces
1147
-                if (strpos($key, 'nonce') !== false) {
1148
-                    continue;
1149
-                }
1150
-                $args['wp_referer[' . $key . ']'] = $value;
1151
-            }
1152
-        }
1153
-        return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1154
-    }
1155
-
1156
-
1157
-
1158
-    /**
1159
-     * This returns a generated link that will load the related help tab.
1160
-     *
1161
-     * @param  string $help_tab_id the id for the connected help tab
1162
-     * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1163
-     * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1164
-     * @uses EEH_Template::get_help_tab_link()
1165
-     * @return string              generated link
1166
-     */
1167
-    protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1168
-    {
1169
-        return EEH_Template::get_help_tab_link(
1170
-            $help_tab_id,
1171
-            $this->page_slug,
1172
-            $this->_req_action,
1173
-            $icon_style,
1174
-            $help_text
1175
-        );
1176
-    }
1177
-
1178
-
1179
-
1180
-    /**
1181
-     * _add_help_tabs
1182
-     * Note child classes define their help tabs within the page_config array.
1183
-     *
1184
-     * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1185
-     * @return void
1186
-     * @throws DomainException
1187
-     * @throws EE_Error
1188
-     */
1189
-    protected function _add_help_tabs()
1190
-    {
1191
-        $tour_buttons = '';
1192
-        if (isset($this->_page_config[$this->_req_action])) {
1193
-            $config = $this->_page_config[$this->_req_action];
1194
-            //is there a help tour for the current route?  if there is let's setup the tour buttons
1195
-            if (isset($this->_help_tour[$this->_req_action])) {
1196
-                $tb           = array();
1197
-                $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1198
-                foreach ($this->_help_tour['tours'] as $tour) {
1199
-                    //if this is the end tour then we don't need to setup a button
1200
-                    if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1201
-                        continue;
1202
-                    }
1203
-                    $tb[] = '<button id="trigger-tour-'
1204
-                            . $tour->get_slug()
1205
-                            . '" class="button-primary trigger-ee-help-tour">'
1206
-                            . $tour->get_label()
1207
-                            . '</button>';
1208
-                }
1209
-                $tour_buttons .= implode('<br />', $tb);
1210
-                $tour_buttons .= '</div></div>';
1211
-            }
1212
-            // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213
-            if (is_array($config) && isset($config['help_sidebar'])) {
1214
-                //check that the callback given is valid
1215
-                if (! method_exists($this, $config['help_sidebar'])) {
1216
-                    throw new EE_Error(
1217
-                        sprintf(
1218
-                            esc_html__(
1219
-                                'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1220
-                                'event_espresso'
1221
-                            ),
1222
-                            $config['help_sidebar'],
1223
-                            get_class($this)
1224
-                        )
1225
-                    );
1226
-                }
1227
-                $content = apply_filters(
1228
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1229
-                    $this->{$config['help_sidebar']}
1230
-                );
1231
-                $content .= $tour_buttons; //add help tour buttons.
1232
-                //do we have any help tours setup?  Cause if we do we want to add the buttons
1233
-                $this->_current_screen->set_help_sidebar($content);
1234
-            }
1235
-            //if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar.
1236
-            if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1237
-                $this->_current_screen->set_help_sidebar($tour_buttons);
1238
-            }
1239
-            //handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1240
-            if (! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1241
-                $_ht['id']      = $this->page_slug;
1242
-                $_ht['title']   = esc_html__('Help Tours', 'event_espresso');
1243
-                $_ht['content'] = '<p>' . esc_html__(
1244
-                        'The buttons to the right allow you to start/restart any help tours available for this page',
1245
-                        'event_espresso'
1246
-                    ) . '</p>';
1247
-                $this->_current_screen->add_help_tab($_ht);
1248
-            }
1249
-            if (! isset($config['help_tabs'])) {
1250
-                return;
1251
-            } //no help tabs for this route
1252
-            foreach ((array)$config['help_tabs'] as $tab_id => $cfg) {
1253
-                //we're here so there ARE help tabs!
1254
-                //make sure we've got what we need
1255
-                if (! isset($cfg['title'])) {
1256
-                    throw new EE_Error(
1257
-                        esc_html__(
1258
-                            'The _page_config array is not set up properly for help tabs.  It is missing a title',
1259
-                            'event_espresso'
1260
-                        )
1261
-                    );
1262
-                }
1263
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1264
-                    throw new EE_Error(
1265
-                        esc_html__(
1266
-                            'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1267
-                            'event_espresso'
1268
-                        )
1269
-                    );
1270
-                }
1271
-                //first priority goes to content.
1272
-                if (! empty($cfg['content'])) {
1273
-                    $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1274
-                    //second priority goes to filename
1275
-                } elseif (! empty($cfg['filename'])) {
1276
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1277
-                    //it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1278
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1279
-                                                             . basename($this->_get_dir())
1280
-                                                             . '/help_tabs/'
1281
-                                                             . $cfg['filename']
1282
-                                                             . '.help_tab.php' : $file_path;
1283
-                    //if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1284
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1285
-                        EE_Error::add_error(
1286
-                            sprintf(
1287
-                                esc_html__(
1288
-                                    'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1289
-                                    'event_espresso'
1290
-                                ),
1291
-                                $tab_id,
1292
-                                key($config),
1293
-                                $file_path
1294
-                            ),
1295
-                            __FILE__,
1296
-                            __FUNCTION__,
1297
-                            __LINE__
1298
-                        );
1299
-                        return;
1300
-                    }
1301
-                    $template_args['admin_page_obj'] = $this;
1302
-                    $content = EEH_Template::display_template(
1303
-                        $file_path,
1304
-                        $template_args,
1305
-                        true
1306
-                    );
1307
-                } else {
1308
-                    $content = '';
1309
-                }
1310
-                //check if callback is valid
1311
-                if (
1312
-                    empty($content) && (
1313
-                        ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1314
-                    )
1315
-                ) {
1316
-                    EE_Error::add_error(
1317
-                        sprintf(
1318
-                            esc_html__(
1319
-                                'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1320
-                                'event_espresso'
1321
-                            ),
1322
-                            $cfg['title']
1323
-                        ),
1324
-                        __FILE__,
1325
-                        __FUNCTION__,
1326
-                        __LINE__
1327
-                    );
1328
-                    return;
1329
-                }
1330
-                //setup config array for help tab method
1331
-                $id  = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1332
-                $_ht = array(
1333
-                    'id'       => $id,
1334
-                    'title'    => $cfg['title'],
1335
-                    'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1336
-                    'content'  => $content,
1337
-                );
1338
-                $this->_current_screen->add_help_tab($_ht);
1339
-            }
1340
-        }
1341
-    }
1342
-
1343
-
1344
-
1345
-    /**
1346
-     * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1347
-     * an array with properties for setting up usage of the joyride plugin
1348
-     *
1349
-     * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1350
-     * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1351
-     *         _set_page_config() comments
1352
-     * @return void
1353
-     * @throws EE_Error
1354
-     * @throws InvalidArgumentException
1355
-     * @throws InvalidDataTypeException
1356
-     * @throws InvalidInterfaceException
1357
-     */
1358
-    protected function _add_help_tour()
1359
-    {
1360
-        $tours            = array();
1361
-        $this->_help_tour = array();
1362
-        //exit early if help tours are turned off globally
1363
-        if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1364
-            || ! EE_Registry::instance()->CFG->admin->help_tour_activation
1365
-        ) {
1366
-            return;
1367
-        }
1368
-        //loop through _page_config to find any help_tour defined
1369
-        foreach ($this->_page_config as $route => $config) {
1370
-            //we're only going to set things up for this route
1371
-            if ($route !== $this->_req_action) {
1372
-                continue;
1373
-            }
1374
-            if (isset($config['help_tour'])) {
1375
-                foreach ($config['help_tour'] as $tour) {
1376
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1377
-                    // let's see if we can get that file...
1378
-                    // if not its possible this is a decaf route not set in caffeinated
1379
-                    // so lets try and get the caffeinated equivalent
1380
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1381
-                                                             . basename($this->_get_dir())
1382
-                                                             . '/help_tours/'
1383
-                                                             . $tour
1384
-                                                             . '.class.php' : $file_path;
1385
-                    //if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1386
-                    if (! is_readable($file_path)) {
1387
-                        EE_Error::add_error(
1388
-                            sprintf(
1389
-                                esc_html__(
1390
-                                    'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1391
-                                    'event_espresso'
1392
-                                ),
1393
-                                $file_path,
1394
-                                $tour
1395
-                            ),
1396
-                            __FILE__,
1397
-                            __FUNCTION__,
1398
-                            __LINE__
1399
-                        );
1400
-                        return;
1401
-                    }
1402
-                    require_once $file_path;
1403
-                    if (! class_exists($tour)) {
1404
-                        $error_msg[] = sprintf(
1405
-                            esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1406
-                            $tour
1407
-                        );
1408
-                        $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
1409
-                                esc_html__(
1410
-                                    'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1411
-                                    'event_espresso'
1412
-                                ),
1413
-                                $tour,
1414
-                                '<br />',
1415
-                                $tour,
1416
-                                $this->_req_action,
1417
-                                get_class($this)
1418
-                            );
1419
-                        throw new EE_Error(implode('||', $error_msg));
1420
-                    }
1421
-                    $tour_obj                   = new $tour($this->_is_caf);
1422
-                    $tours[]                    = $tour_obj;
1423
-                    $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($tour_obj);
1424
-                }
1425
-                //let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1426
-                $end_stop_tour              = new EE_Help_Tour_final_stop($this->_is_caf);
1427
-                $tours[]                    = $end_stop_tour;
1428
-                $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1429
-            }
1430
-        }
1431
-        if (! empty($tours)) {
1432
-            $this->_help_tour['tours'] = $tours;
1433
-        }
1434
-        // that's it!  Now that the $_help_tours property is set (or not)
1435
-        // the scripts and html should be taken care of automatically.
1436
-    }
1437
-
1438
-
1439
-
1440
-    /**
1441
-     * This simply sets up any qtips that have been defined in the page config
1442
-     *
1443
-     * @return void
1444
-     */
1445
-    protected function _add_qtips()
1446
-    {
1447
-        if (isset($this->_route_config['qtips'])) {
1448
-            $qtips = (array)$this->_route_config['qtips'];
1449
-            //load qtip loader
1450
-            $path = array(
1451
-                $this->_get_dir() . '/qtips/',
1452
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1453
-            );
1454
-            EEH_Qtip_Loader::instance()->register($qtips, $path);
1455
-        }
1456
-    }
1457
-
1458
-
1459
-
1460
-    /**
1461
-     * _set_nav_tabs
1462
-     * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1463
-     * wish to add additional tabs or modify accordingly.
1464
-     *
1465
-     * @return void
1466
-     * @throws InvalidArgumentException
1467
-     * @throws InvalidInterfaceException
1468
-     * @throws InvalidDataTypeException
1469
-     */
1470
-    protected function _set_nav_tabs()
1471
-    {
1472
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1473
-        $i = 0;
1474
-        foreach ($this->_page_config as $slug => $config) {
1475
-            if (
1476
-                ! is_array($config)
1477
-                || (
1478
-                    is_array($config)
1479
-                    && (isset($config['nav']) && ! $config['nav'])
1480
-                    || ! isset($config['nav'])
1481
-                )
1482
-            ) {
1483
-                continue;
1484
-            }
1485
-            //no nav tab for this config
1486
-            //check for persistent flag
1487
-            if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1488
-                // nav tab is only to appear when route requested.
1489
-                continue;
1490
-            }
1491
-            if (! $this->check_user_access($slug, true)) {
1492
-                // no nav tab because current user does not have access.
1493
-                continue;
1494
-            }
1495
-            $css_class              = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1496
-            $this->_nav_tabs[$slug] = array(
1497
-                'url'       => isset($config['nav']['url'])
1498
-                    ? $config['nav']['url']
1499
-                    : self::add_query_args_and_nonce(
1500
-                        array('action' => $slug),
1501
-                        $this->_admin_base_url
1502
-                    ),
1503
-                'link_text' => isset($config['nav']['label'])
1504
-                    ? $config['nav']['label']
1505
-                    : ucwords(
1506
-                        str_replace('_', ' ', $slug)
1507
-                    ),
1508
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1509
-                'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1510
-            );
1511
-            $i++;
1512
-        }
1513
-        //if $this->_nav_tabs is empty then lets set the default
1514
-        if (empty($this->_nav_tabs)) {
1515
-            $this->_nav_tabs[$this->_default_nav_tab_name] = array(
1516
-                'url'       => $this->_admin_base_url,
1517
-                'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1518
-                'css_class' => 'nav-tab-active',
1519
-                'order'     => 10,
1520
-            );
1521
-        }
1522
-        //now let's sort the tabs according to order
1523
-        usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1524
-    }
1525
-
1526
-
1527
-
1528
-    /**
1529
-     * _set_current_labels
1530
-     * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1531
-     * property array
1532
-     *
1533
-     * @return void
1534
-     */
1535
-    private function _set_current_labels()
1536
-    {
1537
-        if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1538
-            foreach ($this->_route_config['labels'] as $label => $text) {
1539
-                if (is_array($text)) {
1540
-                    foreach ($text as $sublabel => $subtext) {
1541
-                        $this->_labels[$label][$sublabel] = $subtext;
1542
-                    }
1543
-                } else {
1544
-                    $this->_labels[$label] = $text;
1545
-                }
1546
-            }
1547
-        }
1548
-    }
1549
-
1550
-
1551
-
1552
-    /**
1553
-     *        verifies user access for this admin page
1554
-     *
1555
-     * @param string $route_to_check if present then the capability for the route matching this string is checked.
1556
-     * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1557
-     *                               return false if verify fail.
1558
-     * @return bool
1559
-     * @throws InvalidArgumentException
1560
-     * @throws InvalidDataTypeException
1561
-     * @throws InvalidInterfaceException
1562
-     */
1563
-    public function check_user_access($route_to_check = '', $verify_only = false)
1564
-    {
1565
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1566
-        $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1567
-        $capability     = ! empty($route_to_check) && isset($this->_page_routes[$route_to_check])
1568
-                          && is_array(
1569
-                              $this->_page_routes[$route_to_check]
1570
-                          )
1571
-                          && ! empty($this->_page_routes[$route_to_check]['capability'])
1572
-            ? $this->_page_routes[$route_to_check]['capability'] : null;
1573
-        if (empty($capability) && empty($route_to_check)) {
1574
-            $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1575
-                : $this->_route['capability'];
1576
-        } else {
1577
-            $capability = empty($capability) ? 'manage_options' : $capability;
1578
-        }
1579
-        $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1580
-        if (
1581
-            ! defined('DOING_AJAX')
1582
-            && (
1583
-                ! function_exists('is_admin')
1584
-                || ! EE_Registry::instance()->CAP->current_user_can(
1585
-                    $capability,
1586
-                    $this->page_slug
1587
-                    . '_'
1588
-                    . $route_to_check,
1589
-                    $id
1590
-                )
1591
-            )
1592
-        ) {
1593
-            if ($verify_only) {
1594
-                return false;
1595
-            }
1596
-            if (is_user_logged_in()) {
1597
-                wp_die(__('You do not have access to this route.', 'event_espresso'));
1598
-            } else {
1599
-                return false;
1600
-            }
1601
-        }
1602
-        return true;
1603
-    }
1604
-
1605
-
1606
-
1607
-    /**
1608
-     * admin_init_global
1609
-     * This runs all the code that we want executed within the WP admin_init hook.
1610
-     * This method executes for ALL EE Admin pages.
1611
-     *
1612
-     * @return void
1613
-     */
1614
-    public function admin_init_global()
1615
-    {
1616
-    }
1617
-
1618
-
1619
-
1620
-    /**
1621
-     * wp_loaded_global
1622
-     * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1623
-     * EE_Admin page and will execute on every EE Admin Page load
1624
-     *
1625
-     * @return void
1626
-     */
1627
-    public function wp_loaded()
1628
-    {
1629
-    }
1630
-
1631
-
1632
-
1633
-    /**
1634
-     * admin_notices
1635
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1636
-     * ALL EE_Admin pages.
1637
-     *
1638
-     * @return void
1639
-     */
1640
-    public function admin_notices_global()
1641
-    {
1642
-        $this->_display_no_javascript_warning();
1643
-        $this->_display_espresso_notices();
1644
-    }
1645
-
1646
-
1647
-
1648
-    public function network_admin_notices_global()
1649
-    {
1650
-        $this->_display_no_javascript_warning();
1651
-        $this->_display_espresso_notices();
1652
-    }
1653
-
1654
-
1655
-
1656
-    /**
1657
-     * admin_footer_scripts_global
1658
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1659
-     * will apply on ALL EE_Admin pages.
1660
-     *
1661
-     * @return void
1662
-     */
1663
-    public function admin_footer_scripts_global()
1664
-    {
1665
-        $this->_add_admin_page_ajax_loading_img();
1666
-        $this->_add_admin_page_overlay();
1667
-        //if metaboxes are present we need to add the nonce field
1668
-        if (
1669
-             isset($this->_route_config['metaboxes'])
1670
-             || isset($this->_route_config['list_table'])
1671
-             || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1672
-        ) {
1673
-            wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1674
-            wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1675
-        }
1676
-    }
1677
-
1678
-
1679
-
1680
-    /**
1681
-     * admin_footer_global
1682
-     * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on
1683
-     * ALL EE_Admin Pages.
1684
-     *
1685
-     * @return  void
1686
-     */
1687
-    public function admin_footer_global()
1688
-    {
1689
-        //dialog container for dialog helper
1690
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1691
-        $d_cont .= '<div class="ee-notices"></div>';
1692
-        $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1693
-        $d_cont .= '</div>';
1694
-        echo $d_cont;
1695
-        //help tour stuff?
1696
-        if (isset($this->_help_tour[$this->_req_action])) {
1697
-            echo implode('<br />', $this->_help_tour[$this->_req_action]);
1698
-        }
1699
-        //current set timezone for timezone js
1700
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1701
-    }
1702
-
1703
-
1704
-
1705
-    /**
1706
-     * This function sees if there is a method for help popup content existing for the given route.  If there is then
1707
-     * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1708
-     * help popups then in your templates or your content you set "triggers" for the content using the
1709
-     * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1710
-     * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1711
-     * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1712
-     * for the
1713
-     * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1714
-     * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1715
-     *    'help_trigger_id' => array(
1716
-     *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1717
-     *        'content' => esc_html__('localized content for popup', 'event_espresso')
1718
-     *    )
1719
-     * );
1720
-     * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1721
-     *
1722
-     * @param array $help_array
1723
-     * @param bool  $display
1724
-     * @return string content
1725
-     * @throws DomainException
1726
-     * @throws EE_Error
1727
-     */
1728
-    protected function _set_help_popup_content($help_array = array(), $display = false)
1729
-    {
1730
-        $content       = '';
1731
-        $help_array    = empty($help_array) ? $this->_get_help_content() : $help_array;
1732
-        //loop through the array and setup content
1733
-        foreach ($help_array as $trigger => $help) {
1734
-            //make sure the array is setup properly
1735
-            if (! isset($help['title']) || ! isset($help['content'])) {
1736
-                throw new EE_Error(
1737
-                    esc_html__(
1738
-                        'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1739
-                        'event_espresso'
1740
-                    )
1741
-                );
1742
-            }
1743
-            //we're good so let'd setup the template vars and then assign parsed template content to our content.
1744
-            $template_args = array(
1745
-                'help_popup_id'      => $trigger,
1746
-                'help_popup_title'   => $help['title'],
1747
-                'help_popup_content' => $help['content'],
1748
-            );
1749
-            $content       .= EEH_Template::display_template(
1750
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1751
-                $template_args,
1752
-                true
1753
-            );
1754
-        }
1755
-        if ($display) {
1756
-            echo $content;
1757
-            return '';
1758
-        }
1759
-        return $content;
1760
-    }
1761
-
1762
-
1763
-
1764
-    /**
1765
-     * All this does is retrieve the help content array if set by the EE_Admin_Page child
1766
-     *
1767
-     * @return array properly formatted array for help popup content
1768
-     * @throws EE_Error
1769
-     */
1770
-    private function _get_help_content()
1771
-    {
1772
-        //what is the method we're looking for?
1773
-        $method_name = '_help_popup_content_' . $this->_req_action;
1774
-        //if method doesn't exist let's get out.
1775
-        if (! method_exists($this, $method_name)) {
1776
-            return array();
1777
-        }
1778
-        //k we're good to go let's retrieve the help array
1779
-        $help_array = call_user_func(array($this, $method_name));
1780
-        //make sure we've got an array!
1781
-        if (! is_array($help_array)) {
1782
-            throw new EE_Error(
1783
-                esc_html__(
1784
-                    'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1785
-                    'event_espresso'
1786
-                )
1787
-            );
1788
-        }
1789
-        return $help_array;
1790
-    }
1791
-
1792
-
1793
-
1794
-    /**
1795
-     * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1796
-     * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1797
-     * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1798
-     *
1799
-     * @param string  $trigger_id reference for retrieving the trigger content for the popup
1800
-     * @param boolean $display    if false then we return the trigger string
1801
-     * @param array   $dimensions an array of dimensions for the box (array(h,w))
1802
-     * @return string
1803
-     * @throws DomainException
1804
-     * @throws EE_Error
1805
-     */
1806
-    protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1807
-    {
1808
-        if (defined('DOING_AJAX')) {
1809
-            return '';
1810
-        }
1811
-        //let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1812
-        $help_array   = $this->_get_help_content();
1813
-        $help_content = '';
1814
-        if (empty($help_array) || ! isset($help_array[$trigger_id])) {
1815
-            $help_array[$trigger_id] = array(
1816
-                'title'   => esc_html__('Missing Content', 'event_espresso'),
1817
-                'content' => esc_html__(
1818
-                    'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1819
-                    'event_espresso'
1820
-                ),
1821
-            );
1822
-            $help_content            = $this->_set_help_popup_content($help_array, false);
1823
-        }
1824
-        //let's setup the trigger
1825
-        $content = '<a class="ee-dialog" href="?height='
1826
-                   . $dimensions[0]
1827
-                   . '&width='
1828
-                   . $dimensions[1]
1829
-                   . '&inlineId='
1830
-                   . $trigger_id
1831
-                   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1832
-        $content .= $help_content;
1833
-        if ($display) {
1834
-            echo $content;
1835
-            return  '';
1836
-        }
1837
-        return $content;
1838
-    }
1839
-
1840
-
1841
-
1842
-    /**
1843
-     * _add_global_screen_options
1844
-     * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1845
-     * This particular method will add_screen_options on ALL EE_Admin Pages
1846
-     *
1847
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1848
-     *         see also WP_Screen object documents...
1849
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1850
-     * @abstract
1851
-     * @return void
1852
-     */
1853
-    private function _add_global_screen_options()
1854
-    {
1855
-    }
1856
-
1857
-
1858
-
1859
-    /**
1860
-     * _add_global_feature_pointers
1861
-     * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1862
-     * This particular method will implement feature pointers for ALL EE_Admin pages.
1863
-     * Note: this is just a placeholder for now.  Implementation will come down the road
1864
-     *
1865
-     * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1866
-     *         extended) also see:
1867
-     * @link   http://eamann.com/tech/wordpress-portland/
1868
-     * @abstract
1869
-     * @return void
1870
-     */
1871
-    private function _add_global_feature_pointers()
1872
-    {
1873
-    }
1874
-
1875
-
1876
-
1877
-    /**
1878
-     * load_global_scripts_styles
1879
-     * The scripts and styles enqueued in here will be loaded on every EE Admin page
1880
-     *
1881
-     * @return void
1882
-     */
1883
-    public function load_global_scripts_styles()
1884
-    {
1885
-        /** STYLES **/
1886
-        // add debugging styles
1887
-        if (WP_DEBUG) {
1888
-            add_action('admin_head', array($this, 'add_xdebug_style'));
1889
-        }
1890
-        // register all styles
1891
-        wp_register_style(
1892
-            'espresso-ui-theme',
1893
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1894
-            array(),
1895
-            EVENT_ESPRESSO_VERSION
1896
-        );
1897
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1898
-        //helpers styles
1899
-        wp_register_style(
1900
-            'ee-text-links',
1901
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1902
-            array(),
1903
-            EVENT_ESPRESSO_VERSION
1904
-        );
1905
-        /** SCRIPTS **/
1906
-        //register all scripts
1907
-        wp_register_script(
1908
-            'ee-dialog',
1909
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1910
-            array('jquery', 'jquery-ui-draggable'),
1911
-            EVENT_ESPRESSO_VERSION,
1912
-            true
1913
-        );
1914
-        wp_register_script(
1915
-            'ee_admin_js',
1916
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1917
-            array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1918
-            EVENT_ESPRESSO_VERSION,
1919
-            true
1920
-        );
1921
-        wp_register_script(
1922
-            'jquery-ui-timepicker-addon',
1923
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1924
-            array('jquery-ui-datepicker', 'jquery-ui-slider'),
1925
-            EVENT_ESPRESSO_VERSION,
1926
-            true
1927
-        );
1928
-        add_filter('FHEE_load_joyride', '__return_true');
1929
-        //script for sorting tables
1930
-        wp_register_script(
1931
-            'espresso_ajax_table_sorting',
1932
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1933
-            array('ee_admin_js', 'jquery-ui-sortable'),
1934
-            EVENT_ESPRESSO_VERSION,
1935
-            true
1936
-        );
1937
-        //script for parsing uri's
1938
-        wp_register_script(
1939
-            'ee-parse-uri',
1940
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1941
-            array(),
1942
-            EVENT_ESPRESSO_VERSION,
1943
-            true
1944
-        );
1945
-        //and parsing associative serialized form elements
1946
-        wp_register_script(
1947
-            'ee-serialize-full-array',
1948
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1949
-            array('jquery'),
1950
-            EVENT_ESPRESSO_VERSION,
1951
-            true
1952
-        );
1953
-        //helpers scripts
1954
-        wp_register_script(
1955
-            'ee-text-links',
1956
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1957
-            array('jquery'),
1958
-            EVENT_ESPRESSO_VERSION,
1959
-            true
1960
-        );
1961
-        wp_register_script(
1962
-            'ee-moment-core',
1963
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1964
-            array(),
1965
-            EVENT_ESPRESSO_VERSION,
1966
-            true
1967
-        );
1968
-        wp_register_script(
1969
-            'ee-moment',
1970
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1971
-            array('ee-moment-core'),
1972
-            EVENT_ESPRESSO_VERSION,
1973
-            true
1974
-        );
1975
-        wp_register_script(
1976
-            'ee-datepicker',
1977
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1978
-            array('jquery-ui-timepicker-addon', 'ee-moment'),
1979
-            EVENT_ESPRESSO_VERSION,
1980
-            true
1981
-        );
1982
-        //google charts
1983
-        wp_register_script(
1984
-            'google-charts',
1985
-            'https://www.gstatic.com/charts/loader.js',
1986
-            array(),
1987
-            EVENT_ESPRESSO_VERSION,
1988
-            false
1989
-        );
1990
-        // ENQUEUE ALL BASICS BY DEFAULT
1991
-        wp_enqueue_style('ee-admin-css');
1992
-        wp_enqueue_script('ee_admin_js');
1993
-        wp_enqueue_script('ee-accounting');
1994
-        wp_enqueue_script('jquery-validate');
1995
-        //taking care of metaboxes
1996
-        if (
1997
-            empty($this->_cpt_route)
1998
-            && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1999
-        ) {
2000
-            wp_enqueue_script('dashboard');
2001
-        }
2002
-        // LOCALIZED DATA
2003
-        //localize script for ajax lazy loading
2004
-        $lazy_loader_container_ids = apply_filters(
2005
-            'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2006
-            array('espresso_news_post_box_content')
2007
-        );
2008
-        wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2009
-        /**
2010
-         * help tour stuff
2011
-         */
2012
-        if (! empty($this->_help_tour)) {
2013
-            //register the js for kicking things off
2014
-            wp_enqueue_script(
2015
-                'ee-help-tour',
2016
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2017
-                array('jquery-joyride'),
2018
-                EVENT_ESPRESSO_VERSION,
2019
-                true
2020
-            );
2021
-            //setup tours for the js tour object
2022
-            foreach ($this->_help_tour['tours'] as $tour) {
2023
-                if ($tour instanceof EE_Help_Tour) {
2024
-                    $tours[] = array(
2025
-                        'id'      => $tour->get_slug(),
2026
-                        'options' => $tour->get_options(),
2027
-                    );
2028
-                }
2029
-            }
2030
-            wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2031
-            //admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2032
-        }
2033
-    }
2034
-
2035
-
2036
-
2037
-    /**
2038
-     *        admin_footer_scripts_eei18n_js_strings
2039
-     *
2040
-     * @return        void
2041
-     */
2042
-    public function admin_footer_scripts_eei18n_js_strings()
2043
-    {
2044
-        EE_Registry::$i18n_js_strings['ajax_url']       = WP_AJAX_URL;
2045
-        EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2046
-            'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2047
-            'event_espresso'
2048
-        );
2049
-        EE_Registry::$i18n_js_strings['January']        = esc_html__('January', 'event_espresso');
2050
-        EE_Registry::$i18n_js_strings['February']       = esc_html__('February', 'event_espresso');
2051
-        EE_Registry::$i18n_js_strings['March']          = esc_html__('March', 'event_espresso');
2052
-        EE_Registry::$i18n_js_strings['April']          = esc_html__('April', 'event_espresso');
2053
-        EE_Registry::$i18n_js_strings['May']            = esc_html__('May', 'event_espresso');
2054
-        EE_Registry::$i18n_js_strings['June']           = esc_html__('June', 'event_espresso');
2055
-        EE_Registry::$i18n_js_strings['July']           = esc_html__('July', 'event_espresso');
2056
-        EE_Registry::$i18n_js_strings['August']         = esc_html__('August', 'event_espresso');
2057
-        EE_Registry::$i18n_js_strings['September']      = esc_html__('September', 'event_espresso');
2058
-        EE_Registry::$i18n_js_strings['October']        = esc_html__('October', 'event_espresso');
2059
-        EE_Registry::$i18n_js_strings['November']       = esc_html__('November', 'event_espresso');
2060
-        EE_Registry::$i18n_js_strings['December']       = esc_html__('December', 'event_espresso');
2061
-        EE_Registry::$i18n_js_strings['Jan']            = esc_html__('Jan', 'event_espresso');
2062
-        EE_Registry::$i18n_js_strings['Feb']            = esc_html__('Feb', 'event_espresso');
2063
-        EE_Registry::$i18n_js_strings['Mar']            = esc_html__('Mar', 'event_espresso');
2064
-        EE_Registry::$i18n_js_strings['Apr']            = esc_html__('Apr', 'event_espresso');
2065
-        EE_Registry::$i18n_js_strings['May']            = esc_html__('May', 'event_espresso');
2066
-        EE_Registry::$i18n_js_strings['Jun']            = esc_html__('Jun', 'event_espresso');
2067
-        EE_Registry::$i18n_js_strings['Jul']            = esc_html__('Jul', 'event_espresso');
2068
-        EE_Registry::$i18n_js_strings['Aug']            = esc_html__('Aug', 'event_espresso');
2069
-        EE_Registry::$i18n_js_strings['Sep']            = esc_html__('Sep', 'event_espresso');
2070
-        EE_Registry::$i18n_js_strings['Oct']            = esc_html__('Oct', 'event_espresso');
2071
-        EE_Registry::$i18n_js_strings['Nov']            = esc_html__('Nov', 'event_espresso');
2072
-        EE_Registry::$i18n_js_strings['Dec']            = esc_html__('Dec', 'event_espresso');
2073
-        EE_Registry::$i18n_js_strings['Sunday']         = esc_html__('Sunday', 'event_espresso');
2074
-        EE_Registry::$i18n_js_strings['Monday']         = esc_html__('Monday', 'event_espresso');
2075
-        EE_Registry::$i18n_js_strings['Tuesday']        = esc_html__('Tuesday', 'event_espresso');
2076
-        EE_Registry::$i18n_js_strings['Wednesday']      = esc_html__('Wednesday', 'event_espresso');
2077
-        EE_Registry::$i18n_js_strings['Thursday']       = esc_html__('Thursday', 'event_espresso');
2078
-        EE_Registry::$i18n_js_strings['Friday']         = esc_html__('Friday', 'event_espresso');
2079
-        EE_Registry::$i18n_js_strings['Saturday']       = esc_html__('Saturday', 'event_espresso');
2080
-        EE_Registry::$i18n_js_strings['Sun']            = esc_html__('Sun', 'event_espresso');
2081
-        EE_Registry::$i18n_js_strings['Mon']            = esc_html__('Mon', 'event_espresso');
2082
-        EE_Registry::$i18n_js_strings['Tue']            = esc_html__('Tue', 'event_espresso');
2083
-        EE_Registry::$i18n_js_strings['Wed']            = esc_html__('Wed', 'event_espresso');
2084
-        EE_Registry::$i18n_js_strings['Thu']            = esc_html__('Thu', 'event_espresso');
2085
-        EE_Registry::$i18n_js_strings['Fri']            = esc_html__('Fri', 'event_espresso');
2086
-        EE_Registry::$i18n_js_strings['Sat']            = esc_html__('Sat', 'event_espresso');
2087
-    }
2088
-
2089
-
2090
-
2091
-    /**
2092
-     *        load enhanced xdebug styles for ppl with failing eyesight
2093
-     *
2094
-     * @return        void
2095
-     */
2096
-    public function add_xdebug_style()
2097
-    {
2098
-        echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2099
-    }
2100
-
2101
-
2102
-    /************************/
2103
-    /** LIST TABLE METHODS **/
2104
-    /************************/
2105
-    /**
2106
-     * this sets up the list table if the current view requires it.
2107
-     *
2108
-     * @return void
2109
-     * @throws EE_Error
2110
-     */
2111
-    protected function _set_list_table()
2112
-    {
2113
-        //first is this a list_table view?
2114
-        if (! isset($this->_route_config['list_table'])) {
2115
-            return;
2116
-        } //not a list_table view so get out.
2117
-        // list table functions are per view specific (because some admin pages might have more than one listtable!)
2118
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2119
-        if ($this->{$list_table_view} === false) {
2120
-            //user error msg
2121
-            $error_msg = esc_html__(
2122
-                'An error occurred. The requested list table views could not be found.',
2123
-                'event_espresso'
2124
-            );
2125
-            //developer error msg
2126
-            $error_msg .= '||' . sprintf(
2127
-                    esc_html__(
2128
-                        'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2129
-                        'event_espresso'
2130
-                    ),
2131
-                    $this->_req_action,
2132
-                    $list_table_view
2133
-                );
2134
-            throw new EE_Error($error_msg);
2135
-        }
2136
-        //let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2137
-        $this->_views = apply_filters(
2138
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2139
-            $this->_views
2140
-        );
2141
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2142
-        $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2143
-        $this->_set_list_table_view();
2144
-        $this->_set_list_table_object();
2145
-    }
2146
-
2147
-
2148
-
2149
-    /**
2150
-     * set current view for List Table
2151
-     *
2152
-     * @return void
2153
-     */
2154
-    protected function _set_list_table_view()
2155
-    {
2156
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2157
-        // looking at active items or dumpster diving ?
2158
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2159
-            $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2160
-        } else {
2161
-            $this->_view = sanitize_key($this->_req_data['status']);
2162
-        }
2163
-    }
2164
-
2165
-
2166
-
2167
-    /**
2168
-     * _set_list_table_object
2169
-     * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2170
-     *
2171
-     * @throws EE_Error
2172
-     */
2173
-    protected function _set_list_table_object()
2174
-    {
2175
-        if (isset($this->_route_config['list_table'])) {
2176
-            if (! class_exists($this->_route_config['list_table'])) {
2177
-                throw new EE_Error(
2178
-                    sprintf(
2179
-                        esc_html__(
2180
-                            'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2181
-                            'event_espresso'
2182
-                        ),
2183
-                        $this->_route_config['list_table'],
2184
-                        get_class($this)
2185
-                    )
2186
-                );
2187
-            }
2188
-            $list_table               = $this->_route_config['list_table'];
2189
-            $this->_list_table_object = new $list_table($this);
2190
-        }
2191
-    }
2192
-
2193
-
2194
-
2195
-    /**
2196
-     * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2197
-     *
2198
-     * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2199
-     *                                                    urls.  The array should be indexed by the view it is being
2200
-     *                                                    added to.
2201
-     * @return array
2202
-     */
2203
-    public function get_list_table_view_RLs($extra_query_args = array())
2204
-    {
2205
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2206
-        if (empty($this->_views)) {
2207
-            $this->_views = array();
2208
-        }
2209
-        // cycle thru views
2210
-        foreach ($this->_views as $key => $view) {
2211
-            $query_args = array();
2212
-            // check for current view
2213
-            $this->_views[$key]['class']               = $this->_view === $view['slug'] ? 'current' : '';
2214
-            $query_args['action']                      = $this->_req_action;
2215
-            $query_args[$this->_req_action . '_nonce'] = wp_create_nonce($query_args['action'] . '_nonce');
2216
-            $query_args['status']                      = $view['slug'];
2217
-            //merge any other arguments sent in.
2218
-            if (isset($extra_query_args[$view['slug']])) {
2219
-                $query_args = array_merge($query_args, $extra_query_args[$view['slug']]);
2220
-            }
2221
-            $this->_views[$key]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2222
-        }
2223
-        return $this->_views;
2224
-    }
2225
-
2226
-
2227
-
2228
-    /**
2229
-     * _entries_per_page_dropdown
2230
-     * generates a drop down box for selecting the number of visible rows in an admin page list table
2231
-     *
2232
-     * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2233
-     *         WP does it.
2234
-     * @param int $max_entries total number of rows in the table
2235
-     * @return string
2236
-     */
2237
-    protected function _entries_per_page_dropdown($max_entries = 0)
2238
-    {
2239
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2240
-        $values   = array(10, 25, 50, 100);
2241
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2242
-        if ($max_entries) {
2243
-            $values[] = $max_entries;
2244
-            sort($values);
2245
-        }
2246
-        $entries_per_page_dropdown = '
125
+	/**
126
+	 * @var string $_req_action
127
+	 */
128
+	protected $_req_action;
129
+
130
+	/**
131
+	 * @var string $_req_nonce
132
+	 */
133
+	protected $_req_nonce;
134
+
135
+	//search related
136
+	protected $_search_btn_label;
137
+
138
+	protected $_search_box_callback;
139
+
140
+	/**
141
+	 * WP Current Screen object
142
+	 *
143
+	 * @var WP_Screen
144
+	 */
145
+	protected $_current_screen;
146
+
147
+	//for holding EE_Admin_Hooks object when needed (set via set_hook_object())
148
+	protected $_hook_obj;
149
+
150
+	//for holding incoming request data
151
+	protected $_req_data;
152
+
153
+	// yes / no array for admin form fields
154
+	protected $_yes_no_values = array();
155
+
156
+	//some default things shared by all child classes
157
+	protected $_default_espresso_metaboxes;
158
+
159
+	/**
160
+	 *    EE_Registry Object
161
+	 *
162
+	 * @var    EE_Registry
163
+	 */
164
+	protected $EE = null;
165
+
166
+
167
+
168
+	/**
169
+	 * This is just a property that flags whether the given route is a caffeinated route or not.
170
+	 *
171
+	 * @var boolean
172
+	 */
173
+	protected $_is_caf = false;
174
+
175
+
176
+
177
+	/**
178
+	 * @Constructor
179
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
+	 * @throws EE_Error
181
+	 * @throws InvalidArgumentException
182
+	 * @throws ReflectionException
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws InvalidInterfaceException
185
+	 */
186
+	public function __construct($routing = true)
187
+	{
188
+		if (strpos($this->_get_dir(), 'caffeinated') !== false) {
189
+			$this->_is_caf = true;
190
+		}
191
+		$this->_yes_no_values = array(
192
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
193
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
194
+		);
195
+		//set the _req_data property.
196
+		$this->_req_data = array_merge($_GET, $_POST);
197
+		//routing enabled?
198
+		$this->_routing = $routing;
199
+		//set initial page props (child method)
200
+		$this->_init_page_props();
201
+		//set global defaults
202
+		$this->_set_defaults();
203
+		//set early because incoming requests could be ajax related and we need to register those hooks.
204
+		$this->_global_ajax_hooks();
205
+		$this->_ajax_hooks();
206
+		//other_page_hooks have to be early too.
207
+		$this->_do_other_page_hooks();
208
+		//This just allows us to have extending classes do something specific
209
+		// before the parent constructor runs _page_setup().
210
+		if (method_exists($this, '_before_page_setup')) {
211
+			$this->_before_page_setup();
212
+		}
213
+		//set up page dependencies
214
+		$this->_page_setup();
215
+	}
216
+
217
+
218
+
219
+	/**
220
+	 * _init_page_props
221
+	 * Child classes use to set at least the following properties:
222
+	 * $page_slug.
223
+	 * $page_label.
224
+	 *
225
+	 * @abstract
226
+	 * @return void
227
+	 */
228
+	abstract protected function _init_page_props();
229
+
230
+
231
+
232
+	/**
233
+	 * _ajax_hooks
234
+	 * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
235
+	 * Note: within the ajax callback methods.
236
+	 *
237
+	 * @abstract
238
+	 * @return void
239
+	 */
240
+	abstract protected function _ajax_hooks();
241
+
242
+
243
+
244
+	/**
245
+	 * _define_page_props
246
+	 * child classes define page properties in here.  Must include at least:
247
+	 * $_admin_base_url = base_url for all admin pages
248
+	 * $_admin_page_title = default admin_page_title for admin pages
249
+	 * $_labels = array of default labels for various automatically generated elements:
250
+	 *    array(
251
+	 *        'buttons' => array(
252
+	 *            'add' => esc_html__('label for add new button'),
253
+	 *            'edit' => esc_html__('label for edit button'),
254
+	 *            'delete' => esc_html__('label for delete button')
255
+	 *            )
256
+	 *        )
257
+	 *
258
+	 * @abstract
259
+	 * @return void
260
+	 */
261
+	abstract protected function _define_page_props();
262
+
263
+
264
+
265
+	/**
266
+	 * _set_page_routes
267
+	 * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
268
+	 * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
269
+	 * have a 'default' route. Here's the format
270
+	 * $this->_page_routes = array(
271
+	 *        'default' => array(
272
+	 *            'func' => '_default_method_handling_route',
273
+	 *            'args' => array('array','of','args'),
274
+	 *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
275
+	 *            ajax request, backend processing)
276
+	 *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
277
+	 *            headers route after.  The string you enter here should match the defined route reference for a
278
+	 *            headers sent route.
279
+	 *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
280
+	 *            this route.
281
+	 *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
282
+	 *            checks).
283
+	 *        ),
284
+	 *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
285
+	 *        handling method.
286
+	 *        )
287
+	 * )
288
+	 *
289
+	 * @abstract
290
+	 * @return void
291
+	 */
292
+	abstract protected function _set_page_routes();
293
+
294
+
295
+
296
+	/**
297
+	 * _set_page_config
298
+	 * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
299
+	 * array corresponds to the page_route for the loaded page. Format:
300
+	 * $this->_page_config = array(
301
+	 *        'default' => array(
302
+	 *            'labels' => array(
303
+	 *                'buttons' => array(
304
+	 *                    'add' => esc_html__('label for adding item'),
305
+	 *                    'edit' => esc_html__('label for editing item'),
306
+	 *                    'delete' => esc_html__('label for deleting item')
307
+	 *                ),
308
+	 *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
309
+	 *            ), //optional an array of custom labels for various automatically generated elements to use on the
310
+	 *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
311
+	 *            _define_page_props() method
312
+	 *            'nav' => array(
313
+	 *                'label' => esc_html__('Label for Tab', 'event_espresso').
314
+	 *                'url' => 'http://someurl', //automatically generated UNLESS you define
315
+	 *                'css_class' => 'css-class', //automatically generated UNLESS you define
316
+	 *                'order' => 10, //required to indicate tab position.
317
+	 *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
318
+	 *                displayed then add this parameter.
319
+	 *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
320
+	 *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
321
+	 *            metaboxes set for eventespresso admin pages.
322
+	 *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
323
+	 *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
324
+	 *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
325
+	 *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
326
+	 *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
327
+	 *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
328
+	 *            array indicates the max number of columns (4) and the default number of columns on page load (2).
329
+	 *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
330
+	 *            want to display.
331
+	 *            'help_tabs' => array( //this is used for adding help tabs to a page
332
+	 *                'tab_id' => array(
333
+	 *                    'title' => 'tab_title',
334
+	 *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
335
+	 *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
336
+	 *                    should match a file in the admin folder's "help_tabs" dir (ie..
337
+	 *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
338
+	 *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
339
+	 *                    attempt to use the callback which should match the name of a method in the class
340
+	 *                    ),
341
+	 *                'tab2_id' => array(
342
+	 *                    'title' => 'tab2 title',
343
+	 *                    'filename' => 'file_name_2'
344
+	 *                    'callback' => 'callback_method_for_content',
345
+	 *                 ),
346
+	 *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
347
+	 *            help tab area on an admin page. @link
348
+	 *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
349
+	 *            'help_tour' => array(
350
+	 *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
351
+	 *                in a folder for this admin page named "help_tours", a file name matching the key given here
352
+	 *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
353
+	 *            ),
354
+	 *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
355
+	 *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
356
+	 *            just set
357
+	 *            'require_nonce' to FALSE
358
+	 *            )
359
+	 * )
360
+	 *
361
+	 * @abstract
362
+	 * @return void
363
+	 */
364
+	abstract protected function _set_page_config();
365
+
366
+
367
+
368
+
369
+
370
+	/** end sample help_tour methods **/
371
+	/**
372
+	 * _add_screen_options
373
+	 * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
374
+	 * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
375
+	 * to a particular view.
376
+	 *
377
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
378
+	 *         see also WP_Screen object documents...
379
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
380
+	 * @abstract
381
+	 * @return void
382
+	 */
383
+	abstract protected function _add_screen_options();
384
+
385
+
386
+
387
+	/**
388
+	 * _add_feature_pointers
389
+	 * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
390
+	 * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
391
+	 * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
392
+	 * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
393
+	 * extended) also see:
394
+	 *
395
+	 * @link   http://eamann.com/tech/wordpress-portland/
396
+	 * @abstract
397
+	 * @return void
398
+	 */
399
+	abstract protected function _add_feature_pointers();
400
+
401
+
402
+
403
+	/**
404
+	 * load_scripts_styles
405
+	 * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
406
+	 * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
407
+	 * scripts/styles per view by putting them in a dynamic function in this format
408
+	 * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
409
+	 *
410
+	 * @abstract
411
+	 * @return void
412
+	 */
413
+	abstract public function load_scripts_styles();
414
+
415
+
416
+
417
+	/**
418
+	 * admin_init
419
+	 * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
420
+	 * all pages/views loaded by child class.
421
+	 *
422
+	 * @abstract
423
+	 * @return void
424
+	 */
425
+	abstract public function admin_init();
426
+
427
+
428
+
429
+	/**
430
+	 * admin_notices
431
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
432
+	 * all pages/views loaded by child class.
433
+	 *
434
+	 * @abstract
435
+	 * @return void
436
+	 */
437
+	abstract public function admin_notices();
438
+
439
+
440
+
441
+	/**
442
+	 * admin_footer_scripts
443
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
444
+	 * will apply to all pages/views loaded by child class.
445
+	 *
446
+	 * @return void
447
+	 */
448
+	abstract public function admin_footer_scripts();
449
+
450
+
451
+
452
+	/**
453
+	 * admin_footer
454
+	 * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
455
+	 * apply to all pages/views loaded by child class.
456
+	 *
457
+	 * @return void
458
+	 */
459
+	public function admin_footer()
460
+	{
461
+	}
462
+
463
+
464
+
465
+	/**
466
+	 * _global_ajax_hooks
467
+	 * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
468
+	 * Note: within the ajax callback methods.
469
+	 *
470
+	 * @abstract
471
+	 * @return void
472
+	 */
473
+	protected function _global_ajax_hooks()
474
+	{
475
+		//for lazy loading of metabox content
476
+		add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
477
+	}
478
+
479
+
480
+
481
+	public function ajax_metabox_content()
482
+	{
483
+		$contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
484
+		$url       = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
485
+		self::cached_rss_display($contentid, $url);
486
+		wp_die();
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * _page_setup
493
+	 * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
494
+	 * doesn't match the object.
495
+	 *
496
+	 * @final
497
+	 * @return void
498
+	 * @throws EE_Error
499
+	 * @throws InvalidArgumentException
500
+	 * @throws ReflectionException
501
+	 * @throws InvalidDataTypeException
502
+	 * @throws InvalidInterfaceException
503
+	 */
504
+	final protected function _page_setup()
505
+	{
506
+		//requires?
507
+		//admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can.  But keep in mind, not everything is available from the EE_Admin Page object at this point.
508
+		add_action('admin_init', array($this, 'admin_init_global'), 5);
509
+		//next verify if we need to load anything...
510
+		$this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
511
+		$this->page_folder   = strtolower(
512
+			str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
513
+		);
514
+		global $ee_menu_slugs;
515
+		$ee_menu_slugs = (array)$ee_menu_slugs;
516
+		if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
517
+			return;
518
+		}
519
+		// becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
520
+		if (isset($this->_req_data['action2']) && $this->_req_data['action'] === -1) {
521
+			$this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== -1
522
+				? $this->_req_data['action2']
523
+				: $this->_req_data['action'];
524
+		}
525
+		// then set blank or -1 action values to 'default'
526
+		$this->_req_action = isset($this->_req_data['action'])
527
+							 && ! empty($this->_req_data['action'])
528
+							 && $this->_req_data['action'] !== -1
529
+			? sanitize_key($this->_req_data['action'])
530
+			: 'default';
531
+		// if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
532
+		//  This covers cases where we're coming in from a list table that isn't on the default route.
533
+		$this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
534
+			? $this->_req_data['route'] : $this->_req_action;
535
+		//however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
536
+		$this->_req_action   = defined('DOING_AJAX') && isset($this->_req_data['route'])
537
+			? $this->_req_data['route']
538
+			: $this->_req_action;
539
+		$this->_current_view = $this->_req_action;
540
+		$this->_req_nonce    = $this->_req_action . '_nonce';
541
+		$this->_define_page_props();
542
+		$this->_current_page_view_url = add_query_arg(
543
+			array('page' => $this->_current_page, 'action' => $this->_current_view),
544
+			$this->_admin_base_url
545
+		);
546
+		//default things
547
+		$this->_default_espresso_metaboxes = array(
548
+			'_espresso_news_post_box',
549
+			'_espresso_links_post_box',
550
+			'_espresso_ratings_request',
551
+			'_espresso_sponsors_post_box',
552
+		);
553
+		//set page configs
554
+		$this->_set_page_routes();
555
+		$this->_set_page_config();
556
+		//let's include any referrer data in our default_query_args for this route for "stickiness".
557
+		if (isset($this->_req_data['wp_referer'])) {
558
+			$this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
559
+		}
560
+		//for caffeinated and other extended functionality.
561
+		//  If there is a _extend_page_config method
562
+		// then let's run that to modify the all the various page configuration arrays
563
+		if (method_exists($this, '_extend_page_config')) {
564
+			$this->_extend_page_config();
565
+		}
566
+		//for CPT and other extended functionality.
567
+		// If there is an _extend_page_config_for_cpt
568
+		// then let's run that to modify all the various page configuration arrays.
569
+		if (method_exists($this, '_extend_page_config_for_cpt')) {
570
+			$this->_extend_page_config_for_cpt();
571
+		}
572
+		//filter routes and page_config so addons can add their stuff. Filtering done per class
573
+		$this->_page_routes = apply_filters(
574
+			'FHEE__' . get_class($this) . '__page_setup__page_routes',
575
+			$this->_page_routes,
576
+			$this
577
+		);
578
+		$this->_page_config = apply_filters(
579
+			'FHEE__' . get_class($this) . '__page_setup__page_config',
580
+			$this->_page_config,
581
+			$this
582
+		);
583
+		//if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
584
+		// then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
585
+		if (
586
+			method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)
587
+		) {
588
+			add_action(
589
+				'AHEE__EE_Admin_Page__route_admin_request',
590
+				array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
591
+				10,
592
+				2
593
+			);
594
+		}
595
+		//next route only if routing enabled
596
+		if ($this->_routing && ! defined('DOING_AJAX')) {
597
+			$this->_verify_routes();
598
+			//next let's just check user_access and kill if no access
599
+			$this->check_user_access();
600
+			if ($this->_is_UI_request) {
601
+				//admin_init stuff - global, all views for this page class, specific view
602
+				add_action('admin_init', array($this, 'admin_init'), 10);
603
+				if (method_exists($this, 'admin_init_' . $this->_current_view)) {
604
+					add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
605
+				}
606
+			} else {
607
+				//hijack regular WP loading and route admin request immediately
608
+				@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
609
+				$this->route_admin_request();
610
+			}
611
+		}
612
+	}
613
+
614
+
615
+
616
+	/**
617
+	 * Provides a way for related child admin pages to load stuff on the loaded admin page.
618
+	 *
619
+	 * @return void
620
+	 * @throws ReflectionException
621
+	 * @throws EE_Error
622
+	 */
623
+	private function _do_other_page_hooks()
624
+	{
625
+		$registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
626
+		foreach ($registered_pages as $page) {
627
+			//now let's setup the file name and class that should be present
628
+			$classname = str_replace('.class.php', '', $page);
629
+			//autoloaders should take care of loading file
630
+			if (! class_exists($classname)) {
631
+				$error_msg[] = sprintf(
632
+					esc_html__(
633
+						'Something went wrong with loading the %s admin hooks page.',
634
+						'event_espresso'
635
+					),
636
+					$page
637
+				);
638
+				$error_msg[] = $error_msg[0]
639
+							   . "\r\n"
640
+							   . sprintf(
641
+								   esc_html__(
642
+									   'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
643
+									   'event_espresso'
644
+								   ),
645
+								   $page,
646
+								   '<br />',
647
+								   '<strong>' . $classname . '</strong>'
648
+							   );
649
+				throw new EE_Error(implode('||', $error_msg));
650
+			}
651
+			$a = new ReflectionClass($classname);
652
+			//notice we are passing the instance of this class to the hook object.
653
+			$hookobj[] = $a->newInstance($this);
654
+		}
655
+	}
656
+
657
+
658
+
659
+	public function load_page_dependencies()
660
+	{
661
+		try {
662
+			$this->_load_page_dependencies();
663
+		} catch (EE_Error $e) {
664
+			$e->get_error();
665
+		}
666
+	}
667
+
668
+
669
+
670
+	/**
671
+	 * load_page_dependencies
672
+	 * loads things specific to this page class when its loaded.  Really helps with efficiency.
673
+	 *
674
+	 * @return void
675
+	 * @throws DomainException
676
+	 * @throws EE_Error
677
+	 * @throws InvalidArgumentException
678
+	 * @throws InvalidDataTypeException
679
+	 * @throws InvalidInterfaceException
680
+	 * @throws ReflectionException
681
+	 */
682
+	protected function _load_page_dependencies()
683
+	{
684
+		//let's set the current_screen and screen options to override what WP set
685
+		$this->_current_screen = get_current_screen();
686
+		//load admin_notices - global, page class, and view specific
687
+		add_action('admin_notices', array($this, 'admin_notices_global'), 5);
688
+		add_action('admin_notices', array($this, 'admin_notices'), 10);
689
+		if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
690
+			add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
691
+		}
692
+		//load network admin_notices - global, page class, and view specific
693
+		add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
694
+		if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
695
+			add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
696
+		}
697
+		//this will save any per_page screen options if they are present
698
+		$this->_set_per_page_screen_options();
699
+		//setup list table properties
700
+		$this->_set_list_table();
701
+		// child classes can "register" a metabox to be automatically handled via the _page_config array property.
702
+		// However in some cases the metaboxes will need to be added within a route handling callback.
703
+		$this->_add_registered_meta_boxes();
704
+		$this->_add_screen_columns();
705
+		//add screen options - global, page child class, and view specific
706
+		$this->_add_global_screen_options();
707
+		$this->_add_screen_options();
708
+		$add_screen_options  = "_add_screen_options_{$this->_current_view}";
709
+		if (method_exists($this, $add_screen_options )) {
710
+			$this->{$add_screen_options};
711
+		}
712
+		//add help tab(s) and tours- set via page_config and qtips.
713
+		$this->_add_help_tour();
714
+		$this->_add_help_tabs();
715
+		$this->_add_qtips();
716
+		//add feature_pointers - global, page child class, and view specific
717
+		$this->_add_feature_pointers();
718
+		$this->_add_global_feature_pointers();
719
+		$add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
720
+		if (method_exists($this, $add_feature_pointer )) {
721
+			$this->{$add_feature_pointer};
722
+		}
723
+		//enqueue scripts/styles - global, page class, and view specific
724
+		add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
725
+		add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
726
+		if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
727
+			add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
728
+		}
729
+		add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
730
+		// admin_print_footer_scripts - global, page child class, and view specific.
731
+		// NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
732
+		// In most cases that's doing_it_wrong().  But adding hidden container elements etc.
733
+		// is a good use case. Notice the late priority we're giving these
734
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
735
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
736
+		if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
737
+			add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
738
+		}
739
+		//admin footer scripts
740
+		add_action('admin_footer', array($this, 'admin_footer_global'), 99);
741
+		add_action('admin_footer', array($this, 'admin_footer'), 100);
742
+		if (method_exists($this, "admin_footer_{$this->_current_view}")) {
743
+			add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
744
+		}
745
+		do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
746
+		//targeted hook
747
+		do_action(
748
+			"FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
749
+
750
+		);
751
+	}
752
+
753
+
754
+
755
+	/**
756
+	 * _set_defaults
757
+	 * This sets some global defaults for class properties.
758
+	 */
759
+	private function _set_defaults()
760
+	{
761
+		$this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
762
+		$this->_event = $this->_template_path = $this->_column_template_path = null;
763
+		$this->_nav_tabs = $this->_views = $this->_page_routes = array();
764
+		$this->_page_config = $this->_default_route_query_args = array();
765
+		$this->_default_nav_tab_name = 'overview';
766
+		//init template args
767
+		$this->_template_args = array(
768
+			'admin_page_header'  => '',
769
+			'admin_page_content' => '',
770
+			'post_body_content'  => '',
771
+			'before_list_table'  => '',
772
+			'after_list_table'   => '',
773
+		);
774
+	}
775
+
776
+
777
+
778
+	/**
779
+	 * route_admin_request
780
+	 *
781
+	 * @see    _route_admin_request()
782
+	 * @return exception|void error
783
+	 * @throws InvalidArgumentException
784
+	 * @throws InvalidInterfaceException
785
+	 * @throws InvalidDataTypeException
786
+	 * @throws EE_Error
787
+	 * @throws ReflectionException
788
+	 */
789
+	public function route_admin_request()
790
+	{
791
+		try {
792
+			$this->_route_admin_request();
793
+		} catch (EE_Error $e) {
794
+			$e->get_error();
795
+		}
796
+	}
797
+
798
+
799
+
800
+	public function set_wp_page_slug($wp_page_slug)
801
+	{
802
+		$this->_wp_page_slug = $wp_page_slug;
803
+		//if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
804
+		if (is_network_admin()) {
805
+			$this->_wp_page_slug .= '-network';
806
+		}
807
+	}
808
+
809
+
810
+
811
+	/**
812
+	 * _verify_routes
813
+	 * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
814
+	 * we know if we need to drop out.
815
+	 *
816
+	 * @return bool
817
+	 * @throws EE_Error
818
+	 */
819
+	protected function _verify_routes()
820
+	{
821
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
822
+		if (! $this->_current_page && ! defined('DOING_AJAX')) {
823
+			return false;
824
+		}
825
+		$this->_route = false;
826
+		// check that the page_routes array is not empty
827
+		if (empty($this->_page_routes)) {
828
+			// user error msg
829
+			$error_msg = sprintf(
830
+				esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
831
+				$this->_admin_page_title
832
+			);
833
+			// developer error msg
834
+			$error_msg .= '||' . $error_msg . esc_html__(
835
+				' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
836
+				'event_espresso'
837
+			);
838
+			throw new EE_Error($error_msg);
839
+		}
840
+		// and that the requested page route exists
841
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
842
+			$this->_route        = $this->_page_routes[$this->_req_action];
843
+			$this->_route_config = isset($this->_page_config[$this->_req_action])
844
+				? $this->_page_config[$this->_req_action] : array();
845
+		} else {
846
+			// user error msg
847
+			$error_msg = sprintf(
848
+				esc_html__(
849
+						'The requested page route does not exist for the %s admin page.',
850
+						'event_espresso'
851
+				),
852
+				$this->_admin_page_title
853
+			);
854
+			// developer error msg
855
+			$error_msg .= '||' . $error_msg . sprintf(
856
+					esc_html__(
857
+						' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
858
+						'event_espresso'
859
+					),
860
+					$this->_req_action
861
+				);
862
+			throw new EE_Error($error_msg);
863
+		}
864
+		// and that a default route exists
865
+		if (! array_key_exists('default', $this->_page_routes)) {
866
+			// user error msg
867
+			$error_msg = sprintf(
868
+				esc_html__(
869
+						'A default page route has not been set for the % admin page.',
870
+						'event_espresso'
871
+				),
872
+				$this->_admin_page_title
873
+			);
874
+			// developer error msg
875
+			$error_msg .= '||' . $error_msg . esc_html__(
876
+				' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
877
+				'event_espresso'
878
+			);
879
+			throw new EE_Error($error_msg);
880
+		}
881
+		//first lets' catch if the UI request has EVER been set.
882
+		if ($this->_is_UI_request === null) {
883
+			//lets set if this is a UI request or not.
884
+			$this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
885
+			//wait a minute... we might have a noheader in the route array
886
+			$this->_is_UI_request = is_array($this->_route)
887
+									&& isset($this->_route['noheader'])
888
+									&& $this->_route['noheader'] ? false : $this->_is_UI_request;
889
+		}
890
+		$this->_set_current_labels();
891
+		return true;
892
+	}
893
+
894
+
895
+
896
+	/**
897
+	 * this method simply verifies a given route and makes sure its an actual route available for the loaded page
898
+	 *
899
+	 * @param  string $route the route name we're verifying
900
+	 * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
901
+	 * @throws EE_Error
902
+	 */
903
+	protected function _verify_route($route)
904
+	{
905
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
906
+			return true;
907
+		}
908
+		// user error msg
909
+		$error_msg = sprintf(
910
+			esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
911
+			$this->_admin_page_title
912
+		);
913
+		// developer error msg
914
+		$error_msg .= '||' . $error_msg . sprintf(
915
+				esc_html__(
916
+					' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
917
+					'event_espresso'
918
+				),
919
+				$route
920
+			);
921
+		throw new EE_Error($error_msg);
922
+	}
923
+
924
+
925
+
926
+	/**
927
+	 * perform nonce verification
928
+	 * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
929
+	 * using this method (and save retyping!)
930
+	 *
931
+	 * @param  string $nonce     The nonce sent
932
+	 * @param  string $nonce_ref The nonce reference string (name0)
933
+	 * @return void
934
+	 * @throws EE_Error
935
+	 */
936
+	protected function _verify_nonce($nonce, $nonce_ref)
937
+	{
938
+		// verify nonce against expected value
939
+		if (! wp_verify_nonce($nonce, $nonce_ref)) {
940
+			// these are not the droids you are looking for !!!
941
+			$msg = sprintf(
942
+				esc_html__('%sNonce Fail.%s', 'event_espresso'),
943
+				'<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
944
+				'</a>'
945
+			);
946
+			if (WP_DEBUG) {
947
+				$msg .= "\n  " . sprintf(
948
+						esc_html__(
949
+							'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
950
+							'event_espresso'
951
+						),
952
+						__CLASS__
953
+					);
954
+			}
955
+			if (! defined('DOING_AJAX')) {
956
+				wp_die($msg);
957
+			} else {
958
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
959
+				$this->_return_json();
960
+			}
961
+		}
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 * _route_admin_request()
968
+	 * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if theres are
969
+	 * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
970
+	 * in the page routes and then will try to load the corresponding method.
971
+	 *
972
+	 * @return void
973
+	 * @throws EE_Error
974
+	 * @throws InvalidArgumentException
975
+	 * @throws InvalidDataTypeException
976
+	 * @throws InvalidInterfaceException
977
+	 * @throws ReflectionException
978
+	 */
979
+	protected function _route_admin_request()
980
+	{
981
+		if (! $this->_is_UI_request) {
982
+			$this->_verify_routes();
983
+		}
984
+		$nonce_check = isset($this->_route_config['require_nonce'])
985
+			? $this->_route_config['require_nonce']
986
+			: true;
987
+		if ($this->_req_action !== 'default' && $nonce_check) {
988
+			// set nonce from post data
989
+			$nonce = isset($this->_req_data[$this->_req_nonce])
990
+				? sanitize_text_field($this->_req_data[$this->_req_nonce])
991
+				: '';
992
+			$this->_verify_nonce($nonce, $this->_req_nonce);
993
+		}
994
+		//set the nav_tabs array but ONLY if this is  UI_request
995
+		if ($this->_is_UI_request) {
996
+			$this->_set_nav_tabs();
997
+		}
998
+		// grab callback function
999
+		$func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
1000
+		// check if callback has args
1001
+		$args      = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1002
+		$error_msg = '';
1003
+		// action right before calling route
1004
+		// (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1005
+		if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1006
+			do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1007
+		}
1008
+		// right before calling the route, let's remove _wp_http_referer from the
1009
+		// $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1010
+		$_SERVER['REQUEST_URI'] = remove_query_arg(
1011
+				'_wp_http_referer',
1012
+				wp_unslash($_SERVER['REQUEST_URI'])
1013
+		);
1014
+		if (! empty($func)) {
1015
+			if (is_array($func)) {
1016
+				list($class, $method) = $func;
1017
+			} elseif (strpos($func, '::') !== false) {
1018
+				list($class, $method) = explode('::', $func);
1019
+			} else {
1020
+				$class  = $this;
1021
+				$method = $func;
1022
+			}
1023
+			if (! (is_object($class) && $class === $this)) {
1024
+				// send along this admin page object for access by addons.
1025
+				$args['admin_page_object'] = $this;
1026
+			}
1027
+			if (
1028
+				//is it a method on a class that doesn't work?
1029
+				(
1030
+					(
1031
+						method_exists($class, $method)
1032
+						&& call_user_func_array(array($class, $method), $args) === false
1033
+					)
1034
+					&& (
1035
+						//is it a standalone function that doesn't work?
1036
+						function_exists($method)
1037
+						&& call_user_func_array(
1038
+							$func,
1039
+							array_merge(array('admin_page_object' => $this), $args)
1040
+						   ) === false
1041
+					)
1042
+				)
1043
+				|| (
1044
+					//is it neither a class method NOR a standalone function?
1045
+					! method_exists($class, $method)
1046
+					&& ! function_exists($method)
1047
+				)
1048
+			) {
1049
+				// user error msg
1050
+				$error_msg = esc_html__(
1051
+					'An error occurred. The  requested page route could not be found.',
1052
+					'event_espresso'
1053
+				);
1054
+				// developer error msg
1055
+				$error_msg .= '||';
1056
+				$error_msg .= sprintf(
1057
+					esc_html__(
1058
+						'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1059
+						'event_espresso'
1060
+					),
1061
+					$method
1062
+				);
1063
+			}
1064
+			if (! empty($error_msg)) {
1065
+				throw new EE_Error($error_msg);
1066
+			}
1067
+		}
1068
+		// if we've routed and this route has a no headers route AND a sent_headers_route,
1069
+		// then we need to reset the routing properties to the new route.
1070
+		//now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1071
+		if ($this->_is_UI_request === false
1072
+			&& is_array($this->_route)
1073
+			&& ! empty($this->_route['headers_sent_route'])
1074
+		) {
1075
+			$this->_reset_routing_properties($this->_route['headers_sent_route']);
1076
+		}
1077
+	}
1078
+
1079
+
1080
+
1081
+	/**
1082
+	 * This method just allows the resetting of page properties in the case where a no headers
1083
+	 * route redirects to a headers route in its route config.
1084
+	 *
1085
+	 * @since   4.3.0
1086
+	 * @param  string $new_route New (non header) route to redirect to.
1087
+	 * @return   void
1088
+	 * @throws ReflectionException
1089
+	 * @throws InvalidArgumentException
1090
+	 * @throws InvalidInterfaceException
1091
+	 * @throws InvalidDataTypeException
1092
+	 * @throws EE_Error
1093
+	 */
1094
+	protected function _reset_routing_properties($new_route)
1095
+	{
1096
+		$this->_is_UI_request = true;
1097
+		//now we set the current route to whatever the headers_sent_route is set at
1098
+		$this->_req_data['action'] = $new_route;
1099
+		//rerun page setup
1100
+		$this->_page_setup();
1101
+	}
1102
+
1103
+
1104
+
1105
+	/**
1106
+	 * _add_query_arg
1107
+	 * adds nonce to array of arguments then calls WP add_query_arg function
1108
+	 *(internally just uses EEH_URL's function with the same name)
1109
+	 *
1110
+	 * @param array  $args
1111
+	 * @param string $url
1112
+	 * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1113
+	 *                                        generated url in an associative array indexed by the key 'wp_referer';
1114
+	 *                                        Example usage: If the current page is:
1115
+	 *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1116
+	 *                                        &action=default&event_id=20&month_range=March%202015
1117
+	 *                                        &_wpnonce=5467821
1118
+	 *                                        and you call:
1119
+	 *                                        EE_Admin_Page::add_query_args_and_nonce(
1120
+	 *                                        array(
1121
+	 *                                        'action' => 'resend_something',
1122
+	 *                                        'page=>espresso_registrations'
1123
+	 *                                        ),
1124
+	 *                                        $some_url,
1125
+	 *                                        true
1126
+	 *                                        );
1127
+	 *                                        It will produce a url in this structure:
1128
+	 *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1129
+	 *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1130
+	 *                                        month_range]=March%202015
1131
+	 * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1132
+	 * @return string
1133
+	 */
1134
+	public static function add_query_args_and_nonce(
1135
+		$args = array(),
1136
+		$url = '',
1137
+		$sticky = false,
1138
+		$exclude_nonce = false
1139
+	) {
1140
+		//if there is a _wp_http_referer include the values from the request but only if sticky = true
1141
+		if ($sticky) {
1142
+			$request = $_REQUEST;
1143
+			unset($request['_wp_http_referer']);
1144
+			unset($request['wp_referer']);
1145
+			foreach ($request as $key => $value) {
1146
+				//do not add nonces
1147
+				if (strpos($key, 'nonce') !== false) {
1148
+					continue;
1149
+				}
1150
+				$args['wp_referer[' . $key . ']'] = $value;
1151
+			}
1152
+		}
1153
+		return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1154
+	}
1155
+
1156
+
1157
+
1158
+	/**
1159
+	 * This returns a generated link that will load the related help tab.
1160
+	 *
1161
+	 * @param  string $help_tab_id the id for the connected help tab
1162
+	 * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1163
+	 * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1164
+	 * @uses EEH_Template::get_help_tab_link()
1165
+	 * @return string              generated link
1166
+	 */
1167
+	protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1168
+	{
1169
+		return EEH_Template::get_help_tab_link(
1170
+			$help_tab_id,
1171
+			$this->page_slug,
1172
+			$this->_req_action,
1173
+			$icon_style,
1174
+			$help_text
1175
+		);
1176
+	}
1177
+
1178
+
1179
+
1180
+	/**
1181
+	 * _add_help_tabs
1182
+	 * Note child classes define their help tabs within the page_config array.
1183
+	 *
1184
+	 * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1185
+	 * @return void
1186
+	 * @throws DomainException
1187
+	 * @throws EE_Error
1188
+	 */
1189
+	protected function _add_help_tabs()
1190
+	{
1191
+		$tour_buttons = '';
1192
+		if (isset($this->_page_config[$this->_req_action])) {
1193
+			$config = $this->_page_config[$this->_req_action];
1194
+			//is there a help tour for the current route?  if there is let's setup the tour buttons
1195
+			if (isset($this->_help_tour[$this->_req_action])) {
1196
+				$tb           = array();
1197
+				$tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1198
+				foreach ($this->_help_tour['tours'] as $tour) {
1199
+					//if this is the end tour then we don't need to setup a button
1200
+					if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1201
+						continue;
1202
+					}
1203
+					$tb[] = '<button id="trigger-tour-'
1204
+							. $tour->get_slug()
1205
+							. '" class="button-primary trigger-ee-help-tour">'
1206
+							. $tour->get_label()
1207
+							. '</button>';
1208
+				}
1209
+				$tour_buttons .= implode('<br />', $tb);
1210
+				$tour_buttons .= '</div></div>';
1211
+			}
1212
+			// let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213
+			if (is_array($config) && isset($config['help_sidebar'])) {
1214
+				//check that the callback given is valid
1215
+				if (! method_exists($this, $config['help_sidebar'])) {
1216
+					throw new EE_Error(
1217
+						sprintf(
1218
+							esc_html__(
1219
+								'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1220
+								'event_espresso'
1221
+							),
1222
+							$config['help_sidebar'],
1223
+							get_class($this)
1224
+						)
1225
+					);
1226
+				}
1227
+				$content = apply_filters(
1228
+					'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1229
+					$this->{$config['help_sidebar']}
1230
+				);
1231
+				$content .= $tour_buttons; //add help tour buttons.
1232
+				//do we have any help tours setup?  Cause if we do we want to add the buttons
1233
+				$this->_current_screen->set_help_sidebar($content);
1234
+			}
1235
+			//if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar.
1236
+			if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1237
+				$this->_current_screen->set_help_sidebar($tour_buttons);
1238
+			}
1239
+			//handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1240
+			if (! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1241
+				$_ht['id']      = $this->page_slug;
1242
+				$_ht['title']   = esc_html__('Help Tours', 'event_espresso');
1243
+				$_ht['content'] = '<p>' . esc_html__(
1244
+						'The buttons to the right allow you to start/restart any help tours available for this page',
1245
+						'event_espresso'
1246
+					) . '</p>';
1247
+				$this->_current_screen->add_help_tab($_ht);
1248
+			}
1249
+			if (! isset($config['help_tabs'])) {
1250
+				return;
1251
+			} //no help tabs for this route
1252
+			foreach ((array)$config['help_tabs'] as $tab_id => $cfg) {
1253
+				//we're here so there ARE help tabs!
1254
+				//make sure we've got what we need
1255
+				if (! isset($cfg['title'])) {
1256
+					throw new EE_Error(
1257
+						esc_html__(
1258
+							'The _page_config array is not set up properly for help tabs.  It is missing a title',
1259
+							'event_espresso'
1260
+						)
1261
+					);
1262
+				}
1263
+				if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1264
+					throw new EE_Error(
1265
+						esc_html__(
1266
+							'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1267
+							'event_espresso'
1268
+						)
1269
+					);
1270
+				}
1271
+				//first priority goes to content.
1272
+				if (! empty($cfg['content'])) {
1273
+					$content = ! empty($cfg['content']) ? $cfg['content'] : null;
1274
+					//second priority goes to filename
1275
+				} elseif (! empty($cfg['filename'])) {
1276
+					$file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1277
+					//it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1278
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1279
+															 . basename($this->_get_dir())
1280
+															 . '/help_tabs/'
1281
+															 . $cfg['filename']
1282
+															 . '.help_tab.php' : $file_path;
1283
+					//if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1284
+					if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1285
+						EE_Error::add_error(
1286
+							sprintf(
1287
+								esc_html__(
1288
+									'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1289
+									'event_espresso'
1290
+								),
1291
+								$tab_id,
1292
+								key($config),
1293
+								$file_path
1294
+							),
1295
+							__FILE__,
1296
+							__FUNCTION__,
1297
+							__LINE__
1298
+						);
1299
+						return;
1300
+					}
1301
+					$template_args['admin_page_obj'] = $this;
1302
+					$content = EEH_Template::display_template(
1303
+						$file_path,
1304
+						$template_args,
1305
+						true
1306
+					);
1307
+				} else {
1308
+					$content = '';
1309
+				}
1310
+				//check if callback is valid
1311
+				if (
1312
+					empty($content) && (
1313
+						! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1314
+					)
1315
+				) {
1316
+					EE_Error::add_error(
1317
+						sprintf(
1318
+							esc_html__(
1319
+								'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1320
+								'event_espresso'
1321
+							),
1322
+							$cfg['title']
1323
+						),
1324
+						__FILE__,
1325
+						__FUNCTION__,
1326
+						__LINE__
1327
+					);
1328
+					return;
1329
+				}
1330
+				//setup config array for help tab method
1331
+				$id  = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1332
+				$_ht = array(
1333
+					'id'       => $id,
1334
+					'title'    => $cfg['title'],
1335
+					'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1336
+					'content'  => $content,
1337
+				);
1338
+				$this->_current_screen->add_help_tab($_ht);
1339
+			}
1340
+		}
1341
+	}
1342
+
1343
+
1344
+
1345
+	/**
1346
+	 * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1347
+	 * an array with properties for setting up usage of the joyride plugin
1348
+	 *
1349
+	 * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1350
+	 * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1351
+	 *         _set_page_config() comments
1352
+	 * @return void
1353
+	 * @throws EE_Error
1354
+	 * @throws InvalidArgumentException
1355
+	 * @throws InvalidDataTypeException
1356
+	 * @throws InvalidInterfaceException
1357
+	 */
1358
+	protected function _add_help_tour()
1359
+	{
1360
+		$tours            = array();
1361
+		$this->_help_tour = array();
1362
+		//exit early if help tours are turned off globally
1363
+		if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1364
+			|| ! EE_Registry::instance()->CFG->admin->help_tour_activation
1365
+		) {
1366
+			return;
1367
+		}
1368
+		//loop through _page_config to find any help_tour defined
1369
+		foreach ($this->_page_config as $route => $config) {
1370
+			//we're only going to set things up for this route
1371
+			if ($route !== $this->_req_action) {
1372
+				continue;
1373
+			}
1374
+			if (isset($config['help_tour'])) {
1375
+				foreach ($config['help_tour'] as $tour) {
1376
+					$file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1377
+					// let's see if we can get that file...
1378
+					// if not its possible this is a decaf route not set in caffeinated
1379
+					// so lets try and get the caffeinated equivalent
1380
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1381
+															 . basename($this->_get_dir())
1382
+															 . '/help_tours/'
1383
+															 . $tour
1384
+															 . '.class.php' : $file_path;
1385
+					//if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1386
+					if (! is_readable($file_path)) {
1387
+						EE_Error::add_error(
1388
+							sprintf(
1389
+								esc_html__(
1390
+									'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1391
+									'event_espresso'
1392
+								),
1393
+								$file_path,
1394
+								$tour
1395
+							),
1396
+							__FILE__,
1397
+							__FUNCTION__,
1398
+							__LINE__
1399
+						);
1400
+						return;
1401
+					}
1402
+					require_once $file_path;
1403
+					if (! class_exists($tour)) {
1404
+						$error_msg[] = sprintf(
1405
+							esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1406
+							$tour
1407
+						);
1408
+						$error_msg[] = $error_msg[0] . "\r\n" . sprintf(
1409
+								esc_html__(
1410
+									'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1411
+									'event_espresso'
1412
+								),
1413
+								$tour,
1414
+								'<br />',
1415
+								$tour,
1416
+								$this->_req_action,
1417
+								get_class($this)
1418
+							);
1419
+						throw new EE_Error(implode('||', $error_msg));
1420
+					}
1421
+					$tour_obj                   = new $tour($this->_is_caf);
1422
+					$tours[]                    = $tour_obj;
1423
+					$this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($tour_obj);
1424
+				}
1425
+				//let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1426
+				$end_stop_tour              = new EE_Help_Tour_final_stop($this->_is_caf);
1427
+				$tours[]                    = $end_stop_tour;
1428
+				$this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1429
+			}
1430
+		}
1431
+		if (! empty($tours)) {
1432
+			$this->_help_tour['tours'] = $tours;
1433
+		}
1434
+		// that's it!  Now that the $_help_tours property is set (or not)
1435
+		// the scripts and html should be taken care of automatically.
1436
+	}
1437
+
1438
+
1439
+
1440
+	/**
1441
+	 * This simply sets up any qtips that have been defined in the page config
1442
+	 *
1443
+	 * @return void
1444
+	 */
1445
+	protected function _add_qtips()
1446
+	{
1447
+		if (isset($this->_route_config['qtips'])) {
1448
+			$qtips = (array)$this->_route_config['qtips'];
1449
+			//load qtip loader
1450
+			$path = array(
1451
+				$this->_get_dir() . '/qtips/',
1452
+				EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1453
+			);
1454
+			EEH_Qtip_Loader::instance()->register($qtips, $path);
1455
+		}
1456
+	}
1457
+
1458
+
1459
+
1460
+	/**
1461
+	 * _set_nav_tabs
1462
+	 * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1463
+	 * wish to add additional tabs or modify accordingly.
1464
+	 *
1465
+	 * @return void
1466
+	 * @throws InvalidArgumentException
1467
+	 * @throws InvalidInterfaceException
1468
+	 * @throws InvalidDataTypeException
1469
+	 */
1470
+	protected function _set_nav_tabs()
1471
+	{
1472
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1473
+		$i = 0;
1474
+		foreach ($this->_page_config as $slug => $config) {
1475
+			if (
1476
+				! is_array($config)
1477
+				|| (
1478
+					is_array($config)
1479
+					&& (isset($config['nav']) && ! $config['nav'])
1480
+					|| ! isset($config['nav'])
1481
+				)
1482
+			) {
1483
+				continue;
1484
+			}
1485
+			//no nav tab for this config
1486
+			//check for persistent flag
1487
+			if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1488
+				// nav tab is only to appear when route requested.
1489
+				continue;
1490
+			}
1491
+			if (! $this->check_user_access($slug, true)) {
1492
+				// no nav tab because current user does not have access.
1493
+				continue;
1494
+			}
1495
+			$css_class              = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1496
+			$this->_nav_tabs[$slug] = array(
1497
+				'url'       => isset($config['nav']['url'])
1498
+					? $config['nav']['url']
1499
+					: self::add_query_args_and_nonce(
1500
+						array('action' => $slug),
1501
+						$this->_admin_base_url
1502
+					),
1503
+				'link_text' => isset($config['nav']['label'])
1504
+					? $config['nav']['label']
1505
+					: ucwords(
1506
+						str_replace('_', ' ', $slug)
1507
+					),
1508
+				'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1509
+				'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1510
+			);
1511
+			$i++;
1512
+		}
1513
+		//if $this->_nav_tabs is empty then lets set the default
1514
+		if (empty($this->_nav_tabs)) {
1515
+			$this->_nav_tabs[$this->_default_nav_tab_name] = array(
1516
+				'url'       => $this->_admin_base_url,
1517
+				'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1518
+				'css_class' => 'nav-tab-active',
1519
+				'order'     => 10,
1520
+			);
1521
+		}
1522
+		//now let's sort the tabs according to order
1523
+		usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1524
+	}
1525
+
1526
+
1527
+
1528
+	/**
1529
+	 * _set_current_labels
1530
+	 * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1531
+	 * property array
1532
+	 *
1533
+	 * @return void
1534
+	 */
1535
+	private function _set_current_labels()
1536
+	{
1537
+		if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1538
+			foreach ($this->_route_config['labels'] as $label => $text) {
1539
+				if (is_array($text)) {
1540
+					foreach ($text as $sublabel => $subtext) {
1541
+						$this->_labels[$label][$sublabel] = $subtext;
1542
+					}
1543
+				} else {
1544
+					$this->_labels[$label] = $text;
1545
+				}
1546
+			}
1547
+		}
1548
+	}
1549
+
1550
+
1551
+
1552
+	/**
1553
+	 *        verifies user access for this admin page
1554
+	 *
1555
+	 * @param string $route_to_check if present then the capability for the route matching this string is checked.
1556
+	 * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1557
+	 *                               return false if verify fail.
1558
+	 * @return bool
1559
+	 * @throws InvalidArgumentException
1560
+	 * @throws InvalidDataTypeException
1561
+	 * @throws InvalidInterfaceException
1562
+	 */
1563
+	public function check_user_access($route_to_check = '', $verify_only = false)
1564
+	{
1565
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1566
+		$route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1567
+		$capability     = ! empty($route_to_check) && isset($this->_page_routes[$route_to_check])
1568
+						  && is_array(
1569
+							  $this->_page_routes[$route_to_check]
1570
+						  )
1571
+						  && ! empty($this->_page_routes[$route_to_check]['capability'])
1572
+			? $this->_page_routes[$route_to_check]['capability'] : null;
1573
+		if (empty($capability) && empty($route_to_check)) {
1574
+			$capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1575
+				: $this->_route['capability'];
1576
+		} else {
1577
+			$capability = empty($capability) ? 'manage_options' : $capability;
1578
+		}
1579
+		$id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1580
+		if (
1581
+			! defined('DOING_AJAX')
1582
+			&& (
1583
+				! function_exists('is_admin')
1584
+				|| ! EE_Registry::instance()->CAP->current_user_can(
1585
+					$capability,
1586
+					$this->page_slug
1587
+					. '_'
1588
+					. $route_to_check,
1589
+					$id
1590
+				)
1591
+			)
1592
+		) {
1593
+			if ($verify_only) {
1594
+				return false;
1595
+			}
1596
+			if (is_user_logged_in()) {
1597
+				wp_die(__('You do not have access to this route.', 'event_espresso'));
1598
+			} else {
1599
+				return false;
1600
+			}
1601
+		}
1602
+		return true;
1603
+	}
1604
+
1605
+
1606
+
1607
+	/**
1608
+	 * admin_init_global
1609
+	 * This runs all the code that we want executed within the WP admin_init hook.
1610
+	 * This method executes for ALL EE Admin pages.
1611
+	 *
1612
+	 * @return void
1613
+	 */
1614
+	public function admin_init_global()
1615
+	{
1616
+	}
1617
+
1618
+
1619
+
1620
+	/**
1621
+	 * wp_loaded_global
1622
+	 * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1623
+	 * EE_Admin page and will execute on every EE Admin Page load
1624
+	 *
1625
+	 * @return void
1626
+	 */
1627
+	public function wp_loaded()
1628
+	{
1629
+	}
1630
+
1631
+
1632
+
1633
+	/**
1634
+	 * admin_notices
1635
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1636
+	 * ALL EE_Admin pages.
1637
+	 *
1638
+	 * @return void
1639
+	 */
1640
+	public function admin_notices_global()
1641
+	{
1642
+		$this->_display_no_javascript_warning();
1643
+		$this->_display_espresso_notices();
1644
+	}
1645
+
1646
+
1647
+
1648
+	public function network_admin_notices_global()
1649
+	{
1650
+		$this->_display_no_javascript_warning();
1651
+		$this->_display_espresso_notices();
1652
+	}
1653
+
1654
+
1655
+
1656
+	/**
1657
+	 * admin_footer_scripts_global
1658
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1659
+	 * will apply on ALL EE_Admin pages.
1660
+	 *
1661
+	 * @return void
1662
+	 */
1663
+	public function admin_footer_scripts_global()
1664
+	{
1665
+		$this->_add_admin_page_ajax_loading_img();
1666
+		$this->_add_admin_page_overlay();
1667
+		//if metaboxes are present we need to add the nonce field
1668
+		if (
1669
+			 isset($this->_route_config['metaboxes'])
1670
+			 || isset($this->_route_config['list_table'])
1671
+			 || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1672
+		) {
1673
+			wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1674
+			wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1675
+		}
1676
+	}
1677
+
1678
+
1679
+
1680
+	/**
1681
+	 * admin_footer_global
1682
+	 * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on
1683
+	 * ALL EE_Admin Pages.
1684
+	 *
1685
+	 * @return  void
1686
+	 */
1687
+	public function admin_footer_global()
1688
+	{
1689
+		//dialog container for dialog helper
1690
+		$d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1691
+		$d_cont .= '<div class="ee-notices"></div>';
1692
+		$d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1693
+		$d_cont .= '</div>';
1694
+		echo $d_cont;
1695
+		//help tour stuff?
1696
+		if (isset($this->_help_tour[$this->_req_action])) {
1697
+			echo implode('<br />', $this->_help_tour[$this->_req_action]);
1698
+		}
1699
+		//current set timezone for timezone js
1700
+		echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1701
+	}
1702
+
1703
+
1704
+
1705
+	/**
1706
+	 * This function sees if there is a method for help popup content existing for the given route.  If there is then
1707
+	 * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1708
+	 * help popups then in your templates or your content you set "triggers" for the content using the
1709
+	 * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1710
+	 * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1711
+	 * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1712
+	 * for the
1713
+	 * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1714
+	 * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1715
+	 *    'help_trigger_id' => array(
1716
+	 *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1717
+	 *        'content' => esc_html__('localized content for popup', 'event_espresso')
1718
+	 *    )
1719
+	 * );
1720
+	 * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1721
+	 *
1722
+	 * @param array $help_array
1723
+	 * @param bool  $display
1724
+	 * @return string content
1725
+	 * @throws DomainException
1726
+	 * @throws EE_Error
1727
+	 */
1728
+	protected function _set_help_popup_content($help_array = array(), $display = false)
1729
+	{
1730
+		$content       = '';
1731
+		$help_array    = empty($help_array) ? $this->_get_help_content() : $help_array;
1732
+		//loop through the array and setup content
1733
+		foreach ($help_array as $trigger => $help) {
1734
+			//make sure the array is setup properly
1735
+			if (! isset($help['title']) || ! isset($help['content'])) {
1736
+				throw new EE_Error(
1737
+					esc_html__(
1738
+						'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1739
+						'event_espresso'
1740
+					)
1741
+				);
1742
+			}
1743
+			//we're good so let'd setup the template vars and then assign parsed template content to our content.
1744
+			$template_args = array(
1745
+				'help_popup_id'      => $trigger,
1746
+				'help_popup_title'   => $help['title'],
1747
+				'help_popup_content' => $help['content'],
1748
+			);
1749
+			$content       .= EEH_Template::display_template(
1750
+				EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1751
+				$template_args,
1752
+				true
1753
+			);
1754
+		}
1755
+		if ($display) {
1756
+			echo $content;
1757
+			return '';
1758
+		}
1759
+		return $content;
1760
+	}
1761
+
1762
+
1763
+
1764
+	/**
1765
+	 * All this does is retrieve the help content array if set by the EE_Admin_Page child
1766
+	 *
1767
+	 * @return array properly formatted array for help popup content
1768
+	 * @throws EE_Error
1769
+	 */
1770
+	private function _get_help_content()
1771
+	{
1772
+		//what is the method we're looking for?
1773
+		$method_name = '_help_popup_content_' . $this->_req_action;
1774
+		//if method doesn't exist let's get out.
1775
+		if (! method_exists($this, $method_name)) {
1776
+			return array();
1777
+		}
1778
+		//k we're good to go let's retrieve the help array
1779
+		$help_array = call_user_func(array($this, $method_name));
1780
+		//make sure we've got an array!
1781
+		if (! is_array($help_array)) {
1782
+			throw new EE_Error(
1783
+				esc_html__(
1784
+					'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1785
+					'event_espresso'
1786
+				)
1787
+			);
1788
+		}
1789
+		return $help_array;
1790
+	}
1791
+
1792
+
1793
+
1794
+	/**
1795
+	 * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1796
+	 * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1797
+	 * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1798
+	 *
1799
+	 * @param string  $trigger_id reference for retrieving the trigger content for the popup
1800
+	 * @param boolean $display    if false then we return the trigger string
1801
+	 * @param array   $dimensions an array of dimensions for the box (array(h,w))
1802
+	 * @return string
1803
+	 * @throws DomainException
1804
+	 * @throws EE_Error
1805
+	 */
1806
+	protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1807
+	{
1808
+		if (defined('DOING_AJAX')) {
1809
+			return '';
1810
+		}
1811
+		//let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1812
+		$help_array   = $this->_get_help_content();
1813
+		$help_content = '';
1814
+		if (empty($help_array) || ! isset($help_array[$trigger_id])) {
1815
+			$help_array[$trigger_id] = array(
1816
+				'title'   => esc_html__('Missing Content', 'event_espresso'),
1817
+				'content' => esc_html__(
1818
+					'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1819
+					'event_espresso'
1820
+				),
1821
+			);
1822
+			$help_content            = $this->_set_help_popup_content($help_array, false);
1823
+		}
1824
+		//let's setup the trigger
1825
+		$content = '<a class="ee-dialog" href="?height='
1826
+				   . $dimensions[0]
1827
+				   . '&width='
1828
+				   . $dimensions[1]
1829
+				   . '&inlineId='
1830
+				   . $trigger_id
1831
+				   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1832
+		$content .= $help_content;
1833
+		if ($display) {
1834
+			echo $content;
1835
+			return  '';
1836
+		}
1837
+		return $content;
1838
+	}
1839
+
1840
+
1841
+
1842
+	/**
1843
+	 * _add_global_screen_options
1844
+	 * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1845
+	 * This particular method will add_screen_options on ALL EE_Admin Pages
1846
+	 *
1847
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1848
+	 *         see also WP_Screen object documents...
1849
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1850
+	 * @abstract
1851
+	 * @return void
1852
+	 */
1853
+	private function _add_global_screen_options()
1854
+	{
1855
+	}
1856
+
1857
+
1858
+
1859
+	/**
1860
+	 * _add_global_feature_pointers
1861
+	 * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1862
+	 * This particular method will implement feature pointers for ALL EE_Admin pages.
1863
+	 * Note: this is just a placeholder for now.  Implementation will come down the road
1864
+	 *
1865
+	 * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1866
+	 *         extended) also see:
1867
+	 * @link   http://eamann.com/tech/wordpress-portland/
1868
+	 * @abstract
1869
+	 * @return void
1870
+	 */
1871
+	private function _add_global_feature_pointers()
1872
+	{
1873
+	}
1874
+
1875
+
1876
+
1877
+	/**
1878
+	 * load_global_scripts_styles
1879
+	 * The scripts and styles enqueued in here will be loaded on every EE Admin page
1880
+	 *
1881
+	 * @return void
1882
+	 */
1883
+	public function load_global_scripts_styles()
1884
+	{
1885
+		/** STYLES **/
1886
+		// add debugging styles
1887
+		if (WP_DEBUG) {
1888
+			add_action('admin_head', array($this, 'add_xdebug_style'));
1889
+		}
1890
+		// register all styles
1891
+		wp_register_style(
1892
+			'espresso-ui-theme',
1893
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1894
+			array(),
1895
+			EVENT_ESPRESSO_VERSION
1896
+		);
1897
+		wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1898
+		//helpers styles
1899
+		wp_register_style(
1900
+			'ee-text-links',
1901
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1902
+			array(),
1903
+			EVENT_ESPRESSO_VERSION
1904
+		);
1905
+		/** SCRIPTS **/
1906
+		//register all scripts
1907
+		wp_register_script(
1908
+			'ee-dialog',
1909
+			EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1910
+			array('jquery', 'jquery-ui-draggable'),
1911
+			EVENT_ESPRESSO_VERSION,
1912
+			true
1913
+		);
1914
+		wp_register_script(
1915
+			'ee_admin_js',
1916
+			EE_ADMIN_URL . 'assets/ee-admin-page.js',
1917
+			array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1918
+			EVENT_ESPRESSO_VERSION,
1919
+			true
1920
+		);
1921
+		wp_register_script(
1922
+			'jquery-ui-timepicker-addon',
1923
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1924
+			array('jquery-ui-datepicker', 'jquery-ui-slider'),
1925
+			EVENT_ESPRESSO_VERSION,
1926
+			true
1927
+		);
1928
+		add_filter('FHEE_load_joyride', '__return_true');
1929
+		//script for sorting tables
1930
+		wp_register_script(
1931
+			'espresso_ajax_table_sorting',
1932
+			EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1933
+			array('ee_admin_js', 'jquery-ui-sortable'),
1934
+			EVENT_ESPRESSO_VERSION,
1935
+			true
1936
+		);
1937
+		//script for parsing uri's
1938
+		wp_register_script(
1939
+			'ee-parse-uri',
1940
+			EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1941
+			array(),
1942
+			EVENT_ESPRESSO_VERSION,
1943
+			true
1944
+		);
1945
+		//and parsing associative serialized form elements
1946
+		wp_register_script(
1947
+			'ee-serialize-full-array',
1948
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1949
+			array('jquery'),
1950
+			EVENT_ESPRESSO_VERSION,
1951
+			true
1952
+		);
1953
+		//helpers scripts
1954
+		wp_register_script(
1955
+			'ee-text-links',
1956
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1957
+			array('jquery'),
1958
+			EVENT_ESPRESSO_VERSION,
1959
+			true
1960
+		);
1961
+		wp_register_script(
1962
+			'ee-moment-core',
1963
+			EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1964
+			array(),
1965
+			EVENT_ESPRESSO_VERSION,
1966
+			true
1967
+		);
1968
+		wp_register_script(
1969
+			'ee-moment',
1970
+			EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1971
+			array('ee-moment-core'),
1972
+			EVENT_ESPRESSO_VERSION,
1973
+			true
1974
+		);
1975
+		wp_register_script(
1976
+			'ee-datepicker',
1977
+			EE_ADMIN_URL . 'assets/ee-datepicker.js',
1978
+			array('jquery-ui-timepicker-addon', 'ee-moment'),
1979
+			EVENT_ESPRESSO_VERSION,
1980
+			true
1981
+		);
1982
+		//google charts
1983
+		wp_register_script(
1984
+			'google-charts',
1985
+			'https://www.gstatic.com/charts/loader.js',
1986
+			array(),
1987
+			EVENT_ESPRESSO_VERSION,
1988
+			false
1989
+		);
1990
+		// ENQUEUE ALL BASICS BY DEFAULT
1991
+		wp_enqueue_style('ee-admin-css');
1992
+		wp_enqueue_script('ee_admin_js');
1993
+		wp_enqueue_script('ee-accounting');
1994
+		wp_enqueue_script('jquery-validate');
1995
+		//taking care of metaboxes
1996
+		if (
1997
+			empty($this->_cpt_route)
1998
+			&& (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1999
+		) {
2000
+			wp_enqueue_script('dashboard');
2001
+		}
2002
+		// LOCALIZED DATA
2003
+		//localize script for ajax lazy loading
2004
+		$lazy_loader_container_ids = apply_filters(
2005
+			'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2006
+			array('espresso_news_post_box_content')
2007
+		);
2008
+		wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2009
+		/**
2010
+		 * help tour stuff
2011
+		 */
2012
+		if (! empty($this->_help_tour)) {
2013
+			//register the js for kicking things off
2014
+			wp_enqueue_script(
2015
+				'ee-help-tour',
2016
+				EE_ADMIN_URL . 'assets/ee-help-tour.js',
2017
+				array('jquery-joyride'),
2018
+				EVENT_ESPRESSO_VERSION,
2019
+				true
2020
+			);
2021
+			//setup tours for the js tour object
2022
+			foreach ($this->_help_tour['tours'] as $tour) {
2023
+				if ($tour instanceof EE_Help_Tour) {
2024
+					$tours[] = array(
2025
+						'id'      => $tour->get_slug(),
2026
+						'options' => $tour->get_options(),
2027
+					);
2028
+				}
2029
+			}
2030
+			wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2031
+			//admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2032
+		}
2033
+	}
2034
+
2035
+
2036
+
2037
+	/**
2038
+	 *        admin_footer_scripts_eei18n_js_strings
2039
+	 *
2040
+	 * @return        void
2041
+	 */
2042
+	public function admin_footer_scripts_eei18n_js_strings()
2043
+	{
2044
+		EE_Registry::$i18n_js_strings['ajax_url']       = WP_AJAX_URL;
2045
+		EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2046
+			'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2047
+			'event_espresso'
2048
+		);
2049
+		EE_Registry::$i18n_js_strings['January']        = esc_html__('January', 'event_espresso');
2050
+		EE_Registry::$i18n_js_strings['February']       = esc_html__('February', 'event_espresso');
2051
+		EE_Registry::$i18n_js_strings['March']          = esc_html__('March', 'event_espresso');
2052
+		EE_Registry::$i18n_js_strings['April']          = esc_html__('April', 'event_espresso');
2053
+		EE_Registry::$i18n_js_strings['May']            = esc_html__('May', 'event_espresso');
2054
+		EE_Registry::$i18n_js_strings['June']           = esc_html__('June', 'event_espresso');
2055
+		EE_Registry::$i18n_js_strings['July']           = esc_html__('July', 'event_espresso');
2056
+		EE_Registry::$i18n_js_strings['August']         = esc_html__('August', 'event_espresso');
2057
+		EE_Registry::$i18n_js_strings['September']      = esc_html__('September', 'event_espresso');
2058
+		EE_Registry::$i18n_js_strings['October']        = esc_html__('October', 'event_espresso');
2059
+		EE_Registry::$i18n_js_strings['November']       = esc_html__('November', 'event_espresso');
2060
+		EE_Registry::$i18n_js_strings['December']       = esc_html__('December', 'event_espresso');
2061
+		EE_Registry::$i18n_js_strings['Jan']            = esc_html__('Jan', 'event_espresso');
2062
+		EE_Registry::$i18n_js_strings['Feb']            = esc_html__('Feb', 'event_espresso');
2063
+		EE_Registry::$i18n_js_strings['Mar']            = esc_html__('Mar', 'event_espresso');
2064
+		EE_Registry::$i18n_js_strings['Apr']            = esc_html__('Apr', 'event_espresso');
2065
+		EE_Registry::$i18n_js_strings['May']            = esc_html__('May', 'event_espresso');
2066
+		EE_Registry::$i18n_js_strings['Jun']            = esc_html__('Jun', 'event_espresso');
2067
+		EE_Registry::$i18n_js_strings['Jul']            = esc_html__('Jul', 'event_espresso');
2068
+		EE_Registry::$i18n_js_strings['Aug']            = esc_html__('Aug', 'event_espresso');
2069
+		EE_Registry::$i18n_js_strings['Sep']            = esc_html__('Sep', 'event_espresso');
2070
+		EE_Registry::$i18n_js_strings['Oct']            = esc_html__('Oct', 'event_espresso');
2071
+		EE_Registry::$i18n_js_strings['Nov']            = esc_html__('Nov', 'event_espresso');
2072
+		EE_Registry::$i18n_js_strings['Dec']            = esc_html__('Dec', 'event_espresso');
2073
+		EE_Registry::$i18n_js_strings['Sunday']         = esc_html__('Sunday', 'event_espresso');
2074
+		EE_Registry::$i18n_js_strings['Monday']         = esc_html__('Monday', 'event_espresso');
2075
+		EE_Registry::$i18n_js_strings['Tuesday']        = esc_html__('Tuesday', 'event_espresso');
2076
+		EE_Registry::$i18n_js_strings['Wednesday']      = esc_html__('Wednesday', 'event_espresso');
2077
+		EE_Registry::$i18n_js_strings['Thursday']       = esc_html__('Thursday', 'event_espresso');
2078
+		EE_Registry::$i18n_js_strings['Friday']         = esc_html__('Friday', 'event_espresso');
2079
+		EE_Registry::$i18n_js_strings['Saturday']       = esc_html__('Saturday', 'event_espresso');
2080
+		EE_Registry::$i18n_js_strings['Sun']            = esc_html__('Sun', 'event_espresso');
2081
+		EE_Registry::$i18n_js_strings['Mon']            = esc_html__('Mon', 'event_espresso');
2082
+		EE_Registry::$i18n_js_strings['Tue']            = esc_html__('Tue', 'event_espresso');
2083
+		EE_Registry::$i18n_js_strings['Wed']            = esc_html__('Wed', 'event_espresso');
2084
+		EE_Registry::$i18n_js_strings['Thu']            = esc_html__('Thu', 'event_espresso');
2085
+		EE_Registry::$i18n_js_strings['Fri']            = esc_html__('Fri', 'event_espresso');
2086
+		EE_Registry::$i18n_js_strings['Sat']            = esc_html__('Sat', 'event_espresso');
2087
+	}
2088
+
2089
+
2090
+
2091
+	/**
2092
+	 *        load enhanced xdebug styles for ppl with failing eyesight
2093
+	 *
2094
+	 * @return        void
2095
+	 */
2096
+	public function add_xdebug_style()
2097
+	{
2098
+		echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2099
+	}
2100
+
2101
+
2102
+	/************************/
2103
+	/** LIST TABLE METHODS **/
2104
+	/************************/
2105
+	/**
2106
+	 * this sets up the list table if the current view requires it.
2107
+	 *
2108
+	 * @return void
2109
+	 * @throws EE_Error
2110
+	 */
2111
+	protected function _set_list_table()
2112
+	{
2113
+		//first is this a list_table view?
2114
+		if (! isset($this->_route_config['list_table'])) {
2115
+			return;
2116
+		} //not a list_table view so get out.
2117
+		// list table functions are per view specific (because some admin pages might have more than one listtable!)
2118
+		$list_table_view = '_set_list_table_views_' . $this->_req_action;
2119
+		if ($this->{$list_table_view} === false) {
2120
+			//user error msg
2121
+			$error_msg = esc_html__(
2122
+				'An error occurred. The requested list table views could not be found.',
2123
+				'event_espresso'
2124
+			);
2125
+			//developer error msg
2126
+			$error_msg .= '||' . sprintf(
2127
+					esc_html__(
2128
+						'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2129
+						'event_espresso'
2130
+					),
2131
+					$this->_req_action,
2132
+					$list_table_view
2133
+				);
2134
+			throw new EE_Error($error_msg);
2135
+		}
2136
+		//let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2137
+		$this->_views = apply_filters(
2138
+			'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2139
+			$this->_views
2140
+		);
2141
+		$this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2142
+		$this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2143
+		$this->_set_list_table_view();
2144
+		$this->_set_list_table_object();
2145
+	}
2146
+
2147
+
2148
+
2149
+	/**
2150
+	 * set current view for List Table
2151
+	 *
2152
+	 * @return void
2153
+	 */
2154
+	protected function _set_list_table_view()
2155
+	{
2156
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2157
+		// looking at active items or dumpster diving ?
2158
+		if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2159
+			$this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2160
+		} else {
2161
+			$this->_view = sanitize_key($this->_req_data['status']);
2162
+		}
2163
+	}
2164
+
2165
+
2166
+
2167
+	/**
2168
+	 * _set_list_table_object
2169
+	 * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2170
+	 *
2171
+	 * @throws EE_Error
2172
+	 */
2173
+	protected function _set_list_table_object()
2174
+	{
2175
+		if (isset($this->_route_config['list_table'])) {
2176
+			if (! class_exists($this->_route_config['list_table'])) {
2177
+				throw new EE_Error(
2178
+					sprintf(
2179
+						esc_html__(
2180
+							'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2181
+							'event_espresso'
2182
+						),
2183
+						$this->_route_config['list_table'],
2184
+						get_class($this)
2185
+					)
2186
+				);
2187
+			}
2188
+			$list_table               = $this->_route_config['list_table'];
2189
+			$this->_list_table_object = new $list_table($this);
2190
+		}
2191
+	}
2192
+
2193
+
2194
+
2195
+	/**
2196
+	 * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2197
+	 *
2198
+	 * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2199
+	 *                                                    urls.  The array should be indexed by the view it is being
2200
+	 *                                                    added to.
2201
+	 * @return array
2202
+	 */
2203
+	public function get_list_table_view_RLs($extra_query_args = array())
2204
+	{
2205
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2206
+		if (empty($this->_views)) {
2207
+			$this->_views = array();
2208
+		}
2209
+		// cycle thru views
2210
+		foreach ($this->_views as $key => $view) {
2211
+			$query_args = array();
2212
+			// check for current view
2213
+			$this->_views[$key]['class']               = $this->_view === $view['slug'] ? 'current' : '';
2214
+			$query_args['action']                      = $this->_req_action;
2215
+			$query_args[$this->_req_action . '_nonce'] = wp_create_nonce($query_args['action'] . '_nonce');
2216
+			$query_args['status']                      = $view['slug'];
2217
+			//merge any other arguments sent in.
2218
+			if (isset($extra_query_args[$view['slug']])) {
2219
+				$query_args = array_merge($query_args, $extra_query_args[$view['slug']]);
2220
+			}
2221
+			$this->_views[$key]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2222
+		}
2223
+		return $this->_views;
2224
+	}
2225
+
2226
+
2227
+
2228
+	/**
2229
+	 * _entries_per_page_dropdown
2230
+	 * generates a drop down box for selecting the number of visible rows in an admin page list table
2231
+	 *
2232
+	 * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2233
+	 *         WP does it.
2234
+	 * @param int $max_entries total number of rows in the table
2235
+	 * @return string
2236
+	 */
2237
+	protected function _entries_per_page_dropdown($max_entries = 0)
2238
+	{
2239
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2240
+		$values   = array(10, 25, 50, 100);
2241
+		$per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2242
+		if ($max_entries) {
2243
+			$values[] = $max_entries;
2244
+			sort($values);
2245
+		}
2246
+		$entries_per_page_dropdown = '
2247 2247
 			<div id="entries-per-page-dv" class="alignleft actions">
2248 2248
 				<label class="hide-if-no-js">
2249 2249
 					Show
2250 2250
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2251
-        foreach ($values as $value) {
2252
-            if ($value < $max_entries) {
2253
-                $selected                  = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2254
-                $entries_per_page_dropdown .= '
2251
+		foreach ($values as $value) {
2252
+			if ($value < $max_entries) {
2253
+				$selected                  = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2254
+				$entries_per_page_dropdown .= '
2255 2255
 						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2256
-            }
2257
-        }
2258
-        $selected                  = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2259
-        $entries_per_page_dropdown .= '
2256
+			}
2257
+		}
2258
+		$selected                  = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2259
+		$entries_per_page_dropdown .= '
2260 2260
 						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2261
-        $entries_per_page_dropdown .= '
2261
+		$entries_per_page_dropdown .= '
2262 2262
 					</select>
2263 2263
 					entries
2264 2264
 				</label>
2265 2265
 				<input id="entries-per-page-btn" class="button-secondary" type="submit" value="Go" >
2266 2266
 			</div>
2267 2267
 		';
2268
-        return $entries_per_page_dropdown;
2269
-    }
2270
-
2271
-
2272
-
2273
-    /**
2274
-     *        _set_search_attributes
2275
-     *
2276
-     * @return        void
2277
-     */
2278
-    public function _set_search_attributes()
2279
-    {
2280
-        $this->_template_args['search']['btn_label'] = sprintf(
2281
-            esc_html__('Search %s', 'event_espresso'),
2282
-            empty($this->_search_btn_label) ? $this->page_label
2283
-                : $this->_search_btn_label
2284
-        );
2285
-        $this->_template_args['search']['callback']  = 'search_' . $this->page_slug;
2286
-    }
2287
-
2288
-
2289
-
2290
-    /*** END LIST TABLE METHODS **/
2291
-
2292
-
2293
-
2294
-    /**
2295
-     * _add_registered_metaboxes
2296
-     *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2297
-     *
2298
-     * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2299
-     * @return void
2300
-     * @throws EE_Error
2301
-     */
2302
-    private function _add_registered_meta_boxes()
2303
-    {
2304
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2305
-        //we only add meta boxes if the page_route calls for it
2306
-        if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2307
-            && is_array(
2308
-                $this->_route_config['metaboxes']
2309
-            )
2310
-        ) {
2311
-            // this simply loops through the callbacks provided
2312
-            // and checks if there is a corresponding callback registered by the child
2313
-            // if there is then we go ahead and process the metabox loader.
2314
-            foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2315
-                // first check for Closures
2316
-                if ($metabox_callback instanceof Closure) {
2317
-                    $result = $metabox_callback();
2318
-                } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2319
-                    $result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2320
-                } else {
2321
-                    $result = call_user_func(array($this, &$metabox_callback));
2322
-                }
2323
-                if ($result === false) {
2324
-                    // user error msg
2325
-                    $error_msg = esc_html__(
2326
-                            'An error occurred. The  requested metabox could not be found.',
2327
-                            'event_espresso'
2328
-                    );
2329
-                    // developer error msg
2330
-                    $error_msg .= '||' . sprintf(
2331
-                            esc_html__(
2332
-                                'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2333
-                                'event_espresso'
2334
-                            ),
2335
-                            $metabox_callback
2336
-                        );
2337
-                    throw new EE_Error($error_msg);
2338
-                }
2339
-            }
2340
-        }
2341
-    }
2342
-
2343
-
2344
-
2345
-    /**
2346
-     * _add_screen_columns
2347
-     * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2348
-     * the dynamic column template and we'll setup the column options for the page.
2349
-     *
2350
-     * @return void
2351
-     */
2352
-    private function _add_screen_columns()
2353
-    {
2354
-        if (
2355
-            is_array($this->_route_config)
2356
-            && isset($this->_route_config['columns'])
2357
-            && is_array($this->_route_config['columns'])
2358
-            && count($this->_route_config['columns']) === 2
2359
-        ) {
2360
-            add_screen_option(
2361
-                'layout_columns',
2362
-                array(
2363
-                    'max'     => (int)$this->_route_config['columns'][0],
2364
-                    'default' => (int)$this->_route_config['columns'][1],
2365
-                )
2366
-            );
2367
-            $this->_template_args['num_columns']                 = $this->_route_config['columns'][0];
2368
-            $screen_id                                           = $this->_current_screen->id;
2369
-            $screen_columns                                      = (int)get_user_option("screen_layout_{$screen_id}");
2370
-            $total_columns                                       = ! empty($screen_columns)
2371
-                ? $screen_columns
2372
-                : $this->_route_config['columns'][1];
2373
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2374
-            $this->_template_args['current_page']                = $this->_wp_page_slug;
2375
-            $this->_template_args['screen']                      = $this->_current_screen;
2376
-            $this->_column_template_path                         = EE_ADMIN_TEMPLATE
2377
-                                                                   . 'admin_details_metabox_column_wrapper.template.php';
2378
-            // finally if we don't have has_metaboxes set in the route config
2379
-            // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2380
-            $this->_route_config['has_metaboxes'] = true;
2381
-        }
2382
-    }
2383
-
2384
-
2385
-
2386
-    /** GLOBALLY AVAILABLE METABOXES **/
2387
-
2388
-
2389
-    /**
2390
-     * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2391
-     * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2392
-     * these get loaded on.
2393
-     */
2394
-    private function _espresso_news_post_box()
2395
-    {
2396
-        $news_box_title = apply_filters(
2397
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2398
-            esc_html__('New @ Event Espresso', 'event_espresso')
2399
-        );
2400
-        add_meta_box(
2401
-            'espresso_news_post_box',
2402
-            $news_box_title,
2403
-            array(
2404
-                $this,
2405
-                'espresso_news_post_box',
2406
-            ),
2407
-            $this->_wp_page_slug,
2408
-            'side'
2409
-        );
2410
-    }
2411
-
2412
-
2413
-
2414
-    /**
2415
-     * Code for setting up espresso ratings request metabox.
2416
-     */
2417
-    protected function _espresso_ratings_request()
2418
-    {
2419
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2420
-            return;
2421
-        }
2422
-        $ratings_box_title = apply_filters(
2423
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2424
-            esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2425
-        );
2426
-        add_meta_box(
2427
-            'espresso_ratings_request',
2428
-            $ratings_box_title,
2429
-            array(
2430
-                $this,
2431
-                'espresso_ratings_request',
2432
-            ),
2433
-            $this->_wp_page_slug,
2434
-            'side'
2435
-        );
2436
-    }
2437
-
2438
-
2439
-
2440
-    /**
2441
-     * Code for setting up espresso ratings request metabox content.
2442
-     *
2443
-     * @throws DomainException
2444
-     */
2445
-    public function espresso_ratings_request()
2446
-    {
2447
-        EEH_Template::display_template(
2448
-            EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php',
2449
-                array()
2450
-        );
2451
-    }
2452
-
2453
-
2454
-
2455
-    public static function cached_rss_display($rss_id, $url)
2456
-    {
2457
-        $loading    = '<p class="widget-loading hide-if-no-js">'
2458
-                      . __('Loading&#8230;')
2459
-                      . '</p><p class="hide-if-js">'
2460
-                      . esc_html__('This widget requires JavaScript.')
2461
-                      . '</p>';
2462
-        $pre        = '<div class="espresso-rss-display">' . "\n\t";
2463
-        $pre        .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2464
-        $post       = '</div>' . "\n";
2465
-        $cache_key  = 'ee_rss_' . md5($rss_id);
2466
-        $output = get_transient($cache_key);
2467
-        if ($output !== false) {
2468
-            echo $pre . $output . $post;
2469
-            return true;
2470
-        }
2471
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2472
-            echo $pre . $loading . $post;
2473
-            return false;
2474
-        }
2475
-        ob_start();
2476
-        wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2477
-        set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2478
-        return true;
2479
-    }
2480
-
2481
-
2482
-
2483
-    public function espresso_news_post_box()
2484
-    {
2485
-        ?>
2268
+		return $entries_per_page_dropdown;
2269
+	}
2270
+
2271
+
2272
+
2273
+	/**
2274
+	 *        _set_search_attributes
2275
+	 *
2276
+	 * @return        void
2277
+	 */
2278
+	public function _set_search_attributes()
2279
+	{
2280
+		$this->_template_args['search']['btn_label'] = sprintf(
2281
+			esc_html__('Search %s', 'event_espresso'),
2282
+			empty($this->_search_btn_label) ? $this->page_label
2283
+				: $this->_search_btn_label
2284
+		);
2285
+		$this->_template_args['search']['callback']  = 'search_' . $this->page_slug;
2286
+	}
2287
+
2288
+
2289
+
2290
+	/*** END LIST TABLE METHODS **/
2291
+
2292
+
2293
+
2294
+	/**
2295
+	 * _add_registered_metaboxes
2296
+	 *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2297
+	 *
2298
+	 * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2299
+	 * @return void
2300
+	 * @throws EE_Error
2301
+	 */
2302
+	private function _add_registered_meta_boxes()
2303
+	{
2304
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2305
+		//we only add meta boxes if the page_route calls for it
2306
+		if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2307
+			&& is_array(
2308
+				$this->_route_config['metaboxes']
2309
+			)
2310
+		) {
2311
+			// this simply loops through the callbacks provided
2312
+			// and checks if there is a corresponding callback registered by the child
2313
+			// if there is then we go ahead and process the metabox loader.
2314
+			foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2315
+				// first check for Closures
2316
+				if ($metabox_callback instanceof Closure) {
2317
+					$result = $metabox_callback();
2318
+				} elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2319
+					$result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2320
+				} else {
2321
+					$result = call_user_func(array($this, &$metabox_callback));
2322
+				}
2323
+				if ($result === false) {
2324
+					// user error msg
2325
+					$error_msg = esc_html__(
2326
+							'An error occurred. The  requested metabox could not be found.',
2327
+							'event_espresso'
2328
+					);
2329
+					// developer error msg
2330
+					$error_msg .= '||' . sprintf(
2331
+							esc_html__(
2332
+								'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2333
+								'event_espresso'
2334
+							),
2335
+							$metabox_callback
2336
+						);
2337
+					throw new EE_Error($error_msg);
2338
+				}
2339
+			}
2340
+		}
2341
+	}
2342
+
2343
+
2344
+
2345
+	/**
2346
+	 * _add_screen_columns
2347
+	 * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2348
+	 * the dynamic column template and we'll setup the column options for the page.
2349
+	 *
2350
+	 * @return void
2351
+	 */
2352
+	private function _add_screen_columns()
2353
+	{
2354
+		if (
2355
+			is_array($this->_route_config)
2356
+			&& isset($this->_route_config['columns'])
2357
+			&& is_array($this->_route_config['columns'])
2358
+			&& count($this->_route_config['columns']) === 2
2359
+		) {
2360
+			add_screen_option(
2361
+				'layout_columns',
2362
+				array(
2363
+					'max'     => (int)$this->_route_config['columns'][0],
2364
+					'default' => (int)$this->_route_config['columns'][1],
2365
+				)
2366
+			);
2367
+			$this->_template_args['num_columns']                 = $this->_route_config['columns'][0];
2368
+			$screen_id                                           = $this->_current_screen->id;
2369
+			$screen_columns                                      = (int)get_user_option("screen_layout_{$screen_id}");
2370
+			$total_columns                                       = ! empty($screen_columns)
2371
+				? $screen_columns
2372
+				: $this->_route_config['columns'][1];
2373
+			$this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2374
+			$this->_template_args['current_page']                = $this->_wp_page_slug;
2375
+			$this->_template_args['screen']                      = $this->_current_screen;
2376
+			$this->_column_template_path                         = EE_ADMIN_TEMPLATE
2377
+																   . 'admin_details_metabox_column_wrapper.template.php';
2378
+			// finally if we don't have has_metaboxes set in the route config
2379
+			// let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2380
+			$this->_route_config['has_metaboxes'] = true;
2381
+		}
2382
+	}
2383
+
2384
+
2385
+
2386
+	/** GLOBALLY AVAILABLE METABOXES **/
2387
+
2388
+
2389
+	/**
2390
+	 * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2391
+	 * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2392
+	 * these get loaded on.
2393
+	 */
2394
+	private function _espresso_news_post_box()
2395
+	{
2396
+		$news_box_title = apply_filters(
2397
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2398
+			esc_html__('New @ Event Espresso', 'event_espresso')
2399
+		);
2400
+		add_meta_box(
2401
+			'espresso_news_post_box',
2402
+			$news_box_title,
2403
+			array(
2404
+				$this,
2405
+				'espresso_news_post_box',
2406
+			),
2407
+			$this->_wp_page_slug,
2408
+			'side'
2409
+		);
2410
+	}
2411
+
2412
+
2413
+
2414
+	/**
2415
+	 * Code for setting up espresso ratings request metabox.
2416
+	 */
2417
+	protected function _espresso_ratings_request()
2418
+	{
2419
+		if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2420
+			return;
2421
+		}
2422
+		$ratings_box_title = apply_filters(
2423
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2424
+			esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2425
+		);
2426
+		add_meta_box(
2427
+			'espresso_ratings_request',
2428
+			$ratings_box_title,
2429
+			array(
2430
+				$this,
2431
+				'espresso_ratings_request',
2432
+			),
2433
+			$this->_wp_page_slug,
2434
+			'side'
2435
+		);
2436
+	}
2437
+
2438
+
2439
+
2440
+	/**
2441
+	 * Code for setting up espresso ratings request metabox content.
2442
+	 *
2443
+	 * @throws DomainException
2444
+	 */
2445
+	public function espresso_ratings_request()
2446
+	{
2447
+		EEH_Template::display_template(
2448
+			EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php',
2449
+				array()
2450
+		);
2451
+	}
2452
+
2453
+
2454
+
2455
+	public static function cached_rss_display($rss_id, $url)
2456
+	{
2457
+		$loading    = '<p class="widget-loading hide-if-no-js">'
2458
+					  . __('Loading&#8230;')
2459
+					  . '</p><p class="hide-if-js">'
2460
+					  . esc_html__('This widget requires JavaScript.')
2461
+					  . '</p>';
2462
+		$pre        = '<div class="espresso-rss-display">' . "\n\t";
2463
+		$pre        .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2464
+		$post       = '</div>' . "\n";
2465
+		$cache_key  = 'ee_rss_' . md5($rss_id);
2466
+		$output = get_transient($cache_key);
2467
+		if ($output !== false) {
2468
+			echo $pre . $output . $post;
2469
+			return true;
2470
+		}
2471
+		if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2472
+			echo $pre . $loading . $post;
2473
+			return false;
2474
+		}
2475
+		ob_start();
2476
+		wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2477
+		set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2478
+		return true;
2479
+	}
2480
+
2481
+
2482
+
2483
+	public function espresso_news_post_box()
2484
+	{
2485
+		?>
2486 2486
         <div class="padding">
2487 2487
             <div id="espresso_news_post_box_content" class="infolinks">
2488 2488
                 <?php
2489
-                // Get RSS Feed(s)
2490
-                self::cached_rss_display(
2491
-                    'espresso_news_post_box_content',
2492
-                    urlencode(
2493
-                        apply_filters(
2494
-                            'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2495
-                            'http://eventespresso.com/feed/'
2496
-                        )
2497
-                    )
2498
-                );
2499
-                ?>
2489
+				// Get RSS Feed(s)
2490
+				self::cached_rss_display(
2491
+					'espresso_news_post_box_content',
2492
+					urlencode(
2493
+						apply_filters(
2494
+							'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2495
+							'http://eventespresso.com/feed/'
2496
+						)
2497
+					)
2498
+				);
2499
+				?>
2500 2500
             </div>
2501 2501
             <?php do_action('AHEE__EE_Admin_Page__espresso_news_post_box__after_content'); ?>
2502 2502
         </div>
2503 2503
         <?php
2504
-    }
2505
-
2506
-
2507
-
2508
-    private function _espresso_links_post_box()
2509
-    {
2510
-        //Hiding until we actually have content to put in here...
2511
-        //add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2512
-    }
2513
-
2514
-
2515
-
2516
-    public function espresso_links_post_box()
2517
-    {
2518
-        //Hiding until we actually have content to put in here...
2519
-        // EEH_Template::display_template(
2520
-        //     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2521
-        // );
2522
-    }
2523
-
2524
-
2525
-
2526
-    protected function _espresso_sponsors_post_box()
2527
-    {
2528
-        if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2529
-            add_meta_box(
2530
-                'espresso_sponsors_post_box',
2531
-                esc_html__('Event Espresso Highlights', 'event_espresso'),
2532
-                array($this, 'espresso_sponsors_post_box'),
2533
-                $this->_wp_page_slug,
2534
-                'side'
2535
-            );
2536
-        }
2537
-    }
2538
-
2539
-
2540
-
2541
-    public function espresso_sponsors_post_box()
2542
-    {
2543
-        EEH_Template::display_template(
2544
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2545
-        );
2546
-    }
2547
-
2548
-
2549
-
2550
-    private function _publish_post_box()
2551
-    {
2552
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2553
-        // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2554
-        // then we'll use that for the metabox label.
2555
-        // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2556
-        if (! empty($this->_labels['publishbox'])) {
2557
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action]
2558
-                : $this->_labels['publishbox'];
2559
-        } else {
2560
-            $box_label = esc_html__('Publish', 'event_espresso');
2561
-        }
2562
-        $box_label = apply_filters(
2563
-            'FHEE__EE_Admin_Page___publish_post_box__box_label',
2564
-            $box_label,
2565
-            $this->_req_action,
2566
-            $this
2567
-        );
2568
-        add_meta_box(
2569
-            $meta_box_ref,
2570
-            $box_label,
2571
-            array($this, 'editor_overview'),
2572
-            $this->_current_screen->id,
2573
-            'side',
2574
-            'high'
2575
-        );
2576
-    }
2577
-
2578
-
2579
-
2580
-    public function editor_overview()
2581
-    {
2582
-        //if we have extra content set let's add it in if not make sure its empty
2583
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2584
-            ? $this->_template_args['publish_box_extra_content']
2585
-            : '';
2586
-        echo EEH_Template::display_template(
2587
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2588
-            $this->_template_args,
2589
-            true
2590
-        );
2591
-    }
2592
-
2593
-
2594
-    /** end of globally available metaboxes section **/
2595
-
2596
-
2597
-
2598
-    /**
2599
-     * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2600
-     * protected method.
2601
-     *
2602
-     * @see   $this->_set_publish_post_box_vars for param details
2603
-     * @since 4.6.0
2604
-     * @param string $name
2605
-     * @param int    $id
2606
-     * @param bool   $delete
2607
-     * @param string $save_close_redirect_URL
2608
-     * @param bool   $both_btns
2609
-     * @throws EE_Error
2610
-     * @throws InvalidArgumentException
2611
-     * @throws InvalidDataTypeException
2612
-     * @throws InvalidInterfaceException
2613
-     */
2614
-    public function set_publish_post_box_vars(
2615
-        $name = '',
2616
-        $id = 0,
2617
-        $delete = false,
2618
-        $save_close_redirect_URL = '',
2619
-        $both_btns = true
2620
-    ) {
2621
-        $this->_set_publish_post_box_vars(
2622
-            $name,
2623
-            $id,
2624
-            $delete,
2625
-            $save_close_redirect_URL,
2626
-            $both_btns
2627
-        );
2628
-    }
2629
-
2630
-
2631
-
2632
-    /**
2633
-     * Sets the _template_args arguments used by the _publish_post_box shortcut
2634
-     * Note: currently there is no validation for this.  However if you want the delete button, the
2635
-     * save, and save and close buttons to work properly, then you will want to include a
2636
-     * values for the name and id arguments.
2637
-     *
2638
-     * @todo  Add in validation for name/id arguments.
2639
-     * @param    string  $name                    key used for the action ID (i.e. event_id)
2640
-     * @param    int     $id                      id attached to the item published
2641
-     * @param    string  $delete                  page route callback for the delete action
2642
-     * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2643
-     * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2644
-     *                                            the Save button
2645
-     * @throws EE_Error
2646
-     * @throws InvalidArgumentException
2647
-     * @throws InvalidDataTypeException
2648
-     * @throws InvalidInterfaceException
2649
-     */
2650
-    protected function _set_publish_post_box_vars(
2651
-        $name = '',
2652
-        $id = 0,
2653
-        $delete = '',
2654
-        $save_close_redirect_URL = '',
2655
-        $both_btns = true
2656
-    ) {
2657
-        // if Save & Close, use a custom redirect URL or default to the main page?
2658
-        $save_close_redirect_URL = ! empty($save_close_redirect_URL)
2659
-            ? $save_close_redirect_URL
2660
-            : $this->_admin_base_url;
2661
-        // create the Save & Close and Save buttons
2662
-        $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2663
-        //if we have extra content set let's add it in if not make sure its empty
2664
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2665
-            ? $this->_template_args['publish_box_extra_content']
2666
-            : '';
2667
-        if ($delete && ! empty($id)) {
2668
-            //make sure we have a default if just true is sent.
2669
-            $delete           = ! empty($delete) ? $delete : 'delete';
2670
-            $delete_link_args = array($name => $id);
2671
-            $delete           = $this->get_action_link_or_button(
2672
-                $delete,
2673
-                $delete,
2674
-                $delete_link_args,
2675
-                'submitdelete deletion',
2676
-                '',
2677
-                false
2678
-            );
2679
-        }
2680
-        $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2681
-        if (! empty($name) && ! empty($id)) {
2682
-            $hidden_field_arr[$name] = array(
2683
-                'type'  => 'hidden',
2684
-                'value' => $id,
2685
-            );
2686
-            $hf                      = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2687
-        } else {
2688
-            $hf = '';
2689
-        }
2690
-        // add hidden field
2691
-        $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2692
-            ? $hf[$name]['field']
2693
-            : $hf;
2694
-    }
2695
-
2696
-
2697
-
2698
-    /**
2699
-     * displays an error message to ppl who have javascript disabled
2700
-     *
2701
-     * @return void
2702
-     */
2703
-    private function _display_no_javascript_warning()
2704
-    {
2705
-        ?>
2504
+	}
2505
+
2506
+
2507
+
2508
+	private function _espresso_links_post_box()
2509
+	{
2510
+		//Hiding until we actually have content to put in here...
2511
+		//add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2512
+	}
2513
+
2514
+
2515
+
2516
+	public function espresso_links_post_box()
2517
+	{
2518
+		//Hiding until we actually have content to put in here...
2519
+		// EEH_Template::display_template(
2520
+		//     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2521
+		// );
2522
+	}
2523
+
2524
+
2525
+
2526
+	protected function _espresso_sponsors_post_box()
2527
+	{
2528
+		if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2529
+			add_meta_box(
2530
+				'espresso_sponsors_post_box',
2531
+				esc_html__('Event Espresso Highlights', 'event_espresso'),
2532
+				array($this, 'espresso_sponsors_post_box'),
2533
+				$this->_wp_page_slug,
2534
+				'side'
2535
+			);
2536
+		}
2537
+	}
2538
+
2539
+
2540
+
2541
+	public function espresso_sponsors_post_box()
2542
+	{
2543
+		EEH_Template::display_template(
2544
+			EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2545
+		);
2546
+	}
2547
+
2548
+
2549
+
2550
+	private function _publish_post_box()
2551
+	{
2552
+		$meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2553
+		// if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2554
+		// then we'll use that for the metabox label.
2555
+		// Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2556
+		if (! empty($this->_labels['publishbox'])) {
2557
+			$box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action]
2558
+				: $this->_labels['publishbox'];
2559
+		} else {
2560
+			$box_label = esc_html__('Publish', 'event_espresso');
2561
+		}
2562
+		$box_label = apply_filters(
2563
+			'FHEE__EE_Admin_Page___publish_post_box__box_label',
2564
+			$box_label,
2565
+			$this->_req_action,
2566
+			$this
2567
+		);
2568
+		add_meta_box(
2569
+			$meta_box_ref,
2570
+			$box_label,
2571
+			array($this, 'editor_overview'),
2572
+			$this->_current_screen->id,
2573
+			'side',
2574
+			'high'
2575
+		);
2576
+	}
2577
+
2578
+
2579
+
2580
+	public function editor_overview()
2581
+	{
2582
+		//if we have extra content set let's add it in if not make sure its empty
2583
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2584
+			? $this->_template_args['publish_box_extra_content']
2585
+			: '';
2586
+		echo EEH_Template::display_template(
2587
+			EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2588
+			$this->_template_args,
2589
+			true
2590
+		);
2591
+	}
2592
+
2593
+
2594
+	/** end of globally available metaboxes section **/
2595
+
2596
+
2597
+
2598
+	/**
2599
+	 * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2600
+	 * protected method.
2601
+	 *
2602
+	 * @see   $this->_set_publish_post_box_vars for param details
2603
+	 * @since 4.6.0
2604
+	 * @param string $name
2605
+	 * @param int    $id
2606
+	 * @param bool   $delete
2607
+	 * @param string $save_close_redirect_URL
2608
+	 * @param bool   $both_btns
2609
+	 * @throws EE_Error
2610
+	 * @throws InvalidArgumentException
2611
+	 * @throws InvalidDataTypeException
2612
+	 * @throws InvalidInterfaceException
2613
+	 */
2614
+	public function set_publish_post_box_vars(
2615
+		$name = '',
2616
+		$id = 0,
2617
+		$delete = false,
2618
+		$save_close_redirect_URL = '',
2619
+		$both_btns = true
2620
+	) {
2621
+		$this->_set_publish_post_box_vars(
2622
+			$name,
2623
+			$id,
2624
+			$delete,
2625
+			$save_close_redirect_URL,
2626
+			$both_btns
2627
+		);
2628
+	}
2629
+
2630
+
2631
+
2632
+	/**
2633
+	 * Sets the _template_args arguments used by the _publish_post_box shortcut
2634
+	 * Note: currently there is no validation for this.  However if you want the delete button, the
2635
+	 * save, and save and close buttons to work properly, then you will want to include a
2636
+	 * values for the name and id arguments.
2637
+	 *
2638
+	 * @todo  Add in validation for name/id arguments.
2639
+	 * @param    string  $name                    key used for the action ID (i.e. event_id)
2640
+	 * @param    int     $id                      id attached to the item published
2641
+	 * @param    string  $delete                  page route callback for the delete action
2642
+	 * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2643
+	 * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2644
+	 *                                            the Save button
2645
+	 * @throws EE_Error
2646
+	 * @throws InvalidArgumentException
2647
+	 * @throws InvalidDataTypeException
2648
+	 * @throws InvalidInterfaceException
2649
+	 */
2650
+	protected function _set_publish_post_box_vars(
2651
+		$name = '',
2652
+		$id = 0,
2653
+		$delete = '',
2654
+		$save_close_redirect_URL = '',
2655
+		$both_btns = true
2656
+	) {
2657
+		// if Save & Close, use a custom redirect URL or default to the main page?
2658
+		$save_close_redirect_URL = ! empty($save_close_redirect_URL)
2659
+			? $save_close_redirect_URL
2660
+			: $this->_admin_base_url;
2661
+		// create the Save & Close and Save buttons
2662
+		$this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2663
+		//if we have extra content set let's add it in if not make sure its empty
2664
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2665
+			? $this->_template_args['publish_box_extra_content']
2666
+			: '';
2667
+		if ($delete && ! empty($id)) {
2668
+			//make sure we have a default if just true is sent.
2669
+			$delete           = ! empty($delete) ? $delete : 'delete';
2670
+			$delete_link_args = array($name => $id);
2671
+			$delete           = $this->get_action_link_or_button(
2672
+				$delete,
2673
+				$delete,
2674
+				$delete_link_args,
2675
+				'submitdelete deletion',
2676
+				'',
2677
+				false
2678
+			);
2679
+		}
2680
+		$this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2681
+		if (! empty($name) && ! empty($id)) {
2682
+			$hidden_field_arr[$name] = array(
2683
+				'type'  => 'hidden',
2684
+				'value' => $id,
2685
+			);
2686
+			$hf                      = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2687
+		} else {
2688
+			$hf = '';
2689
+		}
2690
+		// add hidden field
2691
+		$this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2692
+			? $hf[$name]['field']
2693
+			: $hf;
2694
+	}
2695
+
2696
+
2697
+
2698
+	/**
2699
+	 * displays an error message to ppl who have javascript disabled
2700
+	 *
2701
+	 * @return void
2702
+	 */
2703
+	private function _display_no_javascript_warning()
2704
+	{
2705
+		?>
2706 2706
         <noscript>
2707 2707
             <div id="no-js-message" class="error">
2708 2708
                 <p style="font-size:1.3em;">
2709 2709
                     <span style="color:red;"><?php esc_html_e('Warning!', 'event_espresso'); ?></span>
2710 2710
                     <?php esc_html_e(
2711
-                        'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2712
-                        'event_espresso'
2713
-                    ); ?>
2711
+						'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2712
+						'event_espresso'
2713
+					); ?>
2714 2714
                 </p>
2715 2715
             </div>
2716 2716
         </noscript>
2717 2717
         <?php
2718
-    }
2718
+	}
2719 2719
 
2720 2720
 
2721 2721
 
2722
-    /**
2723
-     * displays espresso success and/or error notices
2724
-     *
2725
-     * @return void
2726
-     */
2727
-    private function _display_espresso_notices()
2728
-    {
2729
-        $notices = $this->_get_transient(true);
2730
-        echo stripslashes($notices);
2731
-    }
2722
+	/**
2723
+	 * displays espresso success and/or error notices
2724
+	 *
2725
+	 * @return void
2726
+	 */
2727
+	private function _display_espresso_notices()
2728
+	{
2729
+		$notices = $this->_get_transient(true);
2730
+		echo stripslashes($notices);
2731
+	}
2732 2732
 
2733 2733
 
2734 2734
 
2735
-    /**
2736
-     * spinny things pacify the masses
2737
-     *
2738
-     * @return void
2739
-     */
2740
-    protected function _add_admin_page_ajax_loading_img()
2741
-    {
2742
-        ?>
2735
+	/**
2736
+	 * spinny things pacify the masses
2737
+	 *
2738
+	 * @return void
2739
+	 */
2740
+	protected function _add_admin_page_ajax_loading_img()
2741
+	{
2742
+		?>
2743 2743
         <div id="espresso-ajax-loading" class="ajax-loading-grey">
2744 2744
             <span class="ee-spinner ee-spin"></span><span class="hidden"><?php esc_html_e(
2745
-                    'loading...',
2746
-                    'event_espresso'
2747
-                ); ?></span>
2745
+					'loading...',
2746
+					'event_espresso'
2747
+				); ?></span>
2748 2748
         </div>
2749 2749
         <?php
2750
-    }
2750
+	}
2751 2751
 
2752 2752
 
2753 2753
 
2754
-    /**
2755
-     * add admin page overlay for modal boxes
2756
-     *
2757
-     * @return void
2758
-     */
2759
-    protected function _add_admin_page_overlay()
2760
-    {
2761
-        ?>
2754
+	/**
2755
+	 * add admin page overlay for modal boxes
2756
+	 *
2757
+	 * @return void
2758
+	 */
2759
+	protected function _add_admin_page_overlay()
2760
+	{
2761
+		?>
2762 2762
         <div id="espresso-admin-page-overlay-dv" class=""></div>
2763 2763
         <?php
2764
-    }
2765
-
2766
-
2767
-
2768
-    /**
2769
-     * facade for add_meta_box
2770
-     *
2771
-     * @param string  $action        where the metabox get's displayed
2772
-     * @param string  $title         Title of Metabox (output in metabox header)
2773
-     * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2774
-     *                               instead of the one created in here.
2775
-     * @param array   $callback_args an array of args supplied for the metabox
2776
-     * @param string  $column        what metabox column
2777
-     * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2778
-     * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2779
-     *                               created but just set our own callback for wp's add_meta_box.
2780
-     */
2781
-    public function _add_admin_page_meta_box(
2782
-        $action,
2783
-        $title,
2784
-        $callback,
2785
-        $callback_args,
2786
-        $column = 'normal',
2787
-        $priority = 'high',
2788
-        $create_func = true
2789
-    ) {
2790
-        do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2791
-        //if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2792
-        if (empty($callback_args) && $create_func) {
2793
-            $callback_args = array(
2794
-                'template_path' => $this->_template_path,
2795
-                'template_args' => $this->_template_args,
2796
-            );
2797
-        }
2798
-        //if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2799
-        $call_back_func = $create_func
2800
-            ? function ($post, $metabox)
2801
-            {
2802
-                do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2803
-                echo EEH_Template::display_template(
2804
-                    $metabox['args']['template_path'],
2805
-                    $metabox['args']['template_args'],
2806
-                    true
2807
-                );
2808
-            }
2809
-            : $callback;
2810
-        add_meta_box(
2811
-            str_replace('_', '-', $action) . '-mbox',
2812
-            $title,
2813
-            $call_back_func,
2814
-            $this->_wp_page_slug,
2815
-            $column,
2816
-            $priority,
2817
-            $callback_args
2818
-        );
2819
-    }
2820
-
2821
-
2822
-
2823
-    /**
2824
-     * generates HTML wrapper for and admin details page that contains metaboxes in columns
2825
-     *
2826
-     * @throws DomainException
2827
-     * @throws EE_Error
2828
-     */
2829
-    public function display_admin_page_with_metabox_columns()
2830
-    {
2831
-        $this->_template_args['post_body_content']  = $this->_template_args['admin_page_content'];
2832
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2833
-            $this->_column_template_path,
2834
-            $this->_template_args,
2835
-            true
2836
-        );
2837
-        //the final wrapper
2838
-        $this->admin_page_wrapper();
2839
-    }
2840
-
2841
-
2842
-
2843
-    /**
2844
-     * generates  HTML wrapper for an admin details page
2845
-     *
2846
-     * @return void
2847
-     * @throws EE_Error
2848
-     * @throws DomainException
2849
-     */
2850
-    public function display_admin_page_with_sidebar()
2851
-    {
2852
-        $this->_display_admin_page(true);
2853
-    }
2854
-
2855
-
2856
-
2857
-    /**
2858
-     * generates  HTML wrapper for an admin details page (except no sidebar)
2859
-     *
2860
-     * @return void
2861
-     * @throws EE_Error
2862
-     * @throws DomainException
2863
-     */
2864
-    public function display_admin_page_with_no_sidebar()
2865
-    {
2866
-        $this->_display_admin_page();
2867
-    }
2868
-
2869
-
2870
-
2871
-    /**
2872
-     * generates HTML wrapper for an EE about admin page (no sidebar)
2873
-     *
2874
-     * @return void
2875
-     * @throws EE_Error
2876
-     * @throws DomainException
2877
-     */
2878
-    public function display_about_admin_page()
2879
-    {
2880
-        $this->_display_admin_page(false, true);
2881
-    }
2882
-
2883
-
2884
-
2885
-    /**
2886
-     * display_admin_page
2887
-     * contains the code for actually displaying an admin page
2888
-     *
2889
-     * @param  boolean $sidebar true with sidebar, false without
2890
-     * @param  boolean $about   use the about admin wrapper instead of the default.
2891
-     * @return void
2892
-     * @throws DomainException
2893
-     * @throws EE_Error
2894
-     */
2895
-    private function _display_admin_page($sidebar = false, $about = false)
2896
-    {
2897
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2898
-        //custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2899
-        do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2900
-        // set current wp page slug - looks like: event-espresso_page_event_categories
2901
-        // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2902
-        $this->_template_args['current_page']              = $this->_wp_page_slug;
2903
-        $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2904
-            ? 'poststuff'
2905
-            : 'espresso-default-admin';
2906
-        $template_path                                     = $sidebar
2907
-            ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2908
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2909
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2910
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2911
-        }
2912
-        $template_path                                     = ! empty($this->_column_template_path)
2913
-            ? $this->_column_template_path : $template_path;
2914
-        $this->_template_args['post_body_content']         = isset($this->_template_args['admin_page_content'])
2915
-            ? $this->_template_args['admin_page_content']
2916
-            : '';
2917
-        $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2918
-            ? $this->_template_args['before_admin_page_content']
2919
-            : '';
2920
-        $this->_template_args['after_admin_page_content']  = isset($this->_template_args['after_admin_page_content'])
2921
-            ? $this->_template_args['after_admin_page_content']
2922
-            : '';
2923
-        $this->_template_args['admin_page_content']        = EEH_Template::display_template(
2924
-            $template_path,
2925
-            $this->_template_args,
2926
-            true
2927
-        );
2928
-        // the final template wrapper
2929
-        $this->admin_page_wrapper($about);
2930
-    }
2931
-
2932
-
2933
-
2934
-    /**
2935
-     * This is used to display caf preview pages.
2936
-     *
2937
-     * @since 4.3.2
2938
-     * @param string $utm_campaign_source what is the key used for google analytics link
2939
-     * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2940
-     *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2941
-     * @return void
2942
-     * @throws DomainException
2943
-     * @throws EE_Error
2944
-     * @throws InvalidArgumentException
2945
-     * @throws InvalidDataTypeException
2946
-     * @throws InvalidInterfaceException
2947
-     */
2948
-    public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2949
-    {
2950
-        //let's generate a default preview action button if there isn't one already present.
2951
-        $this->_labels['buttons']['buy_now']           = esc_html__(
2952
-            'Upgrade to Event Espresso 4 Right Now',
2953
-            'event_espresso'
2954
-        );
2955
-        $buy_now_url                                   = add_query_arg(
2956
-            array(
2957
-                'ee_ver'       => 'ee4',
2958
-                'utm_source'   => 'ee4_plugin_admin',
2959
-                'utm_medium'   => 'link',
2960
-                'utm_campaign' => $utm_campaign_source,
2961
-                'utm_content'  => 'buy_now_button',
2962
-            ),
2963
-            'http://eventespresso.com/pricing/'
2964
-        );
2965
-        $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2966
-            ? $this->get_action_link_or_button(
2967
-                '',
2968
-                'buy_now',
2969
-                array(),
2970
-                'button-primary button-large',
2971
-                $buy_now_url,
2972
-                true
2973
-            )
2974
-            : $this->_template_args['preview_action_button'];
2975
-        $this->_template_args['admin_page_content']    = EEH_Template::display_template(
2976
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2977
-            $this->_template_args,
2978
-            true
2979
-        );
2980
-        $this->_display_admin_page($display_sidebar);
2981
-    }
2982
-
2983
-
2984
-
2985
-    /**
2986
-     * display_admin_list_table_page_with_sidebar
2987
-     * generates HTML wrapper for an admin_page with list_table
2988
-     *
2989
-     * @return void
2990
-     * @throws EE_Error
2991
-     * @throws DomainException
2992
-     */
2993
-    public function display_admin_list_table_page_with_sidebar()
2994
-    {
2995
-        $this->_display_admin_list_table_page(true);
2996
-    }
2997
-
2998
-
2999
-
3000
-    /**
3001
-     * display_admin_list_table_page_with_no_sidebar
3002
-     * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
3003
-     *
3004
-     * @return void
3005
-     * @throws EE_Error
3006
-     * @throws DomainException
3007
-     */
3008
-    public function display_admin_list_table_page_with_no_sidebar()
3009
-    {
3010
-        $this->_display_admin_list_table_page();
3011
-    }
3012
-
3013
-
3014
-
3015
-    /**
3016
-     * generates html wrapper for an admin_list_table page
3017
-     *
3018
-     * @param boolean $sidebar whether to display with sidebar or not.
3019
-     * @return void
3020
-     * @throws DomainException
3021
-     * @throws EE_Error
3022
-     */
3023
-    private function _display_admin_list_table_page($sidebar = false)
3024
-    {
3025
-        //setup search attributes
3026
-        $this->_set_search_attributes();
3027
-        $this->_template_args['current_page']     = $this->_wp_page_slug;
3028
-        $template_path                            = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3029
-        $this->_template_args['table_url']        = defined('DOING_AJAX')
3030
-            ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3031
-            : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3032
-        $this->_template_args['list_table']       = $this->_list_table_object;
3033
-        $this->_template_args['current_route']    = $this->_req_action;
3034
-        $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3035
-        $ajax_sorting_callback                    = $this->_list_table_object->get_ajax_sorting_callback();
3036
-        if (! empty($ajax_sorting_callback)) {
3037
-            $sortable_list_table_form_fields = wp_nonce_field(
3038
-                $ajax_sorting_callback . '_nonce',
3039
-                $ajax_sorting_callback . '_nonce',
3040
-                false,
3041
-                false
3042
-            );
3043
-            //			$reorder_action = 'espresso_' . $ajax_sorting_callback . '_nonce';
3044
-            //			$sortable_list_table_form_fields = wp_nonce_field( $reorder_action, 'ajax_table_sort_nonce', FALSE, FALSE );
3045
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3046
-                                                . $this->page_slug
3047
-                                                . '" />';
3048
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3049
-                                                . $ajax_sorting_callback
3050
-                                                . '" />';
3051
-        } else {
3052
-            $sortable_list_table_form_fields = '';
3053
-        }
3054
-        $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3055
-        $hidden_form_fields                                      = isset($this->_template_args['list_table_hidden_fields'])
3056
-            ? $this->_template_args['list_table_hidden_fields']
3057
-            : '';
3058
-        $nonce_ref                                               = $this->_req_action . '_nonce';
3059
-        $hidden_form_fields                                      .= '<input type="hidden" name="'
3060
-                                                                    . $nonce_ref
3061
-                                                                    . '" value="'
3062
-                                                                    . wp_create_nonce($nonce_ref)
3063
-                                                                    . '">';
3064
-        $this->_template_args['list_table_hidden_fields']        = $hidden_form_fields;
3065
-        //display message about search results?
3066
-        $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3067
-            ? '<p class="ee-search-results">' . sprintf(
3068
-                esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3069
-                trim($this->_req_data['s'], '%')
3070
-            ) . '</p>'
3071
-            : '';
3072
-        // filter before_list_table template arg
3073
-        $this->_template_args['before_list_table'] = apply_filters(
3074
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3075
-            $this->_template_args['before_list_table'],
3076
-            $this->page_slug,
3077
-            $this->_req_data,
3078
-            $this->_req_action
3079
-        );
3080
-        // convert to array and filter again
3081
-        // arrays are easier to inject new items in a specific location,
3082
-        // but would not be backwards compatible, so we have to add a new filter
3083
-        $this->_template_args['before_list_table'] = implode(
3084
-            " \n",
3085
-            (array)apply_filters(
3086
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3087
-                (array)$this->_template_args['before_list_table'],
3088
-                $this->page_slug,
3089
-                $this->_req_data,
3090
-                $this->_req_action
3091
-            )
3092
-        );
3093
-        // filter after_list_table template arg
3094
-        $this->_template_args['after_list_table'] = apply_filters(
3095
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3096
-            $this->_template_args['after_list_table'],
3097
-            $this->page_slug,
3098
-            $this->_req_data,
3099
-            $this->_req_action
3100
-        );
3101
-        // convert to array and filter again
3102
-        // arrays are easier to inject new items in a specific location,
3103
-        // but would not be backwards compatible, so we have to add a new filter
3104
-        $this->_template_args['after_list_table']   = implode(
3105
-            " \n",
3106
-            (array)apply_filters(
3107
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3108
-                (array)$this->_template_args['after_list_table'],
3109
-                $this->page_slug,
3110
-                $this->_req_data,
3111
-                $this->_req_action
3112
-            )
3113
-        );
3114
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3115
-            $template_path,
3116
-            $this->_template_args,
3117
-            true
3118
-        );
3119
-        // the final template wrapper
3120
-        if ($sidebar) {
3121
-            $this->display_admin_page_with_sidebar();
3122
-        } else {
3123
-            $this->display_admin_page_with_no_sidebar();
3124
-        }
3125
-    }
3126
-
3127
-
3128
-
3129
-    /**
3130
-     * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3131
-     * html string for the legend.
3132
-     * $items are expected in an array in the following format:
3133
-     * $legend_items = array(
3134
-     *        'item_id' => array(
3135
-     *            'icon' => 'http://url_to_icon_being_described.png',
3136
-     *            'desc' => esc_html__('localized description of item');
3137
-     *        )
3138
-     * );
3139
-     *
3140
-     * @param  array $items see above for format of array
3141
-     * @return string html string of legend
3142
-     * @throws DomainException
3143
-     */
3144
-    protected function _display_legend($items)
3145
-    {
3146
-        $this->_template_args['items'] = apply_filters(
3147
-            'FHEE__EE_Admin_Page___display_legend__items',
3148
-            (array)$items,
3149
-            $this
3150
-        );
3151
-        return EEH_Template::display_template(
3152
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3153
-            $this->_template_args,
3154
-            true
3155
-        );
3156
-    }
3157
-
3158
-
3159
-    /**
3160
-     * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3161
-     * The returned json object is created from an array in the following format:
3162
-     * array(
3163
-     *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3164
-     *  'success' => FALSE, //(default FALSE) - contains any special success message.
3165
-     *  'notices' => '', // - contains any EE_Error formatted notices
3166
-     *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3167
-     *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3168
-     *  We're also going to include the template args with every package (so js can pick out any specific template args
3169
-     *  that might be included in here)
3170
-     * )
3171
-     * The json object is populated by whatever is set in the $_template_args property.
3172
-     *
3173
-     * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3174
-     *                                 instead of displayed.
3175
-     * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3176
-     * @return void
3177
-     * @throws EE_Error
3178
-     */
3179
-    protected function _return_json($sticky_notices = false, $notices_arguments = array())
3180
-    {
3181
-        //make sure any EE_Error notices have been handled.
3182
-        $this->_process_notices($notices_arguments, true, $sticky_notices);
3183
-        $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3184
-        unset($this->_template_args['data']);
3185
-        $json = array(
3186
-            'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3187
-            'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3188
-            'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3189
-            'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3190
-            'notices'   => EE_Error::get_notices(),
3191
-            'content'   => isset($this->_template_args['admin_page_content'])
3192
-                ? $this->_template_args['admin_page_content'] : '',
3193
-            'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3194
-            'isEEajax'  => true
3195
-            //special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3196
-        );
3197
-        // make sure there are no php errors or headers_sent.  Then we can set correct json header.
3198
-        if (null === error_get_last() || ! headers_sent()) {
3199
-            header('Content-Type: application/json; charset=UTF-8');
3200
-        }
3201
-        echo wp_json_encode($json);
3202
-        exit();
3203
-    }
3204
-
3205
-
3206
-
3207
-    /**
3208
-     * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3209
-     *
3210
-     * @return void
3211
-     * @throws EE_Error
3212
-     */
3213
-    public function return_json()
3214
-    {
3215
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3216
-            $this->_return_json();
3217
-        } else {
3218
-            throw new EE_Error(
3219
-                sprintf(
3220
-                    esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3221
-                    __FUNCTION__
3222
-                )
3223
-            );
3224
-        }
3225
-    }
3226
-
3227
-
3228
-
3229
-    /**
3230
-     * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3231
-     * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3232
-     *
3233
-     * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3234
-     */
3235
-    public function set_hook_object(EE_Admin_Hooks $hook_obj)
3236
-    {
3237
-        $this->_hook_obj = $hook_obj;
3238
-    }
3239
-
3240
-
3241
-
3242
-    /**
3243
-     *        generates  HTML wrapper with Tabbed nav for an admin page
3244
-     *
3245
-     * @param  boolean $about whether to use the special about page wrapper or default.
3246
-     * @return void
3247
-     * @throws DomainException
3248
-     * @throws EE_Error
3249
-     */
3250
-    public function admin_page_wrapper($about = false)
3251
-    {
3252
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3253
-        $this->_nav_tabs                                   = $this->_get_main_nav_tabs();
3254
-        $this->_template_args['nav_tabs']                  = $this->_nav_tabs;
3255
-        $this->_template_args['admin_page_title']          = $this->_admin_page_title;
3256
-        $this->_template_args['before_admin_page_content'] = apply_filters(
3257
-            "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3258
-            isset($this->_template_args['before_admin_page_content'])
3259
-                ? $this->_template_args['before_admin_page_content']
3260
-                : ''
3261
-        );
3262
-        $this->_template_args['after_admin_page_content']  = apply_filters(
3263
-            "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3264
-            isset($this->_template_args['after_admin_page_content'])
3265
-                ? $this->_template_args['after_admin_page_content']
3266
-                : ''
3267
-        );
3268
-        $this->_template_args['after_admin_page_content']  .= $this->_set_help_popup_content();
3269
-        // load settings page wrapper template
3270
-        $template_path = ! defined('DOING_AJAX')
3271
-            ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3272
-            : EE_ADMIN_TEMPLATE
3273
-              . 'admin_wrapper_ajax.template.php';
3274
-        //about page?
3275
-        $template_path = $about
3276
-            ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3277
-            : $template_path;
3278
-        if (defined('DOING_AJAX')) {
3279
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3280
-                $template_path,
3281
-                $this->_template_args,
3282
-                true
3283
-            );
3284
-            $this->_return_json();
3285
-        } else {
3286
-            EEH_Template::display_template($template_path, $this->_template_args);
3287
-        }
3288
-    }
3289
-
3290
-
3291
-
3292
-    /**
3293
-     * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3294
-     *
3295
-     * @return string html
3296
-     * @throws EE_Error
3297
-     */
3298
-    protected function _get_main_nav_tabs()
3299
-    {
3300
-        // let's generate the html using the EEH_Tabbed_Content helper.
3301
-        // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3302
-        // (rather than setting in the page_routes array)
3303
-        return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3304
-    }
3305
-
3306
-
3307
-
3308
-    /**
3309
-     *        sort nav tabs
3310
-     *
3311
-     * @param $a
3312
-     * @param $b
3313
-     * @return int
3314
-     */
3315
-    private function _sort_nav_tabs($a, $b)
3316
-    {
3317
-        if ($a['order'] === $b['order']) {
3318
-            return 0;
3319
-        }
3320
-        return ($a['order'] < $b['order']) ? -1 : 1;
3321
-    }
3322
-
3323
-
3324
-
3325
-    /**
3326
-     *    generates HTML for the forms used on admin pages
3327
-     *
3328
-     * @param    array $input_vars - array of input field details
3329
-     * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3330
-     *                             use)
3331
-     * @param bool     $id
3332
-     * @return string
3333
-     * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3334
-     * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3335
-     */
3336
-    protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3337
-    {
3338
-        $content = $generator === 'string'
3339
-            ? EEH_Form_Fields::get_form_fields($input_vars, $id)
3340
-            : EEH_Form_Fields::get_form_fields_array($input_vars);
3341
-        return $content;
3342
-    }
3343
-
3344
-
3345
-
3346
-    /**
3347
-     * generates the "Save" and "Save & Close" buttons for edit forms
3348
-     *
3349
-     * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3350
-     *                                   Close" button.
3351
-     * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3352
-     *                                   'Save', [1] => 'save & close')
3353
-     * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3354
-     *                                   via the "name" value in the button).  We can also use this to just dump
3355
-     *                                   default actions by submitting some other value.
3356
-     * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3357
-     *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3358
-     *                                   close (normal form handling).
3359
-     */
3360
-    protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3361
-    {
3362
-        //make sure $text and $actions are in an array
3363
-        $text          = (array)$text;
3364
-        $actions       = (array)$actions;
3365
-        $referrer_url  = empty($referrer)
3366
-            ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3367
-              . $_SERVER['REQUEST_URI']
3368
-              . '" />'
3369
-            : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3370
-              . $referrer
3371
-              . '" />';
3372
-        $button_text   = ! empty($text)
3373
-            ? $text
3374
-            : array(
3375
-                esc_html__('Save', 'event_espresso'),
3376
-                esc_html__('Save and Close', 'event_espresso'),
3377
-            );
3378
-        $default_names = array('save', 'save_and_close');
3379
-        //add in a hidden index for the current page (so save and close redirects properly)
3380
-        $this->_template_args['save_buttons'] = $referrer_url;
3381
-        foreach ($button_text as $key => $button) {
3382
-            $ref                                  = $default_names[$key];
3383
-            $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3384
-                                                     . $ref
3385
-                                                     . '" value="'
3386
-                                                     . $button
3387
-                                                     . '" name="'
3388
-                                                     . (! empty($actions) ? $actions[$key] : $ref)
3389
-                                                     . '" id="'
3390
-                                                     . $this->_current_view . '_' . $ref
3391
-                                                     . '" />';
3392
-            if (! $both) {
3393
-                break;
3394
-            }
3395
-        }
3396
-    }
3397
-
3398
-
3399
-
3400
-    /**
3401
-     * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3402
-     *
3403
-     * @see   $this->_set_add_edit_form_tags() for details on params
3404
-     * @since 4.6.0
3405
-     * @param string $route
3406
-     * @param array  $additional_hidden_fields
3407
-     */
3408
-    public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3409
-    {
3410
-        $this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3411
-    }
3412
-
3413
-
3414
-
3415
-    /**
3416
-     * set form open and close tags on add/edit pages.
3417
-     *
3418
-     * @param string $route                    the route you want the form to direct to
3419
-     * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3420
-     * @return void
3421
-     */
3422
-    protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3423
-    {
3424
-        if (empty($route)) {
3425
-            $user_msg = esc_html__(
3426
-                'An error occurred. No action was set for this page\'s form.',
3427
-                'event_espresso'
3428
-            );
3429
-            $dev_msg  = $user_msg . "\n" . sprintf(
3430
-                    esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3431
-                    __FUNCTION__,
3432
-                    __CLASS__
3433
-                );
3434
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3435
-        }
3436
-        // open form
3437
-        $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3438
-                                                             . $this->_admin_base_url
3439
-                                                             . '" id="'
3440
-                                                             . $route
3441
-                                                             . '_event_form" >';
3442
-        // add nonce
3443
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3444
-        //		$nonce = wp_nonce_field( $route . '_nonce', '_wpnonce', FALSE, FALSE );
3445
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3446
-        // add REQUIRED form action
3447
-        $hidden_fields = array(
3448
-            'action' => array('type' => 'hidden', 'value' => $route),
3449
-        );
3450
-        // merge arrays
3451
-        $hidden_fields = is_array($additional_hidden_fields)
3452
-            ? array_merge($hidden_fields, $additional_hidden_fields)
3453
-            : $hidden_fields;
3454
-        // generate form fields
3455
-        $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456
-        // add fields to form
3457
-        foreach ((array)$form_fields as $field_name => $form_field) {
3458
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3459
-        }
3460
-        // close form
3461
-        $this->_template_args['after_admin_page_content'] = '</form>';
3462
-    }
3463
-
3464
-
3465
-
3466
-    /**
3467
-     * Public Wrapper for _redirect_after_action() method since its
3468
-     * discovered it would be useful for external code to have access.
3469
-     *
3470
-     * @see   EE_Admin_Page::_redirect_after_action() for params.
3471
-     * @since 4.5.0
3472
-     * @param bool   $success
3473
-     * @param string $what
3474
-     * @param string $action_desc
3475
-     * @param array  $query_args
3476
-     * @param bool   $override_overwrite
3477
-     * @throws EE_Error
3478
-     */
3479
-    public function redirect_after_action(
3480
-        $success = false,
3481
-        $what = 'item',
3482
-        $action_desc = 'processed',
3483
-        $query_args = array(),
3484
-        $override_overwrite = false
3485
-    ) {
3486
-        $this->_redirect_after_action(
3487
-            $success,
3488
-            $what,
3489
-            $action_desc,
3490
-            $query_args,
3491
-            $override_overwrite
3492
-        );
3493
-    }
3494
-
3495
-
3496
-
3497
-    /**
3498
-     *    _redirect_after_action
3499
-     *
3500
-     * @param int    $success            - whether success was for two or more records, or just one, or none
3501
-     * @param string $what               - what the action was performed on
3502
-     * @param string $action_desc        - what was done ie: updated, deleted, etc
3503
-     * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3504
-     *                                   action is completed
3505
-     * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3506
-     *                                   override this so that they show.
3507
-     * @return void
3508
-     * @throws EE_Error
3509
-     */
3510
-    protected function _redirect_after_action(
3511
-        $success = 0,
3512
-        $what = 'item',
3513
-        $action_desc = 'processed',
3514
-        $query_args = array(),
3515
-        $override_overwrite = false
3516
-    ) {
3517
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3518
-        //class name for actions/filters.
3519
-        $classname = get_class($this);
3520
-        // set redirect url.
3521
-        // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3522
-        // otherwise we go with whatever is set as the _admin_base_url
3523
-        $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3524
-        $notices      = EE_Error::get_notices(false);
3525
-        // overwrite default success messages //BUT ONLY if overwrite not overridden
3526
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3527
-            EE_Error::overwrite_success();
3528
-        }
3529
-        if (! empty($what) && ! empty($action_desc)  && empty($notices['errors'])) {
3530
-            // how many records affected ? more than one record ? or just one ?
3531
-            if ($success > 1) {
3532
-                // set plural msg
3533
-                EE_Error::add_success(
3534
-                    sprintf(
3535
-                        esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3536
-                        $what,
3537
-                        $action_desc
3538
-                    ),
3539
-                    __FILE__,
3540
-                    __FUNCTION__,
3541
-                    __LINE__
3542
-                );
3543
-            } elseif ($success === 1) {
3544
-                // set singular msg
3545
-                EE_Error::add_success(
3546
-                    sprintf(
3547
-                        esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3548
-                        $what,
3549
-                        $action_desc
3550
-                    ),
3551
-                    __FILE__,
3552
-                    __FUNCTION__,
3553
-                    __LINE__
3554
-                );
3555
-            }
3556
-        }
3557
-        // check that $query_args isn't something crazy
3558
-        if (! is_array($query_args)) {
3559
-            $query_args = array();
3560
-        }
3561
-        /**
3562
-         * Allow injecting actions before the query_args are modified for possible different
3563
-         * redirections on save and close actions
3564
-         *
3565
-         * @since 4.2.0
3566
-         * @param array $query_args       The original query_args array coming into the
3567
-         *                                method.
3568
-         */
3569
-        do_action(
3570
-            "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3571
-            $query_args
3572
-        );
3573
-        //calculate where we're going (if we have a "save and close" button pushed)
3574
-        if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3575
-            // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3576
-            $parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3577
-            // regenerate query args array from referrer URL
3578
-            parse_str($parsed_url['query'], $query_args);
3579
-            // correct page and action will be in the query args now
3580
-            $redirect_url = admin_url('admin.php');
3581
-        }
3582
-        //merge any default query_args set in _default_route_query_args property
3583
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3584
-            $args_to_merge = array();
3585
-            foreach ($this->_default_route_query_args as $query_param => $query_value) {
3586
-                //is there a wp_referer array in our _default_route_query_args property?
3587
-                if ($query_param === 'wp_referer') {
3588
-                    $query_value = (array)$query_value;
3589
-                    foreach ($query_value as $reference => $value) {
3590
-                        if (strpos($reference, 'nonce') !== false) {
3591
-                            continue;
3592
-                        }
3593
-                        //finally we will override any arguments in the referer with
3594
-                        //what might be set on the _default_route_query_args array.
3595
-                        if (isset($this->_default_route_query_args[$reference])) {
3596
-                            $args_to_merge[$reference] = urlencode($this->_default_route_query_args[$reference]);
3597
-                        } else {
3598
-                            $args_to_merge[$reference] = urlencode($value);
3599
-                        }
3600
-                    }
3601
-                    continue;
3602
-                }
3603
-                $args_to_merge[$query_param] = $query_value;
3604
-            }
3605
-            //now let's merge these arguments but override with what was specifically sent in to the
3606
-            //redirect.
3607
-            $query_args = array_merge($args_to_merge, $query_args);
3608
-        }
3609
-        $this->_process_notices($query_args);
3610
-        // generate redirect url
3611
-        // if redirecting to anything other than the main page, add a nonce
3612
-        if (isset($query_args['action'])) {
3613
-            // manually generate wp_nonce and merge that with the query vars
3614
-            // becuz the wp_nonce_url function wrecks havoc on some vars
3615
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3616
-        }
3617
-        // we're adding some hooks and filters in here for processing any things just before redirects
3618
-        // (example: an admin page has done an insert or update and we want to run something after that).
3619
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3620
-        $redirect_url = apply_filters(
3621
-            'FHEE_redirect_' . $classname . $this->_req_action,
3622
-            self::add_query_args_and_nonce($query_args, $redirect_url),
3623
-            $query_args
3624
-        );
3625
-        // check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3626
-        if (defined('DOING_AJAX')) {
3627
-            $default_data                    = array(
3628
-                'close'        => true,
3629
-                'redirect_url' => $redirect_url,
3630
-                'where'        => 'main',
3631
-                'what'         => 'append',
3632
-            );
3633
-            $this->_template_args['success'] = $success;
3634
-            $this->_template_args['data']    = ! empty($this->_template_args['data']) ? array_merge(
3635
-                $default_data,
3636
-                $this->_template_args['data']
3637
-            ) : $default_data;
3638
-            $this->_return_json();
3639
-        }
3640
-        wp_safe_redirect($redirect_url);
3641
-        exit();
3642
-    }
3643
-
3644
-
3645
-
3646
-    /**
3647
-     * process any notices before redirecting (or returning ajax request)
3648
-     * This method sets the $this->_template_args['notices'] attribute;
3649
-     *
3650
-     * @param  array $query_args        any query args that need to be used for notice transient ('action')
3651
-     * @param bool   $skip_route_verify This is typically used when we are processing notices REALLY early and
3652
-     *                                  page_routes haven't been defined yet.
3653
-     * @param bool   $sticky_notices    This is used to flag that regardless of whether this is doing_ajax or not, we
3654
-     *                                  still save a transient for the notice.
3655
-     * @return void
3656
-     * @throws EE_Error
3657
-     */
3658
-    protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3659
-    {
3660
-        //first let's set individual error properties if doing_ajax and the properties aren't already set.
3661
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3662
-            $notices = EE_Error::get_notices(false);
3663
-            if (empty($this->_template_args['success'])) {
3664
-                $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3665
-            }
3666
-            if (empty($this->_template_args['errors'])) {
3667
-                $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3668
-            }
3669
-            if (empty($this->_template_args['attention'])) {
3670
-                $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3671
-            }
3672
-        }
3673
-        $this->_template_args['notices'] = EE_Error::get_notices();
3674
-        //IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3675
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3676
-            $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3677
-            $this->_add_transient(
3678
-                $route,
3679
-                $this->_template_args['notices'],
3680
-                true,
3681
-                $skip_route_verify
3682
-            );
3683
-        }
3684
-    }
3685
-
3686
-
3687
-
3688
-    /**
3689
-     * get_action_link_or_button
3690
-     * returns the button html for adding, editing, or deleting an item (depending on given type)
3691
-     *
3692
-     * @param string $action        use this to indicate which action the url is generated with.
3693
-     * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3694
-     *                              property.
3695
-     * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3696
-     * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3697
-     * @param string $base_url      If this is not provided
3698
-     *                              the _admin_base_url will be used as the default for the button base_url.
3699
-     *                              Otherwise this value will be used.
3700
-     * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3701
-     * @return string
3702
-     * @throws InvalidArgumentException
3703
-     * @throws InvalidInterfaceException
3704
-     * @throws InvalidDataTypeException
3705
-     * @throws EE_Error
3706
-     */
3707
-    public function get_action_link_or_button(
3708
-        $action,
3709
-        $type = 'add',
3710
-        $extra_request = array(),
3711
-        $class = 'button-primary',
3712
-        $base_url = '',
3713
-        $exclude_nonce = false
3714
-    ) {
3715
-        //first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3716
-        if (empty($base_url) && ! isset($this->_page_routes[$action])) {
3717
-            throw new EE_Error(
3718
-                sprintf(
3719
-                    esc_html__(
3720
-                        'There is no page route for given action for the button.  This action was given: %s',
3721
-                        'event_espresso'
3722
-                    ),
3723
-                    $action
3724
-                )
3725
-            );
3726
-        }
3727
-        if (! isset($this->_labels['buttons'][$type])) {
3728
-            throw new EE_Error(
3729
-                sprintf(
3730
-                    __(
3731
-                        'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3732
-                        'event_espresso'
3733
-                    ),
3734
-                    $type
3735
-                )
3736
-            );
3737
-        }
3738
-        //finally check user access for this button.
3739
-        $has_access = $this->check_user_access($action, true);
3740
-        if (! $has_access) {
3741
-            return '';
3742
-        }
3743
-        $_base_url  = ! $base_url ? $this->_admin_base_url : $base_url;
3744
-        $query_args = array(
3745
-            'action' => $action,
3746
-        );
3747
-        //merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3748
-        if (! empty($extra_request)) {
3749
-            $query_args = array_merge($extra_request, $query_args);
3750
-        }
3751
-        $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3752
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][$type], $class);
3753
-    }
3754
-
3755
-
3756
-
3757
-    /**
3758
-     * _per_page_screen_option
3759
-     * Utility function for adding in a per_page_option in the screen_options_dropdown.
3760
-     *
3761
-     * @return void
3762
-     * @throws InvalidArgumentException
3763
-     * @throws InvalidInterfaceException
3764
-     * @throws InvalidDataTypeException
3765
-     */
3766
-    protected function _per_page_screen_option()
3767
-    {
3768
-        $option = 'per_page';
3769
-        $args   = array(
3770
-            'label'   => $this->_admin_page_title,
3771
-            'default' => 10,
3772
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3773
-        );
3774
-        //ONLY add the screen option if the user has access to it.
3775
-        if ($this->check_user_access($this->_current_view, true)) {
3776
-            add_screen_option($option, $args);
3777
-        }
3778
-    }
3779
-
3780
-
3781
-
3782
-    /**
3783
-     * set_per_page_screen_option
3784
-     * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3785
-     * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3786
-     * admin_menu.
3787
-     *
3788
-     * @return void
3789
-     */
3790
-    private function _set_per_page_screen_options()
3791
-    {
3792
-        if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3793
-            check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3794
-            if (! $user = wp_get_current_user()) {
3795
-                return;
3796
-            }
3797
-            $option = $_POST['wp_screen_options']['option'];
3798
-            $value  = $_POST['wp_screen_options']['value'];
3799
-            if ($option != sanitize_key($option)) {
3800
-                return;
3801
-            }
3802
-            $map_option = $option;
3803
-            $option     = str_replace('-', '_', $option);
3804
-            switch ($map_option) {
3805
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3806
-                    $value = (int)$value;
3807
-                    if ($value < 1 || $value > 999) {
3808
-                        return;
3809
-                    }
3810
-                    break;
3811
-                default:
3812
-                    $value = apply_filters(
3813
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3814
-                        false,
3815
-                        $option,
3816
-                        $value
3817
-                    );
3818
-                    if (false === $value) {
3819
-                        return;
3820
-                    }
3821
-                    break;
3822
-            }
3823
-            update_user_meta($user->ID, $option, $value);
3824
-            wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3825
-            exit;
3826
-        }
3827
-    }
3828
-
3829
-
3830
-
3831
-    /**
3832
-     * This just allows for setting the $_template_args property if it needs to be set outside the object
3833
-     *
3834
-     * @param array $data array that will be assigned to template args.
3835
-     */
3836
-    public function set_template_args($data)
3837
-    {
3838
-        $this->_template_args = array_merge($this->_template_args, (array)$data);
3839
-    }
3840
-
3841
-
3842
-
3843
-    /**
3844
-     * This makes available the WP transient system for temporarily moving data between routes
3845
-     *
3846
-     * @param string $route             the route that should receive the transient
3847
-     * @param array  $data              the data that gets sent
3848
-     * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3849
-     *                                  normal route transient.
3850
-     * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3851
-     *                                  when we are adding a transient before page_routes have been defined.
3852
-     * @return void
3853
-     * @throws EE_Error
3854
-     */
3855
-    protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3856
-    {
3857
-        $user_id = get_current_user_id();
3858
-        if (! $skip_route_verify) {
3859
-            $this->_verify_route($route);
3860
-        }
3861
-        //now let's set the string for what kind of transient we're setting
3862
-        $transient = $notices
3863
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3864
-            : 'rte_tx_' . $route . '_' . $user_id;
3865
-        $data      = $notices ? array('notices' => $data) : $data;
3866
-        //is there already a transient for this route?  If there is then let's ADD to that transient
3867
-        $existing = is_multisite() && is_network_admin()
3868
-            ? get_site_transient($transient)
3869
-            : get_transient($transient);
3870
-        if ($existing) {
3871
-            $data = array_merge((array)$data, (array)$existing);
3872
-        }
3873
-        if (is_multisite() && is_network_admin()) {
3874
-            set_site_transient($transient, $data, 8);
3875
-        } else {
3876
-            set_transient($transient, $data, 8);
3877
-        }
3878
-    }
3879
-
3880
-
3881
-
3882
-    /**
3883
-     * this retrieves the temporary transient that has been set for moving data between routes.
3884
-     *
3885
-     * @param bool   $notices true we get notices transient. False we just return normal route transient
3886
-     * @param string $route
3887
-     * @return mixed data
3888
-     */
3889
-    protected function _get_transient($notices = false, $route = '')
3890
-    {
3891
-        $user_id   = get_current_user_id();
3892
-        $route     = ! $route ? $this->_req_action : $route;
3893
-        $transient = $notices
3894
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3895
-            : 'rte_tx_' . $route . '_' . $user_id;
3896
-        $data      = is_multisite() && is_network_admin()
3897
-            ? get_site_transient($transient)
3898
-            : get_transient($transient);
3899
-        //delete transient after retrieval (just in case it hasn't expired);
3900
-        if (is_multisite() && is_network_admin()) {
3901
-            delete_site_transient($transient);
3902
-        } else {
3903
-            delete_transient($transient);
3904
-        }
3905
-        return $notices && isset($data['notices']) ? $data['notices'] : $data;
3906
-    }
3907
-
3908
-
3909
-
3910
-    /**
3911
-     * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3912
-     * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3913
-     * default route callback on the EE_Admin page you want it run.)
3914
-     *
3915
-     * @return void
3916
-     */
3917
-    protected function _transient_garbage_collection()
3918
-    {
3919
-        global $wpdb;
3920
-        //retrieve all existing transients
3921
-        $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3922
-        if ($results = $wpdb->get_results($query)) {
3923
-            foreach ($results as $result) {
3924
-                $transient = str_replace('_transient_', '', $result->option_name);
3925
-                get_transient($transient);
3926
-                if (is_multisite() && is_network_admin()) {
3927
-                    get_site_transient($transient);
3928
-                }
3929
-            }
3930
-        }
3931
-    }
3932
-
3933
-
3934
-
3935
-    /**
3936
-     * get_view
3937
-     *
3938
-     * @return string content of _view property
3939
-     */
3940
-    public function get_view()
3941
-    {
3942
-        return $this->_view;
3943
-    }
3944
-
3945
-
3946
-
3947
-    /**
3948
-     * getter for the protected $_views property
3949
-     *
3950
-     * @return array
3951
-     */
3952
-    public function get_views()
3953
-    {
3954
-        return $this->_views;
3955
-    }
3956
-
3957
-
3958
-
3959
-    /**
3960
-     * get_current_page
3961
-     *
3962
-     * @return string _current_page property value
3963
-     */
3964
-    public function get_current_page()
3965
-    {
3966
-        return $this->_current_page;
3967
-    }
3968
-
3969
-
3970
-
3971
-    /**
3972
-     * get_current_view
3973
-     *
3974
-     * @return string _current_view property value
3975
-     */
3976
-    public function get_current_view()
3977
-    {
3978
-        return $this->_current_view;
3979
-    }
3980
-
3981
-
3982
-
3983
-    /**
3984
-     * get_current_screen
3985
-     *
3986
-     * @return object The current WP_Screen object
3987
-     */
3988
-    public function get_current_screen()
3989
-    {
3990
-        return $this->_current_screen;
3991
-    }
3992
-
3993
-
3994
-
3995
-    /**
3996
-     * get_current_page_view_url
3997
-     *
3998
-     * @return string This returns the url for the current_page_view.
3999
-     */
4000
-    public function get_current_page_view_url()
4001
-    {
4002
-        return $this->_current_page_view_url;
4003
-    }
4004
-
4005
-
4006
-
4007
-    /**
4008
-     * just returns the _req_data property
4009
-     *
4010
-     * @return array
4011
-     */
4012
-    public function get_request_data()
4013
-    {
4014
-        return $this->_req_data;
4015
-    }
4016
-
4017
-
4018
-
4019
-    /**
4020
-     * returns the _req_data protected property
4021
-     *
4022
-     * @return string
4023
-     */
4024
-    public function get_req_action()
4025
-    {
4026
-        return $this->_req_action;
4027
-    }
4028
-
4029
-
4030
-
4031
-    /**
4032
-     * @return bool  value of $_is_caf property
4033
-     */
4034
-    public function is_caf()
4035
-    {
4036
-        return $this->_is_caf;
4037
-    }
4038
-
4039
-
4040
-
4041
-    /**
4042
-     * @return mixed
4043
-     */
4044
-    public function default_espresso_metaboxes()
4045
-    {
4046
-        return $this->_default_espresso_metaboxes;
4047
-    }
4048
-
4049
-
4050
-
4051
-    /**
4052
-     * @return mixed
4053
-     */
4054
-    public function admin_base_url()
4055
-    {
4056
-        return $this->_admin_base_url;
4057
-    }
2764
+	}
2765
+
2766
+
2767
+
2768
+	/**
2769
+	 * facade for add_meta_box
2770
+	 *
2771
+	 * @param string  $action        where the metabox get's displayed
2772
+	 * @param string  $title         Title of Metabox (output in metabox header)
2773
+	 * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2774
+	 *                               instead of the one created in here.
2775
+	 * @param array   $callback_args an array of args supplied for the metabox
2776
+	 * @param string  $column        what metabox column
2777
+	 * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2778
+	 * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2779
+	 *                               created but just set our own callback for wp's add_meta_box.
2780
+	 */
2781
+	public function _add_admin_page_meta_box(
2782
+		$action,
2783
+		$title,
2784
+		$callback,
2785
+		$callback_args,
2786
+		$column = 'normal',
2787
+		$priority = 'high',
2788
+		$create_func = true
2789
+	) {
2790
+		do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2791
+		//if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2792
+		if (empty($callback_args) && $create_func) {
2793
+			$callback_args = array(
2794
+				'template_path' => $this->_template_path,
2795
+				'template_args' => $this->_template_args,
2796
+			);
2797
+		}
2798
+		//if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2799
+		$call_back_func = $create_func
2800
+			? function ($post, $metabox)
2801
+			{
2802
+				do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2803
+				echo EEH_Template::display_template(
2804
+					$metabox['args']['template_path'],
2805
+					$metabox['args']['template_args'],
2806
+					true
2807
+				);
2808
+			}
2809
+			: $callback;
2810
+		add_meta_box(
2811
+			str_replace('_', '-', $action) . '-mbox',
2812
+			$title,
2813
+			$call_back_func,
2814
+			$this->_wp_page_slug,
2815
+			$column,
2816
+			$priority,
2817
+			$callback_args
2818
+		);
2819
+	}
2820
+
2821
+
2822
+
2823
+	/**
2824
+	 * generates HTML wrapper for and admin details page that contains metaboxes in columns
2825
+	 *
2826
+	 * @throws DomainException
2827
+	 * @throws EE_Error
2828
+	 */
2829
+	public function display_admin_page_with_metabox_columns()
2830
+	{
2831
+		$this->_template_args['post_body_content']  = $this->_template_args['admin_page_content'];
2832
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2833
+			$this->_column_template_path,
2834
+			$this->_template_args,
2835
+			true
2836
+		);
2837
+		//the final wrapper
2838
+		$this->admin_page_wrapper();
2839
+	}
2840
+
2841
+
2842
+
2843
+	/**
2844
+	 * generates  HTML wrapper for an admin details page
2845
+	 *
2846
+	 * @return void
2847
+	 * @throws EE_Error
2848
+	 * @throws DomainException
2849
+	 */
2850
+	public function display_admin_page_with_sidebar()
2851
+	{
2852
+		$this->_display_admin_page(true);
2853
+	}
2854
+
2855
+
2856
+
2857
+	/**
2858
+	 * generates  HTML wrapper for an admin details page (except no sidebar)
2859
+	 *
2860
+	 * @return void
2861
+	 * @throws EE_Error
2862
+	 * @throws DomainException
2863
+	 */
2864
+	public function display_admin_page_with_no_sidebar()
2865
+	{
2866
+		$this->_display_admin_page();
2867
+	}
2868
+
2869
+
2870
+
2871
+	/**
2872
+	 * generates HTML wrapper for an EE about admin page (no sidebar)
2873
+	 *
2874
+	 * @return void
2875
+	 * @throws EE_Error
2876
+	 * @throws DomainException
2877
+	 */
2878
+	public function display_about_admin_page()
2879
+	{
2880
+		$this->_display_admin_page(false, true);
2881
+	}
2882
+
2883
+
2884
+
2885
+	/**
2886
+	 * display_admin_page
2887
+	 * contains the code for actually displaying an admin page
2888
+	 *
2889
+	 * @param  boolean $sidebar true with sidebar, false without
2890
+	 * @param  boolean $about   use the about admin wrapper instead of the default.
2891
+	 * @return void
2892
+	 * @throws DomainException
2893
+	 * @throws EE_Error
2894
+	 */
2895
+	private function _display_admin_page($sidebar = false, $about = false)
2896
+	{
2897
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2898
+		//custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2899
+		do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2900
+		// set current wp page slug - looks like: event-espresso_page_event_categories
2901
+		// keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2902
+		$this->_template_args['current_page']              = $this->_wp_page_slug;
2903
+		$this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2904
+			? 'poststuff'
2905
+			: 'espresso-default-admin';
2906
+		$template_path                                     = $sidebar
2907
+			? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2908
+			: EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2909
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2910
+			$template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2911
+		}
2912
+		$template_path                                     = ! empty($this->_column_template_path)
2913
+			? $this->_column_template_path : $template_path;
2914
+		$this->_template_args['post_body_content']         = isset($this->_template_args['admin_page_content'])
2915
+			? $this->_template_args['admin_page_content']
2916
+			: '';
2917
+		$this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2918
+			? $this->_template_args['before_admin_page_content']
2919
+			: '';
2920
+		$this->_template_args['after_admin_page_content']  = isset($this->_template_args['after_admin_page_content'])
2921
+			? $this->_template_args['after_admin_page_content']
2922
+			: '';
2923
+		$this->_template_args['admin_page_content']        = EEH_Template::display_template(
2924
+			$template_path,
2925
+			$this->_template_args,
2926
+			true
2927
+		);
2928
+		// the final template wrapper
2929
+		$this->admin_page_wrapper($about);
2930
+	}
2931
+
2932
+
2933
+
2934
+	/**
2935
+	 * This is used to display caf preview pages.
2936
+	 *
2937
+	 * @since 4.3.2
2938
+	 * @param string $utm_campaign_source what is the key used for google analytics link
2939
+	 * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2940
+	 *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2941
+	 * @return void
2942
+	 * @throws DomainException
2943
+	 * @throws EE_Error
2944
+	 * @throws InvalidArgumentException
2945
+	 * @throws InvalidDataTypeException
2946
+	 * @throws InvalidInterfaceException
2947
+	 */
2948
+	public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2949
+	{
2950
+		//let's generate a default preview action button if there isn't one already present.
2951
+		$this->_labels['buttons']['buy_now']           = esc_html__(
2952
+			'Upgrade to Event Espresso 4 Right Now',
2953
+			'event_espresso'
2954
+		);
2955
+		$buy_now_url                                   = add_query_arg(
2956
+			array(
2957
+				'ee_ver'       => 'ee4',
2958
+				'utm_source'   => 'ee4_plugin_admin',
2959
+				'utm_medium'   => 'link',
2960
+				'utm_campaign' => $utm_campaign_source,
2961
+				'utm_content'  => 'buy_now_button',
2962
+			),
2963
+			'http://eventespresso.com/pricing/'
2964
+		);
2965
+		$this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2966
+			? $this->get_action_link_or_button(
2967
+				'',
2968
+				'buy_now',
2969
+				array(),
2970
+				'button-primary button-large',
2971
+				$buy_now_url,
2972
+				true
2973
+			)
2974
+			: $this->_template_args['preview_action_button'];
2975
+		$this->_template_args['admin_page_content']    = EEH_Template::display_template(
2976
+			EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2977
+			$this->_template_args,
2978
+			true
2979
+		);
2980
+		$this->_display_admin_page($display_sidebar);
2981
+	}
2982
+
2983
+
2984
+
2985
+	/**
2986
+	 * display_admin_list_table_page_with_sidebar
2987
+	 * generates HTML wrapper for an admin_page with list_table
2988
+	 *
2989
+	 * @return void
2990
+	 * @throws EE_Error
2991
+	 * @throws DomainException
2992
+	 */
2993
+	public function display_admin_list_table_page_with_sidebar()
2994
+	{
2995
+		$this->_display_admin_list_table_page(true);
2996
+	}
2997
+
2998
+
2999
+
3000
+	/**
3001
+	 * display_admin_list_table_page_with_no_sidebar
3002
+	 * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
3003
+	 *
3004
+	 * @return void
3005
+	 * @throws EE_Error
3006
+	 * @throws DomainException
3007
+	 */
3008
+	public function display_admin_list_table_page_with_no_sidebar()
3009
+	{
3010
+		$this->_display_admin_list_table_page();
3011
+	}
3012
+
3013
+
3014
+
3015
+	/**
3016
+	 * generates html wrapper for an admin_list_table page
3017
+	 *
3018
+	 * @param boolean $sidebar whether to display with sidebar or not.
3019
+	 * @return void
3020
+	 * @throws DomainException
3021
+	 * @throws EE_Error
3022
+	 */
3023
+	private function _display_admin_list_table_page($sidebar = false)
3024
+	{
3025
+		//setup search attributes
3026
+		$this->_set_search_attributes();
3027
+		$this->_template_args['current_page']     = $this->_wp_page_slug;
3028
+		$template_path                            = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3029
+		$this->_template_args['table_url']        = defined('DOING_AJAX')
3030
+			? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3031
+			: add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3032
+		$this->_template_args['list_table']       = $this->_list_table_object;
3033
+		$this->_template_args['current_route']    = $this->_req_action;
3034
+		$this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3035
+		$ajax_sorting_callback                    = $this->_list_table_object->get_ajax_sorting_callback();
3036
+		if (! empty($ajax_sorting_callback)) {
3037
+			$sortable_list_table_form_fields = wp_nonce_field(
3038
+				$ajax_sorting_callback . '_nonce',
3039
+				$ajax_sorting_callback . '_nonce',
3040
+				false,
3041
+				false
3042
+			);
3043
+			//			$reorder_action = 'espresso_' . $ajax_sorting_callback . '_nonce';
3044
+			//			$sortable_list_table_form_fields = wp_nonce_field( $reorder_action, 'ajax_table_sort_nonce', FALSE, FALSE );
3045
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3046
+												. $this->page_slug
3047
+												. '" />';
3048
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3049
+												. $ajax_sorting_callback
3050
+												. '" />';
3051
+		} else {
3052
+			$sortable_list_table_form_fields = '';
3053
+		}
3054
+		$this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3055
+		$hidden_form_fields                                      = isset($this->_template_args['list_table_hidden_fields'])
3056
+			? $this->_template_args['list_table_hidden_fields']
3057
+			: '';
3058
+		$nonce_ref                                               = $this->_req_action . '_nonce';
3059
+		$hidden_form_fields                                      .= '<input type="hidden" name="'
3060
+																	. $nonce_ref
3061
+																	. '" value="'
3062
+																	. wp_create_nonce($nonce_ref)
3063
+																	. '">';
3064
+		$this->_template_args['list_table_hidden_fields']        = $hidden_form_fields;
3065
+		//display message about search results?
3066
+		$this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3067
+			? '<p class="ee-search-results">' . sprintf(
3068
+				esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3069
+				trim($this->_req_data['s'], '%')
3070
+			) . '</p>'
3071
+			: '';
3072
+		// filter before_list_table template arg
3073
+		$this->_template_args['before_list_table'] = apply_filters(
3074
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3075
+			$this->_template_args['before_list_table'],
3076
+			$this->page_slug,
3077
+			$this->_req_data,
3078
+			$this->_req_action
3079
+		);
3080
+		// convert to array and filter again
3081
+		// arrays are easier to inject new items in a specific location,
3082
+		// but would not be backwards compatible, so we have to add a new filter
3083
+		$this->_template_args['before_list_table'] = implode(
3084
+			" \n",
3085
+			(array)apply_filters(
3086
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3087
+				(array)$this->_template_args['before_list_table'],
3088
+				$this->page_slug,
3089
+				$this->_req_data,
3090
+				$this->_req_action
3091
+			)
3092
+		);
3093
+		// filter after_list_table template arg
3094
+		$this->_template_args['after_list_table'] = apply_filters(
3095
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3096
+			$this->_template_args['after_list_table'],
3097
+			$this->page_slug,
3098
+			$this->_req_data,
3099
+			$this->_req_action
3100
+		);
3101
+		// convert to array and filter again
3102
+		// arrays are easier to inject new items in a specific location,
3103
+		// but would not be backwards compatible, so we have to add a new filter
3104
+		$this->_template_args['after_list_table']   = implode(
3105
+			" \n",
3106
+			(array)apply_filters(
3107
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3108
+				(array)$this->_template_args['after_list_table'],
3109
+				$this->page_slug,
3110
+				$this->_req_data,
3111
+				$this->_req_action
3112
+			)
3113
+		);
3114
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3115
+			$template_path,
3116
+			$this->_template_args,
3117
+			true
3118
+		);
3119
+		// the final template wrapper
3120
+		if ($sidebar) {
3121
+			$this->display_admin_page_with_sidebar();
3122
+		} else {
3123
+			$this->display_admin_page_with_no_sidebar();
3124
+		}
3125
+	}
3126
+
3127
+
3128
+
3129
+	/**
3130
+	 * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3131
+	 * html string for the legend.
3132
+	 * $items are expected in an array in the following format:
3133
+	 * $legend_items = array(
3134
+	 *        'item_id' => array(
3135
+	 *            'icon' => 'http://url_to_icon_being_described.png',
3136
+	 *            'desc' => esc_html__('localized description of item');
3137
+	 *        )
3138
+	 * );
3139
+	 *
3140
+	 * @param  array $items see above for format of array
3141
+	 * @return string html string of legend
3142
+	 * @throws DomainException
3143
+	 */
3144
+	protected function _display_legend($items)
3145
+	{
3146
+		$this->_template_args['items'] = apply_filters(
3147
+			'FHEE__EE_Admin_Page___display_legend__items',
3148
+			(array)$items,
3149
+			$this
3150
+		);
3151
+		return EEH_Template::display_template(
3152
+			EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3153
+			$this->_template_args,
3154
+			true
3155
+		);
3156
+	}
3157
+
3158
+
3159
+	/**
3160
+	 * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3161
+	 * The returned json object is created from an array in the following format:
3162
+	 * array(
3163
+	 *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3164
+	 *  'success' => FALSE, //(default FALSE) - contains any special success message.
3165
+	 *  'notices' => '', // - contains any EE_Error formatted notices
3166
+	 *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3167
+	 *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3168
+	 *  We're also going to include the template args with every package (so js can pick out any specific template args
3169
+	 *  that might be included in here)
3170
+	 * )
3171
+	 * The json object is populated by whatever is set in the $_template_args property.
3172
+	 *
3173
+	 * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3174
+	 *                                 instead of displayed.
3175
+	 * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3176
+	 * @return void
3177
+	 * @throws EE_Error
3178
+	 */
3179
+	protected function _return_json($sticky_notices = false, $notices_arguments = array())
3180
+	{
3181
+		//make sure any EE_Error notices have been handled.
3182
+		$this->_process_notices($notices_arguments, true, $sticky_notices);
3183
+		$data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3184
+		unset($this->_template_args['data']);
3185
+		$json = array(
3186
+			'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3187
+			'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3188
+			'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3189
+			'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3190
+			'notices'   => EE_Error::get_notices(),
3191
+			'content'   => isset($this->_template_args['admin_page_content'])
3192
+				? $this->_template_args['admin_page_content'] : '',
3193
+			'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3194
+			'isEEajax'  => true
3195
+			//special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3196
+		);
3197
+		// make sure there are no php errors or headers_sent.  Then we can set correct json header.
3198
+		if (null === error_get_last() || ! headers_sent()) {
3199
+			header('Content-Type: application/json; charset=UTF-8');
3200
+		}
3201
+		echo wp_json_encode($json);
3202
+		exit();
3203
+	}
3204
+
3205
+
3206
+
3207
+	/**
3208
+	 * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3209
+	 *
3210
+	 * @return void
3211
+	 * @throws EE_Error
3212
+	 */
3213
+	public function return_json()
3214
+	{
3215
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3216
+			$this->_return_json();
3217
+		} else {
3218
+			throw new EE_Error(
3219
+				sprintf(
3220
+					esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3221
+					__FUNCTION__
3222
+				)
3223
+			);
3224
+		}
3225
+	}
3226
+
3227
+
3228
+
3229
+	/**
3230
+	 * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3231
+	 * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3232
+	 *
3233
+	 * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3234
+	 */
3235
+	public function set_hook_object(EE_Admin_Hooks $hook_obj)
3236
+	{
3237
+		$this->_hook_obj = $hook_obj;
3238
+	}
3239
+
3240
+
3241
+
3242
+	/**
3243
+	 *        generates  HTML wrapper with Tabbed nav for an admin page
3244
+	 *
3245
+	 * @param  boolean $about whether to use the special about page wrapper or default.
3246
+	 * @return void
3247
+	 * @throws DomainException
3248
+	 * @throws EE_Error
3249
+	 */
3250
+	public function admin_page_wrapper($about = false)
3251
+	{
3252
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3253
+		$this->_nav_tabs                                   = $this->_get_main_nav_tabs();
3254
+		$this->_template_args['nav_tabs']                  = $this->_nav_tabs;
3255
+		$this->_template_args['admin_page_title']          = $this->_admin_page_title;
3256
+		$this->_template_args['before_admin_page_content'] = apply_filters(
3257
+			"FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3258
+			isset($this->_template_args['before_admin_page_content'])
3259
+				? $this->_template_args['before_admin_page_content']
3260
+				: ''
3261
+		);
3262
+		$this->_template_args['after_admin_page_content']  = apply_filters(
3263
+			"FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3264
+			isset($this->_template_args['after_admin_page_content'])
3265
+				? $this->_template_args['after_admin_page_content']
3266
+				: ''
3267
+		);
3268
+		$this->_template_args['after_admin_page_content']  .= $this->_set_help_popup_content();
3269
+		// load settings page wrapper template
3270
+		$template_path = ! defined('DOING_AJAX')
3271
+			? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3272
+			: EE_ADMIN_TEMPLATE
3273
+			  . 'admin_wrapper_ajax.template.php';
3274
+		//about page?
3275
+		$template_path = $about
3276
+			? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3277
+			: $template_path;
3278
+		if (defined('DOING_AJAX')) {
3279
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3280
+				$template_path,
3281
+				$this->_template_args,
3282
+				true
3283
+			);
3284
+			$this->_return_json();
3285
+		} else {
3286
+			EEH_Template::display_template($template_path, $this->_template_args);
3287
+		}
3288
+	}
3289
+
3290
+
3291
+
3292
+	/**
3293
+	 * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3294
+	 *
3295
+	 * @return string html
3296
+	 * @throws EE_Error
3297
+	 */
3298
+	protected function _get_main_nav_tabs()
3299
+	{
3300
+		// let's generate the html using the EEH_Tabbed_Content helper.
3301
+		// We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3302
+		// (rather than setting in the page_routes array)
3303
+		return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3304
+	}
3305
+
3306
+
3307
+
3308
+	/**
3309
+	 *        sort nav tabs
3310
+	 *
3311
+	 * @param $a
3312
+	 * @param $b
3313
+	 * @return int
3314
+	 */
3315
+	private function _sort_nav_tabs($a, $b)
3316
+	{
3317
+		if ($a['order'] === $b['order']) {
3318
+			return 0;
3319
+		}
3320
+		return ($a['order'] < $b['order']) ? -1 : 1;
3321
+	}
3322
+
3323
+
3324
+
3325
+	/**
3326
+	 *    generates HTML for the forms used on admin pages
3327
+	 *
3328
+	 * @param    array $input_vars - array of input field details
3329
+	 * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3330
+	 *                             use)
3331
+	 * @param bool     $id
3332
+	 * @return string
3333
+	 * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3334
+	 * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3335
+	 */
3336
+	protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3337
+	{
3338
+		$content = $generator === 'string'
3339
+			? EEH_Form_Fields::get_form_fields($input_vars, $id)
3340
+			: EEH_Form_Fields::get_form_fields_array($input_vars);
3341
+		return $content;
3342
+	}
3343
+
3344
+
3345
+
3346
+	/**
3347
+	 * generates the "Save" and "Save & Close" buttons for edit forms
3348
+	 *
3349
+	 * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3350
+	 *                                   Close" button.
3351
+	 * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3352
+	 *                                   'Save', [1] => 'save & close')
3353
+	 * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3354
+	 *                                   via the "name" value in the button).  We can also use this to just dump
3355
+	 *                                   default actions by submitting some other value.
3356
+	 * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3357
+	 *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3358
+	 *                                   close (normal form handling).
3359
+	 */
3360
+	protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3361
+	{
3362
+		//make sure $text and $actions are in an array
3363
+		$text          = (array)$text;
3364
+		$actions       = (array)$actions;
3365
+		$referrer_url  = empty($referrer)
3366
+			? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3367
+			  . $_SERVER['REQUEST_URI']
3368
+			  . '" />'
3369
+			: '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3370
+			  . $referrer
3371
+			  . '" />';
3372
+		$button_text   = ! empty($text)
3373
+			? $text
3374
+			: array(
3375
+				esc_html__('Save', 'event_espresso'),
3376
+				esc_html__('Save and Close', 'event_espresso'),
3377
+			);
3378
+		$default_names = array('save', 'save_and_close');
3379
+		//add in a hidden index for the current page (so save and close redirects properly)
3380
+		$this->_template_args['save_buttons'] = $referrer_url;
3381
+		foreach ($button_text as $key => $button) {
3382
+			$ref                                  = $default_names[$key];
3383
+			$this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3384
+													 . $ref
3385
+													 . '" value="'
3386
+													 . $button
3387
+													 . '" name="'
3388
+													 . (! empty($actions) ? $actions[$key] : $ref)
3389
+													 . '" id="'
3390
+													 . $this->_current_view . '_' . $ref
3391
+													 . '" />';
3392
+			if (! $both) {
3393
+				break;
3394
+			}
3395
+		}
3396
+	}
3397
+
3398
+
3399
+
3400
+	/**
3401
+	 * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3402
+	 *
3403
+	 * @see   $this->_set_add_edit_form_tags() for details on params
3404
+	 * @since 4.6.0
3405
+	 * @param string $route
3406
+	 * @param array  $additional_hidden_fields
3407
+	 */
3408
+	public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3409
+	{
3410
+		$this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3411
+	}
3412
+
3413
+
3414
+
3415
+	/**
3416
+	 * set form open and close tags on add/edit pages.
3417
+	 *
3418
+	 * @param string $route                    the route you want the form to direct to
3419
+	 * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3420
+	 * @return void
3421
+	 */
3422
+	protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3423
+	{
3424
+		if (empty($route)) {
3425
+			$user_msg = esc_html__(
3426
+				'An error occurred. No action was set for this page\'s form.',
3427
+				'event_espresso'
3428
+			);
3429
+			$dev_msg  = $user_msg . "\n" . sprintf(
3430
+					esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3431
+					__FUNCTION__,
3432
+					__CLASS__
3433
+				);
3434
+			EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3435
+		}
3436
+		// open form
3437
+		$this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3438
+															 . $this->_admin_base_url
3439
+															 . '" id="'
3440
+															 . $route
3441
+															 . '_event_form" >';
3442
+		// add nonce
3443
+		$nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3444
+		//		$nonce = wp_nonce_field( $route . '_nonce', '_wpnonce', FALSE, FALSE );
3445
+		$this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3446
+		// add REQUIRED form action
3447
+		$hidden_fields = array(
3448
+			'action' => array('type' => 'hidden', 'value' => $route),
3449
+		);
3450
+		// merge arrays
3451
+		$hidden_fields = is_array($additional_hidden_fields)
3452
+			? array_merge($hidden_fields, $additional_hidden_fields)
3453
+			: $hidden_fields;
3454
+		// generate form fields
3455
+		$form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456
+		// add fields to form
3457
+		foreach ((array)$form_fields as $field_name => $form_field) {
3458
+			$this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3459
+		}
3460
+		// close form
3461
+		$this->_template_args['after_admin_page_content'] = '</form>';
3462
+	}
3463
+
3464
+
3465
+
3466
+	/**
3467
+	 * Public Wrapper for _redirect_after_action() method since its
3468
+	 * discovered it would be useful for external code to have access.
3469
+	 *
3470
+	 * @see   EE_Admin_Page::_redirect_after_action() for params.
3471
+	 * @since 4.5.0
3472
+	 * @param bool   $success
3473
+	 * @param string $what
3474
+	 * @param string $action_desc
3475
+	 * @param array  $query_args
3476
+	 * @param bool   $override_overwrite
3477
+	 * @throws EE_Error
3478
+	 */
3479
+	public function redirect_after_action(
3480
+		$success = false,
3481
+		$what = 'item',
3482
+		$action_desc = 'processed',
3483
+		$query_args = array(),
3484
+		$override_overwrite = false
3485
+	) {
3486
+		$this->_redirect_after_action(
3487
+			$success,
3488
+			$what,
3489
+			$action_desc,
3490
+			$query_args,
3491
+			$override_overwrite
3492
+		);
3493
+	}
3494
+
3495
+
3496
+
3497
+	/**
3498
+	 *    _redirect_after_action
3499
+	 *
3500
+	 * @param int    $success            - whether success was for two or more records, or just one, or none
3501
+	 * @param string $what               - what the action was performed on
3502
+	 * @param string $action_desc        - what was done ie: updated, deleted, etc
3503
+	 * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3504
+	 *                                   action is completed
3505
+	 * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3506
+	 *                                   override this so that they show.
3507
+	 * @return void
3508
+	 * @throws EE_Error
3509
+	 */
3510
+	protected function _redirect_after_action(
3511
+		$success = 0,
3512
+		$what = 'item',
3513
+		$action_desc = 'processed',
3514
+		$query_args = array(),
3515
+		$override_overwrite = false
3516
+	) {
3517
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3518
+		//class name for actions/filters.
3519
+		$classname = get_class($this);
3520
+		// set redirect url.
3521
+		// Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3522
+		// otherwise we go with whatever is set as the _admin_base_url
3523
+		$redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3524
+		$notices      = EE_Error::get_notices(false);
3525
+		// overwrite default success messages //BUT ONLY if overwrite not overridden
3526
+		if (! $override_overwrite || ! empty($notices['errors'])) {
3527
+			EE_Error::overwrite_success();
3528
+		}
3529
+		if (! empty($what) && ! empty($action_desc)  && empty($notices['errors'])) {
3530
+			// how many records affected ? more than one record ? or just one ?
3531
+			if ($success > 1) {
3532
+				// set plural msg
3533
+				EE_Error::add_success(
3534
+					sprintf(
3535
+						esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3536
+						$what,
3537
+						$action_desc
3538
+					),
3539
+					__FILE__,
3540
+					__FUNCTION__,
3541
+					__LINE__
3542
+				);
3543
+			} elseif ($success === 1) {
3544
+				// set singular msg
3545
+				EE_Error::add_success(
3546
+					sprintf(
3547
+						esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3548
+						$what,
3549
+						$action_desc
3550
+					),
3551
+					__FILE__,
3552
+					__FUNCTION__,
3553
+					__LINE__
3554
+				);
3555
+			}
3556
+		}
3557
+		// check that $query_args isn't something crazy
3558
+		if (! is_array($query_args)) {
3559
+			$query_args = array();
3560
+		}
3561
+		/**
3562
+		 * Allow injecting actions before the query_args are modified for possible different
3563
+		 * redirections on save and close actions
3564
+		 *
3565
+		 * @since 4.2.0
3566
+		 * @param array $query_args       The original query_args array coming into the
3567
+		 *                                method.
3568
+		 */
3569
+		do_action(
3570
+			"AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3571
+			$query_args
3572
+		);
3573
+		//calculate where we're going (if we have a "save and close" button pushed)
3574
+		if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3575
+			// even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3576
+			$parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3577
+			// regenerate query args array from referrer URL
3578
+			parse_str($parsed_url['query'], $query_args);
3579
+			// correct page and action will be in the query args now
3580
+			$redirect_url = admin_url('admin.php');
3581
+		}
3582
+		//merge any default query_args set in _default_route_query_args property
3583
+		if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3584
+			$args_to_merge = array();
3585
+			foreach ($this->_default_route_query_args as $query_param => $query_value) {
3586
+				//is there a wp_referer array in our _default_route_query_args property?
3587
+				if ($query_param === 'wp_referer') {
3588
+					$query_value = (array)$query_value;
3589
+					foreach ($query_value as $reference => $value) {
3590
+						if (strpos($reference, 'nonce') !== false) {
3591
+							continue;
3592
+						}
3593
+						//finally we will override any arguments in the referer with
3594
+						//what might be set on the _default_route_query_args array.
3595
+						if (isset($this->_default_route_query_args[$reference])) {
3596
+							$args_to_merge[$reference] = urlencode($this->_default_route_query_args[$reference]);
3597
+						} else {
3598
+							$args_to_merge[$reference] = urlencode($value);
3599
+						}
3600
+					}
3601
+					continue;
3602
+				}
3603
+				$args_to_merge[$query_param] = $query_value;
3604
+			}
3605
+			//now let's merge these arguments but override with what was specifically sent in to the
3606
+			//redirect.
3607
+			$query_args = array_merge($args_to_merge, $query_args);
3608
+		}
3609
+		$this->_process_notices($query_args);
3610
+		// generate redirect url
3611
+		// if redirecting to anything other than the main page, add a nonce
3612
+		if (isset($query_args['action'])) {
3613
+			// manually generate wp_nonce and merge that with the query vars
3614
+			// becuz the wp_nonce_url function wrecks havoc on some vars
3615
+			$query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3616
+		}
3617
+		// we're adding some hooks and filters in here for processing any things just before redirects
3618
+		// (example: an admin page has done an insert or update and we want to run something after that).
3619
+		do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3620
+		$redirect_url = apply_filters(
3621
+			'FHEE_redirect_' . $classname . $this->_req_action,
3622
+			self::add_query_args_and_nonce($query_args, $redirect_url),
3623
+			$query_args
3624
+		);
3625
+		// check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3626
+		if (defined('DOING_AJAX')) {
3627
+			$default_data                    = array(
3628
+				'close'        => true,
3629
+				'redirect_url' => $redirect_url,
3630
+				'where'        => 'main',
3631
+				'what'         => 'append',
3632
+			);
3633
+			$this->_template_args['success'] = $success;
3634
+			$this->_template_args['data']    = ! empty($this->_template_args['data']) ? array_merge(
3635
+				$default_data,
3636
+				$this->_template_args['data']
3637
+			) : $default_data;
3638
+			$this->_return_json();
3639
+		}
3640
+		wp_safe_redirect($redirect_url);
3641
+		exit();
3642
+	}
3643
+
3644
+
3645
+
3646
+	/**
3647
+	 * process any notices before redirecting (or returning ajax request)
3648
+	 * This method sets the $this->_template_args['notices'] attribute;
3649
+	 *
3650
+	 * @param  array $query_args        any query args that need to be used for notice transient ('action')
3651
+	 * @param bool   $skip_route_verify This is typically used when we are processing notices REALLY early and
3652
+	 *                                  page_routes haven't been defined yet.
3653
+	 * @param bool   $sticky_notices    This is used to flag that regardless of whether this is doing_ajax or not, we
3654
+	 *                                  still save a transient for the notice.
3655
+	 * @return void
3656
+	 * @throws EE_Error
3657
+	 */
3658
+	protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3659
+	{
3660
+		//first let's set individual error properties if doing_ajax and the properties aren't already set.
3661
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3662
+			$notices = EE_Error::get_notices(false);
3663
+			if (empty($this->_template_args['success'])) {
3664
+				$this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3665
+			}
3666
+			if (empty($this->_template_args['errors'])) {
3667
+				$this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3668
+			}
3669
+			if (empty($this->_template_args['attention'])) {
3670
+				$this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3671
+			}
3672
+		}
3673
+		$this->_template_args['notices'] = EE_Error::get_notices();
3674
+		//IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3675
+		if (! defined('DOING_AJAX') || $sticky_notices) {
3676
+			$route = isset($query_args['action']) ? $query_args['action'] : 'default';
3677
+			$this->_add_transient(
3678
+				$route,
3679
+				$this->_template_args['notices'],
3680
+				true,
3681
+				$skip_route_verify
3682
+			);
3683
+		}
3684
+	}
3685
+
3686
+
3687
+
3688
+	/**
3689
+	 * get_action_link_or_button
3690
+	 * returns the button html for adding, editing, or deleting an item (depending on given type)
3691
+	 *
3692
+	 * @param string $action        use this to indicate which action the url is generated with.
3693
+	 * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3694
+	 *                              property.
3695
+	 * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3696
+	 * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3697
+	 * @param string $base_url      If this is not provided
3698
+	 *                              the _admin_base_url will be used as the default for the button base_url.
3699
+	 *                              Otherwise this value will be used.
3700
+	 * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3701
+	 * @return string
3702
+	 * @throws InvalidArgumentException
3703
+	 * @throws InvalidInterfaceException
3704
+	 * @throws InvalidDataTypeException
3705
+	 * @throws EE_Error
3706
+	 */
3707
+	public function get_action_link_or_button(
3708
+		$action,
3709
+		$type = 'add',
3710
+		$extra_request = array(),
3711
+		$class = 'button-primary',
3712
+		$base_url = '',
3713
+		$exclude_nonce = false
3714
+	) {
3715
+		//first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3716
+		if (empty($base_url) && ! isset($this->_page_routes[$action])) {
3717
+			throw new EE_Error(
3718
+				sprintf(
3719
+					esc_html__(
3720
+						'There is no page route for given action for the button.  This action was given: %s',
3721
+						'event_espresso'
3722
+					),
3723
+					$action
3724
+				)
3725
+			);
3726
+		}
3727
+		if (! isset($this->_labels['buttons'][$type])) {
3728
+			throw new EE_Error(
3729
+				sprintf(
3730
+					__(
3731
+						'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3732
+						'event_espresso'
3733
+					),
3734
+					$type
3735
+				)
3736
+			);
3737
+		}
3738
+		//finally check user access for this button.
3739
+		$has_access = $this->check_user_access($action, true);
3740
+		if (! $has_access) {
3741
+			return '';
3742
+		}
3743
+		$_base_url  = ! $base_url ? $this->_admin_base_url : $base_url;
3744
+		$query_args = array(
3745
+			'action' => $action,
3746
+		);
3747
+		//merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3748
+		if (! empty($extra_request)) {
3749
+			$query_args = array_merge($extra_request, $query_args);
3750
+		}
3751
+		$url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3752
+		return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][$type], $class);
3753
+	}
3754
+
3755
+
3756
+
3757
+	/**
3758
+	 * _per_page_screen_option
3759
+	 * Utility function for adding in a per_page_option in the screen_options_dropdown.
3760
+	 *
3761
+	 * @return void
3762
+	 * @throws InvalidArgumentException
3763
+	 * @throws InvalidInterfaceException
3764
+	 * @throws InvalidDataTypeException
3765
+	 */
3766
+	protected function _per_page_screen_option()
3767
+	{
3768
+		$option = 'per_page';
3769
+		$args   = array(
3770
+			'label'   => $this->_admin_page_title,
3771
+			'default' => 10,
3772
+			'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3773
+		);
3774
+		//ONLY add the screen option if the user has access to it.
3775
+		if ($this->check_user_access($this->_current_view, true)) {
3776
+			add_screen_option($option, $args);
3777
+		}
3778
+	}
3779
+
3780
+
3781
+
3782
+	/**
3783
+	 * set_per_page_screen_option
3784
+	 * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3785
+	 * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3786
+	 * admin_menu.
3787
+	 *
3788
+	 * @return void
3789
+	 */
3790
+	private function _set_per_page_screen_options()
3791
+	{
3792
+		if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3793
+			check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3794
+			if (! $user = wp_get_current_user()) {
3795
+				return;
3796
+			}
3797
+			$option = $_POST['wp_screen_options']['option'];
3798
+			$value  = $_POST['wp_screen_options']['value'];
3799
+			if ($option != sanitize_key($option)) {
3800
+				return;
3801
+			}
3802
+			$map_option = $option;
3803
+			$option     = str_replace('-', '_', $option);
3804
+			switch ($map_option) {
3805
+				case $this->_current_page . '_' . $this->_current_view . '_per_page':
3806
+					$value = (int)$value;
3807
+					if ($value < 1 || $value > 999) {
3808
+						return;
3809
+					}
3810
+					break;
3811
+				default:
3812
+					$value = apply_filters(
3813
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3814
+						false,
3815
+						$option,
3816
+						$value
3817
+					);
3818
+					if (false === $value) {
3819
+						return;
3820
+					}
3821
+					break;
3822
+			}
3823
+			update_user_meta($user->ID, $option, $value);
3824
+			wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3825
+			exit;
3826
+		}
3827
+	}
3828
+
3829
+
3830
+
3831
+	/**
3832
+	 * This just allows for setting the $_template_args property if it needs to be set outside the object
3833
+	 *
3834
+	 * @param array $data array that will be assigned to template args.
3835
+	 */
3836
+	public function set_template_args($data)
3837
+	{
3838
+		$this->_template_args = array_merge($this->_template_args, (array)$data);
3839
+	}
3840
+
3841
+
3842
+
3843
+	/**
3844
+	 * This makes available the WP transient system for temporarily moving data between routes
3845
+	 *
3846
+	 * @param string $route             the route that should receive the transient
3847
+	 * @param array  $data              the data that gets sent
3848
+	 * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3849
+	 *                                  normal route transient.
3850
+	 * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3851
+	 *                                  when we are adding a transient before page_routes have been defined.
3852
+	 * @return void
3853
+	 * @throws EE_Error
3854
+	 */
3855
+	protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3856
+	{
3857
+		$user_id = get_current_user_id();
3858
+		if (! $skip_route_verify) {
3859
+			$this->_verify_route($route);
3860
+		}
3861
+		//now let's set the string for what kind of transient we're setting
3862
+		$transient = $notices
3863
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3864
+			: 'rte_tx_' . $route . '_' . $user_id;
3865
+		$data      = $notices ? array('notices' => $data) : $data;
3866
+		//is there already a transient for this route?  If there is then let's ADD to that transient
3867
+		$existing = is_multisite() && is_network_admin()
3868
+			? get_site_transient($transient)
3869
+			: get_transient($transient);
3870
+		if ($existing) {
3871
+			$data = array_merge((array)$data, (array)$existing);
3872
+		}
3873
+		if (is_multisite() && is_network_admin()) {
3874
+			set_site_transient($transient, $data, 8);
3875
+		} else {
3876
+			set_transient($transient, $data, 8);
3877
+		}
3878
+	}
3879
+
3880
+
3881
+
3882
+	/**
3883
+	 * this retrieves the temporary transient that has been set for moving data between routes.
3884
+	 *
3885
+	 * @param bool   $notices true we get notices transient. False we just return normal route transient
3886
+	 * @param string $route
3887
+	 * @return mixed data
3888
+	 */
3889
+	protected function _get_transient($notices = false, $route = '')
3890
+	{
3891
+		$user_id   = get_current_user_id();
3892
+		$route     = ! $route ? $this->_req_action : $route;
3893
+		$transient = $notices
3894
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3895
+			: 'rte_tx_' . $route . '_' . $user_id;
3896
+		$data      = is_multisite() && is_network_admin()
3897
+			? get_site_transient($transient)
3898
+			: get_transient($transient);
3899
+		//delete transient after retrieval (just in case it hasn't expired);
3900
+		if (is_multisite() && is_network_admin()) {
3901
+			delete_site_transient($transient);
3902
+		} else {
3903
+			delete_transient($transient);
3904
+		}
3905
+		return $notices && isset($data['notices']) ? $data['notices'] : $data;
3906
+	}
3907
+
3908
+
3909
+
3910
+	/**
3911
+	 * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3912
+	 * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3913
+	 * default route callback on the EE_Admin page you want it run.)
3914
+	 *
3915
+	 * @return void
3916
+	 */
3917
+	protected function _transient_garbage_collection()
3918
+	{
3919
+		global $wpdb;
3920
+		//retrieve all existing transients
3921
+		$query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3922
+		if ($results = $wpdb->get_results($query)) {
3923
+			foreach ($results as $result) {
3924
+				$transient = str_replace('_transient_', '', $result->option_name);
3925
+				get_transient($transient);
3926
+				if (is_multisite() && is_network_admin()) {
3927
+					get_site_transient($transient);
3928
+				}
3929
+			}
3930
+		}
3931
+	}
3932
+
3933
+
3934
+
3935
+	/**
3936
+	 * get_view
3937
+	 *
3938
+	 * @return string content of _view property
3939
+	 */
3940
+	public function get_view()
3941
+	{
3942
+		return $this->_view;
3943
+	}
3944
+
3945
+
3946
+
3947
+	/**
3948
+	 * getter for the protected $_views property
3949
+	 *
3950
+	 * @return array
3951
+	 */
3952
+	public function get_views()
3953
+	{
3954
+		return $this->_views;
3955
+	}
3956
+
3957
+
3958
+
3959
+	/**
3960
+	 * get_current_page
3961
+	 *
3962
+	 * @return string _current_page property value
3963
+	 */
3964
+	public function get_current_page()
3965
+	{
3966
+		return $this->_current_page;
3967
+	}
3968
+
3969
+
3970
+
3971
+	/**
3972
+	 * get_current_view
3973
+	 *
3974
+	 * @return string _current_view property value
3975
+	 */
3976
+	public function get_current_view()
3977
+	{
3978
+		return $this->_current_view;
3979
+	}
3980
+
3981
+
3982
+
3983
+	/**
3984
+	 * get_current_screen
3985
+	 *
3986
+	 * @return object The current WP_Screen object
3987
+	 */
3988
+	public function get_current_screen()
3989
+	{
3990
+		return $this->_current_screen;
3991
+	}
3992
+
3993
+
3994
+
3995
+	/**
3996
+	 * get_current_page_view_url
3997
+	 *
3998
+	 * @return string This returns the url for the current_page_view.
3999
+	 */
4000
+	public function get_current_page_view_url()
4001
+	{
4002
+		return $this->_current_page_view_url;
4003
+	}
4004
+
4005
+
4006
+
4007
+	/**
4008
+	 * just returns the _req_data property
4009
+	 *
4010
+	 * @return array
4011
+	 */
4012
+	public function get_request_data()
4013
+	{
4014
+		return $this->_req_data;
4015
+	}
4016
+
4017
+
4018
+
4019
+	/**
4020
+	 * returns the _req_data protected property
4021
+	 *
4022
+	 * @return string
4023
+	 */
4024
+	public function get_req_action()
4025
+	{
4026
+		return $this->_req_action;
4027
+	}
4028
+
4029
+
4030
+
4031
+	/**
4032
+	 * @return bool  value of $_is_caf property
4033
+	 */
4034
+	public function is_caf()
4035
+	{
4036
+		return $this->_is_caf;
4037
+	}
4038
+
4039
+
4040
+
4041
+	/**
4042
+	 * @return mixed
4043
+	 */
4044
+	public function default_espresso_metaboxes()
4045
+	{
4046
+		return $this->_default_espresso_metaboxes;
4047
+	}
4048
+
4049
+
4050
+
4051
+	/**
4052
+	 * @return mixed
4053
+	 */
4054
+	public function admin_base_url()
4055
+	{
4056
+		return $this->_admin_base_url;
4057
+	}
4058 4058
 
4059 4059
 
4060 4060
 
4061
-    /**
4062
-     * @return mixed
4063
-     */
4064
-    public function wp_page_slug()
4065
-    {
4066
-        return $this->_wp_page_slug;
4067
-    }
4061
+	/**
4062
+	 * @return mixed
4063
+	 */
4064
+	public function wp_page_slug()
4065
+	{
4066
+		return $this->_wp_page_slug;
4067
+	}
4068 4068
 
4069 4069
 
4070
-
4071
-    /**
4072
-     * updates  espresso configuration settings
4073
-     *
4074
-     * @param string                   $tab
4075
-     * @param EE_Config_Base|EE_Config $config
4076
-     * @param string                   $file file where error occurred
4077
-     * @param string                   $func function  where error occurred
4078
-     * @param string                   $line line no where error occurred
4079
-     * @return boolean
4080
-     */
4081
-    protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4082
-    {
4083
-        //remove any options that are NOT going to be saved with the config settings.
4084
-        if (isset($config->core->ee_ueip_optin)) {
4085
-            $config->core->ee_ueip_has_notified = true;
4086
-            // TODO: remove the following two lines and make sure values are migrated from 3.1
4087
-            update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4088
-            update_option('ee_ueip_has_notified', true);
4089
-        }
4090
-        // and save it (note we're also doing the network save here)
4091
-        $net_saved    = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4092
-        $config_saved = EE_Config::instance()->update_espresso_config(false, false);
4093
-        if ($config_saved && $net_saved) {
4094
-            EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4095
-            return true;
4096
-        }
4097
-        EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4098
-        return false;
4099
-    }
4100
-
4101
-
4102
-
4103
-    /**
4104
-     * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4105
-     *
4106
-     * @return array
4107
-     */
4108
-    public function get_yes_no_values()
4109
-    {
4110
-        return $this->_yes_no_values;
4111
-    }
4112
-
4113
-
4114
-
4115
-    protected function _get_dir()
4116
-    {
4117
-        $reflector = new ReflectionClass(get_class($this));
4118
-        return dirname($reflector->getFileName());
4119
-    }
4120
-
4121
-
4122
-
4123
-    /**
4124
-     * A helper for getting a "next link".
4125
-     *
4126
-     * @param string $url   The url to link to
4127
-     * @param string $class The class to use.
4128
-     * @return string
4129
-     */
4130
-    protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4131
-    {
4132
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4133
-    }
4134
-
4135
-
4136
-
4137
-    /**
4138
-     * A helper for getting a "previous link".
4139
-     *
4140
-     * @param string $url   The url to link to
4141
-     * @param string $class The class to use.
4142
-     * @return string
4143
-     */
4144
-    protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4145
-    {
4146
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4147
-    }
4148
-
4149
-
4150
-
4151
-
4152
-
4153
-
4154
-
4155
-    //below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4156
-
4157
-
4158
-    /**
4159
-     * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4160
-     * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4161
-     * _req_data array.
4162
-     *
4163
-     * @return bool success/fail
4164
-     * @throws EE_Error
4165
-     * @throws InvalidArgumentException
4166
-     * @throws ReflectionException
4167
-     * @throws InvalidDataTypeException
4168
-     * @throws InvalidInterfaceException
4169
-     */
4170
-    protected function _process_resend_registration()
4171
-    {
4172
-        $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4173
-        do_action(
4174
-            'AHEE__EE_Admin_Page___process_resend_registration',
4175
-            $this->_template_args['success'],
4176
-            $this->_req_data
4177
-        );
4178
-        return $this->_template_args['success'];
4179
-    }
4180
-
4181
-
4182
-
4183
-    /**
4184
-     * This automatically processes any payment message notifications when manual payment has been applied.
4185
-     *
4186
-     * @param \EE_Payment $payment
4187
-     * @return bool success/fail
4188
-     */
4189
-    protected function _process_payment_notification(EE_Payment $payment)
4190
-    {
4191
-        add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4192
-        do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4193
-        $this->_template_args['success'] = apply_filters(
4194
-            'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4195
-            false,
4196
-            $payment
4197
-        );
4198
-        return $this->_template_args['success'];
4199
-    }
4070
+
4071
+	/**
4072
+	 * updates  espresso configuration settings
4073
+	 *
4074
+	 * @param string                   $tab
4075
+	 * @param EE_Config_Base|EE_Config $config
4076
+	 * @param string                   $file file where error occurred
4077
+	 * @param string                   $func function  where error occurred
4078
+	 * @param string                   $line line no where error occurred
4079
+	 * @return boolean
4080
+	 */
4081
+	protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4082
+	{
4083
+		//remove any options that are NOT going to be saved with the config settings.
4084
+		if (isset($config->core->ee_ueip_optin)) {
4085
+			$config->core->ee_ueip_has_notified = true;
4086
+			// TODO: remove the following two lines and make sure values are migrated from 3.1
4087
+			update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4088
+			update_option('ee_ueip_has_notified', true);
4089
+		}
4090
+		// and save it (note we're also doing the network save here)
4091
+		$net_saved    = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4092
+		$config_saved = EE_Config::instance()->update_espresso_config(false, false);
4093
+		if ($config_saved && $net_saved) {
4094
+			EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4095
+			return true;
4096
+		}
4097
+		EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4098
+		return false;
4099
+	}
4100
+
4101
+
4102
+
4103
+	/**
4104
+	 * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4105
+	 *
4106
+	 * @return array
4107
+	 */
4108
+	public function get_yes_no_values()
4109
+	{
4110
+		return $this->_yes_no_values;
4111
+	}
4112
+
4113
+
4114
+
4115
+	protected function _get_dir()
4116
+	{
4117
+		$reflector = new ReflectionClass(get_class($this));
4118
+		return dirname($reflector->getFileName());
4119
+	}
4120
+
4121
+
4122
+
4123
+	/**
4124
+	 * A helper for getting a "next link".
4125
+	 *
4126
+	 * @param string $url   The url to link to
4127
+	 * @param string $class The class to use.
4128
+	 * @return string
4129
+	 */
4130
+	protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4131
+	{
4132
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4133
+	}
4134
+
4135
+
4136
+
4137
+	/**
4138
+	 * A helper for getting a "previous link".
4139
+	 *
4140
+	 * @param string $url   The url to link to
4141
+	 * @param string $class The class to use.
4142
+	 * @return string
4143
+	 */
4144
+	protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4145
+	{
4146
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4147
+	}
4148
+
4149
+
4150
+
4151
+
4152
+
4153
+
4154
+
4155
+	//below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4156
+
4157
+
4158
+	/**
4159
+	 * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4160
+	 * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4161
+	 * _req_data array.
4162
+	 *
4163
+	 * @return bool success/fail
4164
+	 * @throws EE_Error
4165
+	 * @throws InvalidArgumentException
4166
+	 * @throws ReflectionException
4167
+	 * @throws InvalidDataTypeException
4168
+	 * @throws InvalidInterfaceException
4169
+	 */
4170
+	protected function _process_resend_registration()
4171
+	{
4172
+		$this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4173
+		do_action(
4174
+			'AHEE__EE_Admin_Page___process_resend_registration',
4175
+			$this->_template_args['success'],
4176
+			$this->_req_data
4177
+		);
4178
+		return $this->_template_args['success'];
4179
+	}
4180
+
4181
+
4182
+
4183
+	/**
4184
+	 * This automatically processes any payment message notifications when manual payment has been applied.
4185
+	 *
4186
+	 * @param \EE_Payment $payment
4187
+	 * @return bool success/fail
4188
+	 */
4189
+	protected function _process_payment_notification(EE_Payment $payment)
4190
+	{
4191
+		add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4192
+		do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4193
+		$this->_template_args['success'] = apply_filters(
4194
+			'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4195
+			false,
4196
+			$payment
4197
+		);
4198
+		return $this->_template_args['success'];
4199
+	}
4200 4200
 
4201 4201
 
4202 4202
 }
Please login to merge, or discard this patch.
Spacing   +184 added lines, -184 removed lines patch added patch discarded remove patch
@@ -512,8 +512,8 @@  discard block
 block discarded – undo
512 512
             str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
513 513
         );
514 514
         global $ee_menu_slugs;
515
-        $ee_menu_slugs = (array)$ee_menu_slugs;
516
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
515
+        $ee_menu_slugs = (array) $ee_menu_slugs;
516
+        if ( ! defined('DOING_AJAX') && ( ! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
517 517
             return;
518 518
         }
519 519
         // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
@@ -537,7 +537,7 @@  discard block
 block discarded – undo
537 537
             ? $this->_req_data['route']
538 538
             : $this->_req_action;
539 539
         $this->_current_view = $this->_req_action;
540
-        $this->_req_nonce    = $this->_req_action . '_nonce';
540
+        $this->_req_nonce    = $this->_req_action.'_nonce';
541 541
         $this->_define_page_props();
542 542
         $this->_current_page_view_url = add_query_arg(
543 543
             array('page' => $this->_current_page, 'action' => $this->_current_view),
@@ -571,23 +571,23 @@  discard block
 block discarded – undo
571 571
         }
572 572
         //filter routes and page_config so addons can add their stuff. Filtering done per class
573 573
         $this->_page_routes = apply_filters(
574
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
574
+            'FHEE__'.get_class($this).'__page_setup__page_routes',
575 575
             $this->_page_routes,
576 576
             $this
577 577
         );
578 578
         $this->_page_config = apply_filters(
579
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
579
+            'FHEE__'.get_class($this).'__page_setup__page_config',
580 580
             $this->_page_config,
581 581
             $this
582 582
         );
583 583
         //if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
584 584
         // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
585 585
         if (
586
-            method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)
586
+            method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view)
587 587
         ) {
588 588
             add_action(
589 589
                 'AHEE__EE_Admin_Page__route_admin_request',
590
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
590
+                array($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view),
591 591
                 10,
592 592
                 2
593 593
             );
@@ -600,8 +600,8 @@  discard block
 block discarded – undo
600 600
             if ($this->_is_UI_request) {
601 601
                 //admin_init stuff - global, all views for this page class, specific view
602 602
                 add_action('admin_init', array($this, 'admin_init'), 10);
603
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
604
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
603
+                if (method_exists($this, 'admin_init_'.$this->_current_view)) {
604
+                    add_action('admin_init', array($this, 'admin_init_'.$this->_current_view), 15);
605 605
                 }
606 606
             } else {
607 607
                 //hijack regular WP loading and route admin request immediately
@@ -622,12 +622,12 @@  discard block
 block discarded – undo
622 622
      */
623 623
     private function _do_other_page_hooks()
624 624
     {
625
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
625
+        $registered_pages = apply_filters('FHEE_do_other_page_hooks_'.$this->page_slug, array());
626 626
         foreach ($registered_pages as $page) {
627 627
             //now let's setup the file name and class that should be present
628 628
             $classname = str_replace('.class.php', '', $page);
629 629
             //autoloaders should take care of loading file
630
-            if (! class_exists($classname)) {
630
+            if ( ! class_exists($classname)) {
631 631
                 $error_msg[] = sprintf(
632 632
                     esc_html__(
633 633
                         'Something went wrong with loading the %s admin hooks page.',
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
                                    ),
645 645
                                    $page,
646 646
                                    '<br />',
647
-                                   '<strong>' . $classname . '</strong>'
647
+                                   '<strong>'.$classname.'</strong>'
648 648
                                );
649 649
                 throw new EE_Error(implode('||', $error_msg));
650 650
             }
@@ -686,13 +686,13 @@  discard block
 block discarded – undo
686 686
         //load admin_notices - global, page class, and view specific
687 687
         add_action('admin_notices', array($this, 'admin_notices_global'), 5);
688 688
         add_action('admin_notices', array($this, 'admin_notices'), 10);
689
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
690
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
689
+        if (method_exists($this, 'admin_notices_'.$this->_current_view)) {
690
+            add_action('admin_notices', array($this, 'admin_notices_'.$this->_current_view), 15);
691 691
         }
692 692
         //load network admin_notices - global, page class, and view specific
693 693
         add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
694
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
695
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
694
+        if (method_exists($this, 'network_admin_notices_'.$this->_current_view)) {
695
+            add_action('network_admin_notices', array($this, 'network_admin_notices_'.$this->_current_view));
696 696
         }
697 697
         //this will save any per_page screen options if they are present
698 698
         $this->_set_per_page_screen_options();
@@ -705,8 +705,8 @@  discard block
 block discarded – undo
705 705
         //add screen options - global, page child class, and view specific
706 706
         $this->_add_global_screen_options();
707 707
         $this->_add_screen_options();
708
-        $add_screen_options  = "_add_screen_options_{$this->_current_view}";
709
-        if (method_exists($this, $add_screen_options )) {
708
+        $add_screen_options = "_add_screen_options_{$this->_current_view}";
709
+        if (method_exists($this, $add_screen_options)) {
710 710
             $this->{$add_screen_options};
711 711
         }
712 712
         //add help tab(s) and tours- set via page_config and qtips.
@@ -717,7 +717,7 @@  discard block
 block discarded – undo
717 717
         $this->_add_feature_pointers();
718 718
         $this->_add_global_feature_pointers();
719 719
         $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
720
-        if (method_exists($this, $add_feature_pointer )) {
720
+        if (method_exists($this, $add_feature_pointer)) {
721 721
             $this->{$add_feature_pointer};
722 722
         }
723 723
         //enqueue scripts/styles - global, page class, and view specific
@@ -819,7 +819,7 @@  discard block
 block discarded – undo
819 819
     protected function _verify_routes()
820 820
     {
821 821
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
822
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
822
+        if ( ! $this->_current_page && ! defined('DOING_AJAX')) {
823 823
             return false;
824 824
         }
825 825
         $this->_route = false;
@@ -831,7 +831,7 @@  discard block
 block discarded – undo
831 831
                 $this->_admin_page_title
832 832
             );
833 833
             // developer error msg
834
-            $error_msg .= '||' . $error_msg . esc_html__(
834
+            $error_msg .= '||'.$error_msg.esc_html__(
835 835
                 ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
836 836
                 'event_espresso'
837 837
             );
@@ -852,7 +852,7 @@  discard block
 block discarded – undo
852 852
                 $this->_admin_page_title
853 853
             );
854 854
             // developer error msg
855
-            $error_msg .= '||' . $error_msg . sprintf(
855
+            $error_msg .= '||'.$error_msg.sprintf(
856 856
                     esc_html__(
857 857
                         ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
858 858
                         'event_espresso'
@@ -862,7 +862,7 @@  discard block
 block discarded – undo
862 862
             throw new EE_Error($error_msg);
863 863
         }
864 864
         // and that a default route exists
865
-        if (! array_key_exists('default', $this->_page_routes)) {
865
+        if ( ! array_key_exists('default', $this->_page_routes)) {
866 866
             // user error msg
867 867
             $error_msg = sprintf(
868 868
                 esc_html__(
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
                 $this->_admin_page_title
873 873
             );
874 874
             // developer error msg
875
-            $error_msg .= '||' . $error_msg . esc_html__(
875
+            $error_msg .= '||'.$error_msg.esc_html__(
876 876
                 ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
877 877
                 'event_espresso'
878 878
             );
@@ -911,7 +911,7 @@  discard block
 block discarded – undo
911 911
             $this->_admin_page_title
912 912
         );
913 913
         // developer error msg
914
-        $error_msg .= '||' . $error_msg . sprintf(
914
+        $error_msg .= '||'.$error_msg.sprintf(
915 915
                 esc_html__(
916 916
                     ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
917 917
                     'event_espresso'
@@ -936,7 +936,7 @@  discard block
 block discarded – undo
936 936
     protected function _verify_nonce($nonce, $nonce_ref)
937 937
     {
938 938
         // verify nonce against expected value
939
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
939
+        if ( ! wp_verify_nonce($nonce, $nonce_ref)) {
940 940
             // these are not the droids you are looking for !!!
941 941
             $msg = sprintf(
942 942
                 esc_html__('%sNonce Fail.%s', 'event_espresso'),
@@ -944,7 +944,7 @@  discard block
 block discarded – undo
944 944
                 '</a>'
945 945
             );
946 946
             if (WP_DEBUG) {
947
-                $msg .= "\n  " . sprintf(
947
+                $msg .= "\n  ".sprintf(
948 948
                         esc_html__(
949 949
                             'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
950 950
                             'event_espresso'
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
                         __CLASS__
953 953
                     );
954 954
             }
955
-            if (! defined('DOING_AJAX')) {
955
+            if ( ! defined('DOING_AJAX')) {
956 956
                 wp_die($msg);
957 957
             } else {
958 958
                 EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
@@ -978,7 +978,7 @@  discard block
 block discarded – undo
978 978
      */
979 979
     protected function _route_admin_request()
980 980
     {
981
-        if (! $this->_is_UI_request) {
981
+        if ( ! $this->_is_UI_request) {
982 982
             $this->_verify_routes();
983 983
         }
984 984
         $nonce_check = isset($this->_route_config['require_nonce'])
@@ -1002,7 +1002,7 @@  discard block
 block discarded – undo
1002 1002
         $error_msg = '';
1003 1003
         // action right before calling route
1004 1004
         // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1005
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1005
+        if ( ! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1006 1006
             do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1007 1007
         }
1008 1008
         // right before calling the route, let's remove _wp_http_referer from the
@@ -1011,7 +1011,7 @@  discard block
 block discarded – undo
1011 1011
                 '_wp_http_referer',
1012 1012
                 wp_unslash($_SERVER['REQUEST_URI'])
1013 1013
         );
1014
-        if (! empty($func)) {
1014
+        if ( ! empty($func)) {
1015 1015
             if (is_array($func)) {
1016 1016
                 list($class, $method) = $func;
1017 1017
             } elseif (strpos($func, '::') !== false) {
@@ -1020,7 +1020,7 @@  discard block
 block discarded – undo
1020 1020
                 $class  = $this;
1021 1021
                 $method = $func;
1022 1022
             }
1023
-            if (! (is_object($class) && $class === $this)) {
1023
+            if ( ! (is_object($class) && $class === $this)) {
1024 1024
                 // send along this admin page object for access by addons.
1025 1025
                 $args['admin_page_object'] = $this;
1026 1026
             }
@@ -1061,7 +1061,7 @@  discard block
 block discarded – undo
1061 1061
                     $method
1062 1062
                 );
1063 1063
             }
1064
-            if (! empty($error_msg)) {
1064
+            if ( ! empty($error_msg)) {
1065 1065
                 throw new EE_Error($error_msg);
1066 1066
             }
1067 1067
         }
@@ -1147,7 +1147,7 @@  discard block
 block discarded – undo
1147 1147
                 if (strpos($key, 'nonce') !== false) {
1148 1148
                     continue;
1149 1149
                 }
1150
-                $args['wp_referer[' . $key . ']'] = $value;
1150
+                $args['wp_referer['.$key.']'] = $value;
1151 1151
             }
1152 1152
         }
1153 1153
         return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
@@ -1212,7 +1212,7 @@  discard block
 block discarded – undo
1212 1212
             // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213 1213
             if (is_array($config) && isset($config['help_sidebar'])) {
1214 1214
                 //check that the callback given is valid
1215
-                if (! method_exists($this, $config['help_sidebar'])) {
1215
+                if ( ! method_exists($this, $config['help_sidebar'])) {
1216 1216
                     throw new EE_Error(
1217 1217
                         sprintf(
1218 1218
                             esc_html__(
@@ -1225,7 +1225,7 @@  discard block
 block discarded – undo
1225 1225
                     );
1226 1226
                 }
1227 1227
                 $content = apply_filters(
1228
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1228
+                    'FHEE__'.get_class($this).'__add_help_tabs__help_sidebar',
1229 1229
                     $this->{$config['help_sidebar']}
1230 1230
                 );
1231 1231
                 $content .= $tour_buttons; //add help tour buttons.
@@ -1233,26 +1233,26 @@  discard block
 block discarded – undo
1233 1233
                 $this->_current_screen->set_help_sidebar($content);
1234 1234
             }
1235 1235
             //if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar.
1236
-            if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1236
+            if ( ! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1237 1237
                 $this->_current_screen->set_help_sidebar($tour_buttons);
1238 1238
             }
1239 1239
             //handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1240
-            if (! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1240
+            if ( ! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1241 1241
                 $_ht['id']      = $this->page_slug;
1242 1242
                 $_ht['title']   = esc_html__('Help Tours', 'event_espresso');
1243
-                $_ht['content'] = '<p>' . esc_html__(
1243
+                $_ht['content'] = '<p>'.esc_html__(
1244 1244
                         'The buttons to the right allow you to start/restart any help tours available for this page',
1245 1245
                         'event_espresso'
1246
-                    ) . '</p>';
1246
+                    ).'</p>';
1247 1247
                 $this->_current_screen->add_help_tab($_ht);
1248 1248
             }
1249
-            if (! isset($config['help_tabs'])) {
1249
+            if ( ! isset($config['help_tabs'])) {
1250 1250
                 return;
1251 1251
             } //no help tabs for this route
1252
-            foreach ((array)$config['help_tabs'] as $tab_id => $cfg) {
1252
+            foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1253 1253
                 //we're here so there ARE help tabs!
1254 1254
                 //make sure we've got what we need
1255
-                if (! isset($cfg['title'])) {
1255
+                if ( ! isset($cfg['title'])) {
1256 1256
                     throw new EE_Error(
1257 1257
                         esc_html__(
1258 1258
                             'The _page_config array is not set up properly for help tabs.  It is missing a title',
@@ -1260,7 +1260,7 @@  discard block
 block discarded – undo
1260 1260
                         )
1261 1261
                     );
1262 1262
                 }
1263
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1263
+                if ( ! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1264 1264
                     throw new EE_Error(
1265 1265
                         esc_html__(
1266 1266
                             'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
@@ -1269,11 +1269,11 @@  discard block
 block discarded – undo
1269 1269
                     );
1270 1270
                 }
1271 1271
                 //first priority goes to content.
1272
-                if (! empty($cfg['content'])) {
1272
+                if ( ! empty($cfg['content'])) {
1273 1273
                     $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1274 1274
                     //second priority goes to filename
1275
-                } elseif (! empty($cfg['filename'])) {
1276
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1275
+                } elseif ( ! empty($cfg['filename'])) {
1276
+                    $file_path = $this->_get_dir().'/help_tabs/'.$cfg['filename'].'.help_tab.php';
1277 1277
                     //it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1278 1278
                     $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1279 1279
                                                              . basename($this->_get_dir())
@@ -1281,7 +1281,7 @@  discard block
 block discarded – undo
1281 1281
                                                              . $cfg['filename']
1282 1282
                                                              . '.help_tab.php' : $file_path;
1283 1283
                     //if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1284
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1284
+                    if ( ! isset($cfg['callback']) && ! is_readable($file_path)) {
1285 1285
                         EE_Error::add_error(
1286 1286
                             sprintf(
1287 1287
                                 esc_html__(
@@ -1328,7 +1328,7 @@  discard block
 block discarded – undo
1328 1328
                     return;
1329 1329
                 }
1330 1330
                 //setup config array for help tab method
1331
-                $id  = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1331
+                $id  = $this->page_slug.'-'.$this->_req_action.'-'.$tab_id;
1332 1332
                 $_ht = array(
1333 1333
                     'id'       => $id,
1334 1334
                     'title'    => $cfg['title'],
@@ -1373,7 +1373,7 @@  discard block
 block discarded – undo
1373 1373
             }
1374 1374
             if (isset($config['help_tour'])) {
1375 1375
                 foreach ($config['help_tour'] as $tour) {
1376
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1376
+                    $file_path = $this->_get_dir().'/help_tours/'.$tour.'.class.php';
1377 1377
                     // let's see if we can get that file...
1378 1378
                     // if not its possible this is a decaf route not set in caffeinated
1379 1379
                     // so lets try and get the caffeinated equivalent
@@ -1383,7 +1383,7 @@  discard block
 block discarded – undo
1383 1383
                                                              . $tour
1384 1384
                                                              . '.class.php' : $file_path;
1385 1385
                     //if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1386
-                    if (! is_readable($file_path)) {
1386
+                    if ( ! is_readable($file_path)) {
1387 1387
                         EE_Error::add_error(
1388 1388
                             sprintf(
1389 1389
                                 esc_html__(
@@ -1400,12 +1400,12 @@  discard block
 block discarded – undo
1400 1400
                         return;
1401 1401
                     }
1402 1402
                     require_once $file_path;
1403
-                    if (! class_exists($tour)) {
1403
+                    if ( ! class_exists($tour)) {
1404 1404
                         $error_msg[] = sprintf(
1405 1405
                             esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1406 1406
                             $tour
1407 1407
                         );
1408
-                        $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
1408
+                        $error_msg[] = $error_msg[0]."\r\n".sprintf(
1409 1409
                                 esc_html__(
1410 1410
                                     'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1411 1411
                                     'event_espresso'
@@ -1428,7 +1428,7 @@  discard block
 block discarded – undo
1428 1428
                 $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1429 1429
             }
1430 1430
         }
1431
-        if (! empty($tours)) {
1431
+        if ( ! empty($tours)) {
1432 1432
             $this->_help_tour['tours'] = $tours;
1433 1433
         }
1434 1434
         // that's it!  Now that the $_help_tours property is set (or not)
@@ -1445,11 +1445,11 @@  discard block
 block discarded – undo
1445 1445
     protected function _add_qtips()
1446 1446
     {
1447 1447
         if (isset($this->_route_config['qtips'])) {
1448
-            $qtips = (array)$this->_route_config['qtips'];
1448
+            $qtips = (array) $this->_route_config['qtips'];
1449 1449
             //load qtip loader
1450 1450
             $path = array(
1451
-                $this->_get_dir() . '/qtips/',
1452
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1451
+                $this->_get_dir().'/qtips/',
1452
+                EE_ADMIN_PAGES.basename($this->_get_dir()).'/qtips/',
1453 1453
             );
1454 1454
             EEH_Qtip_Loader::instance()->register($qtips, $path);
1455 1455
         }
@@ -1488,11 +1488,11 @@  discard block
 block discarded – undo
1488 1488
                 // nav tab is only to appear when route requested.
1489 1489
                 continue;
1490 1490
             }
1491
-            if (! $this->check_user_access($slug, true)) {
1491
+            if ( ! $this->check_user_access($slug, true)) {
1492 1492
                 // no nav tab because current user does not have access.
1493 1493
                 continue;
1494 1494
             }
1495
-            $css_class              = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1495
+            $css_class              = isset($config['css_class']) ? $config['css_class'].' ' : '';
1496 1496
             $this->_nav_tabs[$slug] = array(
1497 1497
                 'url'       => isset($config['nav']['url'])
1498 1498
                     ? $config['nav']['url']
@@ -1505,7 +1505,7 @@  discard block
 block discarded – undo
1505 1505
                     : ucwords(
1506 1506
                         str_replace('_', ' ', $slug)
1507 1507
                     ),
1508
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1508
+                'css_class' => $this->_req_action === $slug ? $css_class.'nav-tab-active' : $css_class,
1509 1509
                 'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1510 1510
             );
1511 1511
             $i++;
@@ -1687,7 +1687,7 @@  discard block
 block discarded – undo
1687 1687
     public function admin_footer_global()
1688 1688
     {
1689 1689
         //dialog container for dialog helper
1690
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1690
+        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">'."\n";
1691 1691
         $d_cont .= '<div class="ee-notices"></div>';
1692 1692
         $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1693 1693
         $d_cont .= '</div>';
@@ -1697,7 +1697,7 @@  discard block
 block discarded – undo
1697 1697
             echo implode('<br />', $this->_help_tour[$this->_req_action]);
1698 1698
         }
1699 1699
         //current set timezone for timezone js
1700
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1700
+        echo '<span id="current_timezone" class="hidden">'.EEH_DTT_Helper::get_timezone().'</span>';
1701 1701
     }
1702 1702
 
1703 1703
 
@@ -1732,7 +1732,7 @@  discard block
 block discarded – undo
1732 1732
         //loop through the array and setup content
1733 1733
         foreach ($help_array as $trigger => $help) {
1734 1734
             //make sure the array is setup properly
1735
-            if (! isset($help['title']) || ! isset($help['content'])) {
1735
+            if ( ! isset($help['title']) || ! isset($help['content'])) {
1736 1736
                 throw new EE_Error(
1737 1737
                     esc_html__(
1738 1738
                         'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
@@ -1746,8 +1746,8 @@  discard block
 block discarded – undo
1746 1746
                 'help_popup_title'   => $help['title'],
1747 1747
                 'help_popup_content' => $help['content'],
1748 1748
             );
1749
-            $content       .= EEH_Template::display_template(
1750
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1749
+            $content .= EEH_Template::display_template(
1750
+                EE_ADMIN_TEMPLATE.'admin_help_popup.template.php',
1751 1751
                 $template_args,
1752 1752
                 true
1753 1753
             );
@@ -1770,15 +1770,15 @@  discard block
 block discarded – undo
1770 1770
     private function _get_help_content()
1771 1771
     {
1772 1772
         //what is the method we're looking for?
1773
-        $method_name = '_help_popup_content_' . $this->_req_action;
1773
+        $method_name = '_help_popup_content_'.$this->_req_action;
1774 1774
         //if method doesn't exist let's get out.
1775
-        if (! method_exists($this, $method_name)) {
1775
+        if ( ! method_exists($this, $method_name)) {
1776 1776
             return array();
1777 1777
         }
1778 1778
         //k we're good to go let's retrieve the help array
1779 1779
         $help_array = call_user_func(array($this, $method_name));
1780 1780
         //make sure we've got an array!
1781
-        if (! is_array($help_array)) {
1781
+        if ( ! is_array($help_array)) {
1782 1782
             throw new EE_Error(
1783 1783
                 esc_html__(
1784 1784
                     'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
@@ -1819,7 +1819,7 @@  discard block
 block discarded – undo
1819 1819
                     'event_espresso'
1820 1820
                 ),
1821 1821
             );
1822
-            $help_content            = $this->_set_help_popup_content($help_array, false);
1822
+            $help_content = $this->_set_help_popup_content($help_array, false);
1823 1823
         }
1824 1824
         //let's setup the trigger
1825 1825
         $content = '<a class="ee-dialog" href="?height='
@@ -1890,15 +1890,15 @@  discard block
 block discarded – undo
1890 1890
         // register all styles
1891 1891
         wp_register_style(
1892 1892
             'espresso-ui-theme',
1893
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1893
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1894 1894
             array(),
1895 1895
             EVENT_ESPRESSO_VERSION
1896 1896
         );
1897
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1897
+        wp_register_style('ee-admin-css', EE_ADMIN_URL.'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1898 1898
         //helpers styles
1899 1899
         wp_register_style(
1900 1900
             'ee-text-links',
1901
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1901
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.css',
1902 1902
             array(),
1903 1903
             EVENT_ESPRESSO_VERSION
1904 1904
         );
@@ -1906,21 +1906,21 @@  discard block
 block discarded – undo
1906 1906
         //register all scripts
1907 1907
         wp_register_script(
1908 1908
             'ee-dialog',
1909
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1909
+            EE_ADMIN_URL.'assets/ee-dialog-helper.js',
1910 1910
             array('jquery', 'jquery-ui-draggable'),
1911 1911
             EVENT_ESPRESSO_VERSION,
1912 1912
             true
1913 1913
         );
1914 1914
         wp_register_script(
1915 1915
             'ee_admin_js',
1916
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1916
+            EE_ADMIN_URL.'assets/ee-admin-page.js',
1917 1917
             array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1918 1918
             EVENT_ESPRESSO_VERSION,
1919 1919
             true
1920 1920
         );
1921 1921
         wp_register_script(
1922 1922
             'jquery-ui-timepicker-addon',
1923
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1923
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery-ui-timepicker-addon.js',
1924 1924
             array('jquery-ui-datepicker', 'jquery-ui-slider'),
1925 1925
             EVENT_ESPRESSO_VERSION,
1926 1926
             true
@@ -1929,7 +1929,7 @@  discard block
 block discarded – undo
1929 1929
         //script for sorting tables
1930 1930
         wp_register_script(
1931 1931
             'espresso_ajax_table_sorting',
1932
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1932
+            EE_ADMIN_URL.'assets/espresso_ajax_table_sorting.js',
1933 1933
             array('ee_admin_js', 'jquery-ui-sortable'),
1934 1934
             EVENT_ESPRESSO_VERSION,
1935 1935
             true
@@ -1937,7 +1937,7 @@  discard block
 block discarded – undo
1937 1937
         //script for parsing uri's
1938 1938
         wp_register_script(
1939 1939
             'ee-parse-uri',
1940
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1940
+            EE_GLOBAL_ASSETS_URL.'scripts/parseuri.js',
1941 1941
             array(),
1942 1942
             EVENT_ESPRESSO_VERSION,
1943 1943
             true
@@ -1945,7 +1945,7 @@  discard block
 block discarded – undo
1945 1945
         //and parsing associative serialized form elements
1946 1946
         wp_register_script(
1947 1947
             'ee-serialize-full-array',
1948
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1948
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.serializefullarray.js',
1949 1949
             array('jquery'),
1950 1950
             EVENT_ESPRESSO_VERSION,
1951 1951
             true
@@ -1953,28 +1953,28 @@  discard block
 block discarded – undo
1953 1953
         //helpers scripts
1954 1954
         wp_register_script(
1955 1955
             'ee-text-links',
1956
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1956
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.js',
1957 1957
             array('jquery'),
1958 1958
             EVENT_ESPRESSO_VERSION,
1959 1959
             true
1960 1960
         );
1961 1961
         wp_register_script(
1962 1962
             'ee-moment-core',
1963
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1963
+            EE_THIRD_PARTY_URL.'moment/moment-with-locales.min.js',
1964 1964
             array(),
1965 1965
             EVENT_ESPRESSO_VERSION,
1966 1966
             true
1967 1967
         );
1968 1968
         wp_register_script(
1969 1969
             'ee-moment',
1970
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1970
+            EE_THIRD_PARTY_URL.'moment/moment-timezone-with-data.min.js',
1971 1971
             array('ee-moment-core'),
1972 1972
             EVENT_ESPRESSO_VERSION,
1973 1973
             true
1974 1974
         );
1975 1975
         wp_register_script(
1976 1976
             'ee-datepicker',
1977
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1977
+            EE_ADMIN_URL.'assets/ee-datepicker.js',
1978 1978
             array('jquery-ui-timepicker-addon', 'ee-moment'),
1979 1979
             EVENT_ESPRESSO_VERSION,
1980 1980
             true
@@ -2009,11 +2009,11 @@  discard block
 block discarded – undo
2009 2009
         /**
2010 2010
          * help tour stuff
2011 2011
          */
2012
-        if (! empty($this->_help_tour)) {
2012
+        if ( ! empty($this->_help_tour)) {
2013 2013
             //register the js for kicking things off
2014 2014
             wp_enqueue_script(
2015 2015
                 'ee-help-tour',
2016
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2016
+                EE_ADMIN_URL.'assets/ee-help-tour.js',
2017 2017
                 array('jquery-joyride'),
2018 2018
                 EVENT_ESPRESSO_VERSION,
2019 2019
                 true
@@ -2111,11 +2111,11 @@  discard block
 block discarded – undo
2111 2111
     protected function _set_list_table()
2112 2112
     {
2113 2113
         //first is this a list_table view?
2114
-        if (! isset($this->_route_config['list_table'])) {
2114
+        if ( ! isset($this->_route_config['list_table'])) {
2115 2115
             return;
2116 2116
         } //not a list_table view so get out.
2117 2117
         // list table functions are per view specific (because some admin pages might have more than one listtable!)
2118
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2118
+        $list_table_view = '_set_list_table_views_'.$this->_req_action;
2119 2119
         if ($this->{$list_table_view} === false) {
2120 2120
             //user error msg
2121 2121
             $error_msg = esc_html__(
@@ -2123,7 +2123,7 @@  discard block
 block discarded – undo
2123 2123
                 'event_espresso'
2124 2124
             );
2125 2125
             //developer error msg
2126
-            $error_msg .= '||' . sprintf(
2126
+            $error_msg .= '||'.sprintf(
2127 2127
                     esc_html__(
2128 2128
                         'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2129 2129
                         'event_espresso'
@@ -2135,10 +2135,10 @@  discard block
 block discarded – undo
2135 2135
         }
2136 2136
         //let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2137 2137
         $this->_views = apply_filters(
2138
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2138
+            'FHEE_list_table_views_'.$this->page_slug.'_'.$this->_req_action,
2139 2139
             $this->_views
2140 2140
         );
2141
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2141
+        $this->_views = apply_filters('FHEE_list_table_views_'.$this->page_slug, $this->_views);
2142 2142
         $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2143 2143
         $this->_set_list_table_view();
2144 2144
         $this->_set_list_table_object();
@@ -2155,7 +2155,7 @@  discard block
 block discarded – undo
2155 2155
     {
2156 2156
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2157 2157
         // looking at active items or dumpster diving ?
2158
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2158
+        if ( ! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2159 2159
             $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2160 2160
         } else {
2161 2161
             $this->_view = sanitize_key($this->_req_data['status']);
@@ -2173,7 +2173,7 @@  discard block
 block discarded – undo
2173 2173
     protected function _set_list_table_object()
2174 2174
     {
2175 2175
         if (isset($this->_route_config['list_table'])) {
2176
-            if (! class_exists($this->_route_config['list_table'])) {
2176
+            if ( ! class_exists($this->_route_config['list_table'])) {
2177 2177
                 throw new EE_Error(
2178 2178
                     sprintf(
2179 2179
                         esc_html__(
@@ -2212,7 +2212,7 @@  discard block
 block discarded – undo
2212 2212
             // check for current view
2213 2213
             $this->_views[$key]['class']               = $this->_view === $view['slug'] ? 'current' : '';
2214 2214
             $query_args['action']                      = $this->_req_action;
2215
-            $query_args[$this->_req_action . '_nonce'] = wp_create_nonce($query_args['action'] . '_nonce');
2215
+            $query_args[$this->_req_action.'_nonce'] = wp_create_nonce($query_args['action'].'_nonce');
2216 2216
             $query_args['status']                      = $view['slug'];
2217 2217
             //merge any other arguments sent in.
2218 2218
             if (isset($extra_query_args[$view['slug']])) {
@@ -2238,7 +2238,7 @@  discard block
 block discarded – undo
2238 2238
     {
2239 2239
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2240 2240
         $values   = array(10, 25, 50, 100);
2241
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2241
+        $per_page = ( ! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2242 2242
         if ($max_entries) {
2243 2243
             $values[] = $max_entries;
2244 2244
             sort($values);
@@ -2250,14 +2250,14 @@  discard block
 block discarded – undo
2250 2250
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2251 2251
         foreach ($values as $value) {
2252 2252
             if ($value < $max_entries) {
2253
-                $selected                  = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2253
+                $selected = $value === $per_page ? ' selected="'.$per_page.'"' : '';
2254 2254
                 $entries_per_page_dropdown .= '
2255
-						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2255
+						<option value="' . $value.'"'.$selected.'>'.$value.'&nbsp;&nbsp;</option>';
2256 2256
             }
2257 2257
         }
2258
-        $selected                  = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2258
+        $selected = $max_entries === $per_page ? ' selected="'.$per_page.'"' : '';
2259 2259
         $entries_per_page_dropdown .= '
2260
-						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2260
+						<option value="' . $max_entries.'"'.$selected.'>All&nbsp;&nbsp;</option>';
2261 2261
         $entries_per_page_dropdown .= '
2262 2262
 					</select>
2263 2263
 					entries
@@ -2282,7 +2282,7 @@  discard block
 block discarded – undo
2282 2282
             empty($this->_search_btn_label) ? $this->page_label
2283 2283
                 : $this->_search_btn_label
2284 2284
         );
2285
-        $this->_template_args['search']['callback']  = 'search_' . $this->page_slug;
2285
+        $this->_template_args['search']['callback'] = 'search_'.$this->page_slug;
2286 2286
     }
2287 2287
 
2288 2288
 
@@ -2327,7 +2327,7 @@  discard block
 block discarded – undo
2327 2327
                             'event_espresso'
2328 2328
                     );
2329 2329
                     // developer error msg
2330
-                    $error_msg .= '||' . sprintf(
2330
+                    $error_msg .= '||'.sprintf(
2331 2331
                             esc_html__(
2332 2332
                                 'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2333 2333
                                 'event_espresso'
@@ -2360,17 +2360,17 @@  discard block
 block discarded – undo
2360 2360
             add_screen_option(
2361 2361
                 'layout_columns',
2362 2362
                 array(
2363
-                    'max'     => (int)$this->_route_config['columns'][0],
2364
-                    'default' => (int)$this->_route_config['columns'][1],
2363
+                    'max'     => (int) $this->_route_config['columns'][0],
2364
+                    'default' => (int) $this->_route_config['columns'][1],
2365 2365
                 )
2366 2366
             );
2367 2367
             $this->_template_args['num_columns']                 = $this->_route_config['columns'][0];
2368 2368
             $screen_id                                           = $this->_current_screen->id;
2369
-            $screen_columns                                      = (int)get_user_option("screen_layout_{$screen_id}");
2369
+            $screen_columns                                      = (int) get_user_option("screen_layout_{$screen_id}");
2370 2370
             $total_columns                                       = ! empty($screen_columns)
2371 2371
                 ? $screen_columns
2372 2372
                 : $this->_route_config['columns'][1];
2373
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2373
+            $this->_template_args['current_screen_widget_class'] = 'columns-'.$total_columns;
2374 2374
             $this->_template_args['current_page']                = $this->_wp_page_slug;
2375 2375
             $this->_template_args['screen']                      = $this->_current_screen;
2376 2376
             $this->_column_template_path                         = EE_ADMIN_TEMPLATE
@@ -2416,7 +2416,7 @@  discard block
 block discarded – undo
2416 2416
      */
2417 2417
     protected function _espresso_ratings_request()
2418 2418
     {
2419
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2419
+        if ( ! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2420 2420
             return;
2421 2421
         }
2422 2422
         $ratings_box_title = apply_filters(
@@ -2445,7 +2445,7 @@  discard block
 block discarded – undo
2445 2445
     public function espresso_ratings_request()
2446 2446
     {
2447 2447
         EEH_Template::display_template(
2448
-            EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php',
2448
+            EE_ADMIN_TEMPLATE.'espresso_ratings_request_content.template.php',
2449 2449
                 array()
2450 2450
         );
2451 2451
     }
@@ -2454,22 +2454,22 @@  discard block
 block discarded – undo
2454 2454
 
2455 2455
     public static function cached_rss_display($rss_id, $url)
2456 2456
     {
2457
-        $loading    = '<p class="widget-loading hide-if-no-js">'
2457
+        $loading = '<p class="widget-loading hide-if-no-js">'
2458 2458
                       . __('Loading&#8230;')
2459 2459
                       . '</p><p class="hide-if-js">'
2460 2460
                       . esc_html__('This widget requires JavaScript.')
2461 2461
                       . '</p>';
2462
-        $pre        = '<div class="espresso-rss-display">' . "\n\t";
2463
-        $pre        .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2464
-        $post       = '</div>' . "\n";
2465
-        $cache_key  = 'ee_rss_' . md5($rss_id);
2462
+        $pre        = '<div class="espresso-rss-display">'."\n\t";
2463
+        $pre .= '<span id="'.$rss_id.'_url" class="hidden">'.$url.'</span>';
2464
+        $post       = '</div>'."\n";
2465
+        $cache_key  = 'ee_rss_'.md5($rss_id);
2466 2466
         $output = get_transient($cache_key);
2467 2467
         if ($output !== false) {
2468
-            echo $pre . $output . $post;
2468
+            echo $pre.$output.$post;
2469 2469
             return true;
2470 2470
         }
2471
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2472
-            echo $pre . $loading . $post;
2471
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
2472
+            echo $pre.$loading.$post;
2473 2473
             return false;
2474 2474
         }
2475 2475
         ob_start();
@@ -2541,7 +2541,7 @@  discard block
 block discarded – undo
2541 2541
     public function espresso_sponsors_post_box()
2542 2542
     {
2543 2543
         EEH_Template::display_template(
2544
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2544
+            EE_ADMIN_TEMPLATE.'admin_general_metabox_contents_espresso_sponsors.template.php'
2545 2545
         );
2546 2546
     }
2547 2547
 
@@ -2549,11 +2549,11 @@  discard block
 block discarded – undo
2549 2549
 
2550 2550
     private function _publish_post_box()
2551 2551
     {
2552
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2552
+        $meta_box_ref = 'espresso_'.$this->page_slug.'_editor_overview';
2553 2553
         // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2554 2554
         // then we'll use that for the metabox label.
2555 2555
         // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2556
-        if (! empty($this->_labels['publishbox'])) {
2556
+        if ( ! empty($this->_labels['publishbox'])) {
2557 2557
             $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action]
2558 2558
                 : $this->_labels['publishbox'];
2559 2559
         } else {
@@ -2584,7 +2584,7 @@  discard block
 block discarded – undo
2584 2584
             ? $this->_template_args['publish_box_extra_content']
2585 2585
             : '';
2586 2586
         echo EEH_Template::display_template(
2587
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2587
+            EE_ADMIN_TEMPLATE.'admin_details_publish_metabox.template.php',
2588 2588
             $this->_template_args,
2589 2589
             true
2590 2590
         );
@@ -2678,12 +2678,12 @@  discard block
 block discarded – undo
2678 2678
             );
2679 2679
         }
2680 2680
         $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2681
-        if (! empty($name) && ! empty($id)) {
2681
+        if ( ! empty($name) && ! empty($id)) {
2682 2682
             $hidden_field_arr[$name] = array(
2683 2683
                 'type'  => 'hidden',
2684 2684
                 'value' => $id,
2685 2685
             );
2686
-            $hf                      = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2686
+            $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2687 2687
         } else {
2688 2688
             $hf = '';
2689 2689
         }
@@ -2797,7 +2797,7 @@  discard block
 block discarded – undo
2797 2797
         }
2798 2798
         //if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2799 2799
         $call_back_func = $create_func
2800
-            ? function ($post, $metabox)
2800
+            ? function($post, $metabox)
2801 2801
             {
2802 2802
                 do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2803 2803
                 echo EEH_Template::display_template(
@@ -2808,7 +2808,7 @@  discard block
 block discarded – undo
2808 2808
             }
2809 2809
             : $callback;
2810 2810
         add_meta_box(
2811
-            str_replace('_', '-', $action) . '-mbox',
2811
+            str_replace('_', '-', $action).'-mbox',
2812 2812
             $title,
2813 2813
             $call_back_func,
2814 2814
             $this->_wp_page_slug,
@@ -2905,9 +2905,9 @@  discard block
 block discarded – undo
2905 2905
             : 'espresso-default-admin';
2906 2906
         $template_path                                     = $sidebar
2907 2907
             ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2908
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2908
+            : EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar.template.php';
2909 2909
         if (defined('DOING_AJAX') && DOING_AJAX) {
2910
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2910
+            $template_path = EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar_ajax.template.php';
2911 2911
         }
2912 2912
         $template_path                                     = ! empty($this->_column_template_path)
2913 2913
             ? $this->_column_template_path : $template_path;
@@ -2948,11 +2948,11 @@  discard block
 block discarded – undo
2948 2948
     public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2949 2949
     {
2950 2950
         //let's generate a default preview action button if there isn't one already present.
2951
-        $this->_labels['buttons']['buy_now']           = esc_html__(
2951
+        $this->_labels['buttons']['buy_now'] = esc_html__(
2952 2952
             'Upgrade to Event Espresso 4 Right Now',
2953 2953
             'event_espresso'
2954 2954
         );
2955
-        $buy_now_url                                   = add_query_arg(
2955
+        $buy_now_url = add_query_arg(
2956 2956
             array(
2957 2957
                 'ee_ver'       => 'ee4',
2958 2958
                 'utm_source'   => 'ee4_plugin_admin',
@@ -2972,8 +2972,8 @@  discard block
 block discarded – undo
2972 2972
                 true
2973 2973
             )
2974 2974
             : $this->_template_args['preview_action_button'];
2975
-        $this->_template_args['admin_page_content']    = EEH_Template::display_template(
2976
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2975
+        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2976
+            EE_ADMIN_TEMPLATE.'admin_caf_full_page_preview.template.php',
2977 2977
             $this->_template_args,
2978 2978
             true
2979 2979
         );
@@ -3025,7 +3025,7 @@  discard block
 block discarded – undo
3025 3025
         //setup search attributes
3026 3026
         $this->_set_search_attributes();
3027 3027
         $this->_template_args['current_page']     = $this->_wp_page_slug;
3028
-        $template_path                            = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3028
+        $template_path                            = EE_ADMIN_TEMPLATE.'admin_list_wrapper.template.php';
3029 3029
         $this->_template_args['table_url']        = defined('DOING_AJAX')
3030 3030
             ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3031 3031
             : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
@@ -3033,10 +3033,10 @@  discard block
 block discarded – undo
3033 3033
         $this->_template_args['current_route']    = $this->_req_action;
3034 3034
         $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3035 3035
         $ajax_sorting_callback                    = $this->_list_table_object->get_ajax_sorting_callback();
3036
-        if (! empty($ajax_sorting_callback)) {
3036
+        if ( ! empty($ajax_sorting_callback)) {
3037 3037
             $sortable_list_table_form_fields = wp_nonce_field(
3038
-                $ajax_sorting_callback . '_nonce',
3039
-                $ajax_sorting_callback . '_nonce',
3038
+                $ajax_sorting_callback.'_nonce',
3039
+                $ajax_sorting_callback.'_nonce',
3040 3040
                 false,
3041 3041
                 false
3042 3042
             );
@@ -3055,19 +3055,19 @@  discard block
 block discarded – undo
3055 3055
         $hidden_form_fields                                      = isset($this->_template_args['list_table_hidden_fields'])
3056 3056
             ? $this->_template_args['list_table_hidden_fields']
3057 3057
             : '';
3058
-        $nonce_ref                                               = $this->_req_action . '_nonce';
3059
-        $hidden_form_fields                                      .= '<input type="hidden" name="'
3058
+        $nonce_ref                                               = $this->_req_action.'_nonce';
3059
+        $hidden_form_fields .= '<input type="hidden" name="'
3060 3060
                                                                     . $nonce_ref
3061 3061
                                                                     . '" value="'
3062 3062
                                                                     . wp_create_nonce($nonce_ref)
3063 3063
                                                                     . '">';
3064
-        $this->_template_args['list_table_hidden_fields']        = $hidden_form_fields;
3064
+        $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3065 3065
         //display message about search results?
3066 3066
         $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3067
-            ? '<p class="ee-search-results">' . sprintf(
3067
+            ? '<p class="ee-search-results">'.sprintf(
3068 3068
                 esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3069 3069
                 trim($this->_req_data['s'], '%')
3070
-            ) . '</p>'
3070
+            ).'</p>'
3071 3071
             : '';
3072 3072
         // filter before_list_table template arg
3073 3073
         $this->_template_args['before_list_table'] = apply_filters(
@@ -3082,9 +3082,9 @@  discard block
 block discarded – undo
3082 3082
         // but would not be backwards compatible, so we have to add a new filter
3083 3083
         $this->_template_args['before_list_table'] = implode(
3084 3084
             " \n",
3085
-            (array)apply_filters(
3085
+            (array) apply_filters(
3086 3086
                 'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3087
-                (array)$this->_template_args['before_list_table'],
3087
+                (array) $this->_template_args['before_list_table'],
3088 3088
                 $this->page_slug,
3089 3089
                 $this->_req_data,
3090 3090
                 $this->_req_action
@@ -3101,11 +3101,11 @@  discard block
 block discarded – undo
3101 3101
         // convert to array and filter again
3102 3102
         // arrays are easier to inject new items in a specific location,
3103 3103
         // but would not be backwards compatible, so we have to add a new filter
3104
-        $this->_template_args['after_list_table']   = implode(
3104
+        $this->_template_args['after_list_table'] = implode(
3105 3105
             " \n",
3106
-            (array)apply_filters(
3106
+            (array) apply_filters(
3107 3107
                 'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3108
-                (array)$this->_template_args['after_list_table'],
3108
+                (array) $this->_template_args['after_list_table'],
3109 3109
                 $this->page_slug,
3110 3110
                 $this->_req_data,
3111 3111
                 $this->_req_action
@@ -3145,11 +3145,11 @@  discard block
 block discarded – undo
3145 3145
     {
3146 3146
         $this->_template_args['items'] = apply_filters(
3147 3147
             'FHEE__EE_Admin_Page___display_legend__items',
3148
-            (array)$items,
3148
+            (array) $items,
3149 3149
             $this
3150 3150
         );
3151 3151
         return EEH_Template::display_template(
3152
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3152
+            EE_ADMIN_TEMPLATE.'admin_details_legend.template.php',
3153 3153
             $this->_template_args,
3154 3154
             true
3155 3155
         );
@@ -3259,13 +3259,13 @@  discard block
 block discarded – undo
3259 3259
                 ? $this->_template_args['before_admin_page_content']
3260 3260
                 : ''
3261 3261
         );
3262
-        $this->_template_args['after_admin_page_content']  = apply_filters(
3262
+        $this->_template_args['after_admin_page_content'] = apply_filters(
3263 3263
             "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3264 3264
             isset($this->_template_args['after_admin_page_content'])
3265 3265
                 ? $this->_template_args['after_admin_page_content']
3266 3266
                 : ''
3267 3267
         );
3268
-        $this->_template_args['after_admin_page_content']  .= $this->_set_help_popup_content();
3268
+        $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3269 3269
         // load settings page wrapper template
3270 3270
         $template_path = ! defined('DOING_AJAX')
3271 3271
             ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
@@ -3360,8 +3360,8 @@  discard block
 block discarded – undo
3360 3360
     protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3361 3361
     {
3362 3362
         //make sure $text and $actions are in an array
3363
-        $text          = (array)$text;
3364
-        $actions       = (array)$actions;
3363
+        $text          = (array) $text;
3364
+        $actions       = (array) $actions;
3365 3365
         $referrer_url  = empty($referrer)
3366 3366
             ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3367 3367
               . $_SERVER['REQUEST_URI']
@@ -3369,7 +3369,7 @@  discard block
 block discarded – undo
3369 3369
             : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3370 3370
               . $referrer
3371 3371
               . '" />';
3372
-        $button_text   = ! empty($text)
3372
+        $button_text = ! empty($text)
3373 3373
             ? $text
3374 3374
             : array(
3375 3375
                 esc_html__('Save', 'event_espresso'),
@@ -3379,17 +3379,17 @@  discard block
 block discarded – undo
3379 3379
         //add in a hidden index for the current page (so save and close redirects properly)
3380 3380
         $this->_template_args['save_buttons'] = $referrer_url;
3381 3381
         foreach ($button_text as $key => $button) {
3382
-            $ref                                  = $default_names[$key];
3382
+            $ref = $default_names[$key];
3383 3383
             $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3384 3384
                                                      . $ref
3385 3385
                                                      . '" value="'
3386 3386
                                                      . $button
3387 3387
                                                      . '" name="'
3388
-                                                     . (! empty($actions) ? $actions[$key] : $ref)
3388
+                                                     . ( ! empty($actions) ? $actions[$key] : $ref)
3389 3389
                                                      . '" id="'
3390
-                                                     . $this->_current_view . '_' . $ref
3390
+                                                     . $this->_current_view.'_'.$ref
3391 3391
                                                      . '" />';
3392
-            if (! $both) {
3392
+            if ( ! $both) {
3393 3393
                 break;
3394 3394
             }
3395 3395
         }
@@ -3426,12 +3426,12 @@  discard block
 block discarded – undo
3426 3426
                 'An error occurred. No action was set for this page\'s form.',
3427 3427
                 'event_espresso'
3428 3428
             );
3429
-            $dev_msg  = $user_msg . "\n" . sprintf(
3429
+            $dev_msg = $user_msg."\n".sprintf(
3430 3430
                     esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3431 3431
                     __FUNCTION__,
3432 3432
                     __CLASS__
3433 3433
                 );
3434
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3434
+            EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__);
3435 3435
         }
3436 3436
         // open form
3437 3437
         $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
@@ -3440,9 +3440,9 @@  discard block
 block discarded – undo
3440 3440
                                                              . $route
3441 3441
                                                              . '_event_form" >';
3442 3442
         // add nonce
3443
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3443
+        $nonce = wp_nonce_field($route.'_nonce', $route.'_nonce', false, false);
3444 3444
         //		$nonce = wp_nonce_field( $route . '_nonce', '_wpnonce', FALSE, FALSE );
3445
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3445
+        $this->_template_args['before_admin_page_content'] .= "\n\t".$nonce;
3446 3446
         // add REQUIRED form action
3447 3447
         $hidden_fields = array(
3448 3448
             'action' => array('type' => 'hidden', 'value' => $route),
@@ -3454,8 +3454,8 @@  discard block
 block discarded – undo
3454 3454
         // generate form fields
3455 3455
         $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456 3456
         // add fields to form
3457
-        foreach ((array)$form_fields as $field_name => $form_field) {
3458
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3457
+        foreach ((array) $form_fields as $field_name => $form_field) {
3458
+            $this->_template_args['before_admin_page_content'] .= "\n\t".$form_field['field'];
3459 3459
         }
3460 3460
         // close form
3461 3461
         $this->_template_args['after_admin_page_content'] = '</form>';
@@ -3523,10 +3523,10 @@  discard block
 block discarded – undo
3523 3523
         $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3524 3524
         $notices      = EE_Error::get_notices(false);
3525 3525
         // overwrite default success messages //BUT ONLY if overwrite not overridden
3526
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3526
+        if ( ! $override_overwrite || ! empty($notices['errors'])) {
3527 3527
             EE_Error::overwrite_success();
3528 3528
         }
3529
-        if (! empty($what) && ! empty($action_desc)  && empty($notices['errors'])) {
3529
+        if ( ! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3530 3530
             // how many records affected ? more than one record ? or just one ?
3531 3531
             if ($success > 1) {
3532 3532
                 // set plural msg
@@ -3555,7 +3555,7 @@  discard block
 block discarded – undo
3555 3555
             }
3556 3556
         }
3557 3557
         // check that $query_args isn't something crazy
3558
-        if (! is_array($query_args)) {
3558
+        if ( ! is_array($query_args)) {
3559 3559
             $query_args = array();
3560 3560
         }
3561 3561
         /**
@@ -3580,12 +3580,12 @@  discard block
 block discarded – undo
3580 3580
             $redirect_url = admin_url('admin.php');
3581 3581
         }
3582 3582
         //merge any default query_args set in _default_route_query_args property
3583
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3583
+        if ( ! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3584 3584
             $args_to_merge = array();
3585 3585
             foreach ($this->_default_route_query_args as $query_param => $query_value) {
3586 3586
                 //is there a wp_referer array in our _default_route_query_args property?
3587 3587
                 if ($query_param === 'wp_referer') {
3588
-                    $query_value = (array)$query_value;
3588
+                    $query_value = (array) $query_value;
3589 3589
                     foreach ($query_value as $reference => $value) {
3590 3590
                         if (strpos($reference, 'nonce') !== false) {
3591 3591
                             continue;
@@ -3612,19 +3612,19 @@  discard block
 block discarded – undo
3612 3612
         if (isset($query_args['action'])) {
3613 3613
             // manually generate wp_nonce and merge that with the query vars
3614 3614
             // becuz the wp_nonce_url function wrecks havoc on some vars
3615
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3615
+            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'].'_nonce');
3616 3616
         }
3617 3617
         // we're adding some hooks and filters in here for processing any things just before redirects
3618 3618
         // (example: an admin page has done an insert or update and we want to run something after that).
3619
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3619
+        do_action('AHEE_redirect_'.$classname.$this->_req_action, $query_args);
3620 3620
         $redirect_url = apply_filters(
3621
-            'FHEE_redirect_' . $classname . $this->_req_action,
3621
+            'FHEE_redirect_'.$classname.$this->_req_action,
3622 3622
             self::add_query_args_and_nonce($query_args, $redirect_url),
3623 3623
             $query_args
3624 3624
         );
3625 3625
         // check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3626 3626
         if (defined('DOING_AJAX')) {
3627
-            $default_data                    = array(
3627
+            $default_data = array(
3628 3628
                 'close'        => true,
3629 3629
                 'redirect_url' => $redirect_url,
3630 3630
                 'where'        => 'main',
@@ -3672,7 +3672,7 @@  discard block
 block discarded – undo
3672 3672
         }
3673 3673
         $this->_template_args['notices'] = EE_Error::get_notices();
3674 3674
         //IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3675
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3675
+        if ( ! defined('DOING_AJAX') || $sticky_notices) {
3676 3676
             $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3677 3677
             $this->_add_transient(
3678 3678
                 $route,
@@ -3724,7 +3724,7 @@  discard block
 block discarded – undo
3724 3724
                 )
3725 3725
             );
3726 3726
         }
3727
-        if (! isset($this->_labels['buttons'][$type])) {
3727
+        if ( ! isset($this->_labels['buttons'][$type])) {
3728 3728
             throw new EE_Error(
3729 3729
                 sprintf(
3730 3730
                     __(
@@ -3737,7 +3737,7 @@  discard block
 block discarded – undo
3737 3737
         }
3738 3738
         //finally check user access for this button.
3739 3739
         $has_access = $this->check_user_access($action, true);
3740
-        if (! $has_access) {
3740
+        if ( ! $has_access) {
3741 3741
             return '';
3742 3742
         }
3743 3743
         $_base_url  = ! $base_url ? $this->_admin_base_url : $base_url;
@@ -3745,7 +3745,7 @@  discard block
 block discarded – undo
3745 3745
             'action' => $action,
3746 3746
         );
3747 3747
         //merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3748
-        if (! empty($extra_request)) {
3748
+        if ( ! empty($extra_request)) {
3749 3749
             $query_args = array_merge($extra_request, $query_args);
3750 3750
         }
3751 3751
         $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
@@ -3769,7 +3769,7 @@  discard block
 block discarded – undo
3769 3769
         $args   = array(
3770 3770
             'label'   => $this->_admin_page_title,
3771 3771
             'default' => 10,
3772
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3772
+            'option'  => $this->_current_page.'_'.$this->_current_view.'_per_page',
3773 3773
         );
3774 3774
         //ONLY add the screen option if the user has access to it.
3775 3775
         if ($this->check_user_access($this->_current_view, true)) {
@@ -3791,7 +3791,7 @@  discard block
 block discarded – undo
3791 3791
     {
3792 3792
         if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3793 3793
             check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3794
-            if (! $user = wp_get_current_user()) {
3794
+            if ( ! $user = wp_get_current_user()) {
3795 3795
                 return;
3796 3796
             }
3797 3797
             $option = $_POST['wp_screen_options']['option'];
@@ -3802,8 +3802,8 @@  discard block
 block discarded – undo
3802 3802
             $map_option = $option;
3803 3803
             $option     = str_replace('-', '_', $option);
3804 3804
             switch ($map_option) {
3805
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3806
-                    $value = (int)$value;
3805
+                case $this->_current_page.'_'.$this->_current_view.'_per_page':
3806
+                    $value = (int) $value;
3807 3807
                     if ($value < 1 || $value > 999) {
3808 3808
                         return;
3809 3809
                     }
@@ -3835,7 +3835,7 @@  discard block
 block discarded – undo
3835 3835
      */
3836 3836
     public function set_template_args($data)
3837 3837
     {
3838
-        $this->_template_args = array_merge($this->_template_args, (array)$data);
3838
+        $this->_template_args = array_merge($this->_template_args, (array) $data);
3839 3839
     }
3840 3840
 
3841 3841
 
@@ -3855,20 +3855,20 @@  discard block
 block discarded – undo
3855 3855
     protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3856 3856
     {
3857 3857
         $user_id = get_current_user_id();
3858
-        if (! $skip_route_verify) {
3858
+        if ( ! $skip_route_verify) {
3859 3859
             $this->_verify_route($route);
3860 3860
         }
3861 3861
         //now let's set the string for what kind of transient we're setting
3862 3862
         $transient = $notices
3863
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3864
-            : 'rte_tx_' . $route . '_' . $user_id;
3863
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3864
+            : 'rte_tx_'.$route.'_'.$user_id;
3865 3865
         $data      = $notices ? array('notices' => $data) : $data;
3866 3866
         //is there already a transient for this route?  If there is then let's ADD to that transient
3867 3867
         $existing = is_multisite() && is_network_admin()
3868 3868
             ? get_site_transient($transient)
3869 3869
             : get_transient($transient);
3870 3870
         if ($existing) {
3871
-            $data = array_merge((array)$data, (array)$existing);
3871
+            $data = array_merge((array) $data, (array) $existing);
3872 3872
         }
3873 3873
         if (is_multisite() && is_network_admin()) {
3874 3874
             set_site_transient($transient, $data, 8);
@@ -3891,8 +3891,8 @@  discard block
 block discarded – undo
3891 3891
         $user_id   = get_current_user_id();
3892 3892
         $route     = ! $route ? $this->_req_action : $route;
3893 3893
         $transient = $notices
3894
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3895
-            : 'rte_tx_' . $route . '_' . $user_id;
3894
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3895
+            : 'rte_tx_'.$route.'_'.$user_id;
3896 3896
         $data      = is_multisite() && is_network_admin()
3897 3897
             ? get_site_transient($transient)
3898 3898
             : get_transient($transient);
@@ -4129,7 +4129,7 @@  discard block
 block discarded – undo
4129 4129
      */
4130 4130
     protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4131 4131
     {
4132
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4132
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4133 4133
     }
4134 4134
 
4135 4135
 
@@ -4143,7 +4143,7 @@  discard block
 block discarded – undo
4143 4143
      */
4144 4144
     protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4145 4145
     {
4146
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4146
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4147 4147
     }
4148 4148
 
4149 4149
 
Please login to merge, or discard this patch.
caffeinated/admin/extend/support/Extend_Support_Admin_Page.core.php 2 patches
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -18,77 +18,77 @@
 block discarded – undo
18 18
 class Extend_Support_Admin_Page extends Support_Admin_Page
19 19
 {
20 20
 
21
-    public function __construct($routing = true)
22
-    {
23
-        parent::__construct($routing);
24
-        define('EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'support/templates/');
25
-    }
26
-
27
-
28
-
29
-    protected function _extend_page_config()
30
-    {
31
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'support';
32
-        //new routes and new configs (or overrides )
33
-        $new_page_routes    = array(
34
-            'faq' => array(
35
-                'func'       => '_faq',
36
-                'capability' => 'ee_read_ee',
37
-            ),
38
-        );
39
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
40
-        $new_page_config    = array(
41
-            'faq' => array(
42
-                'nav'           => array(
43
-                    'label' => esc_html__('FAQ', 'event_espresso'),
44
-                    'order' => 40,
45
-                ),
46
-                'metaboxes'     => array('_espresso_news_post_box', '_espresso_links_post_box'),
47
-                'require_nonce' => false,
48
-            ),
49
-        );
50
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
51
-        $this->_page_config['default']['metaboxes'][] = '_installation_boxes';
52
-    }
53
-
54
-
55
-
56
-    protected function _faq()
57
-    {
58
-        $template_path = EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH . 'support_admin_details_faq.template.php';
59
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
60
-            $template_path,
61
-            '',
62
-            true
63
-        );
64
-        $this->display_admin_page_with_sidebar();
65
-    }
66
-
67
-
68
-
69
-    protected function _installation_boxes()
70
-    {
71
-        $callback_args = array(
72
-            'template_path' => EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH
73
-                               . 'support_admin_details_additional_information.template.php',
74
-        );
75
-        add_meta_box(
76
-            'espresso_additional_information_support',
77
-            esc_html__('Additional Information', 'event_espresso'),
78
-            function ($post, $metabox)
79
-            {
80
-                echo EEH_Template::display_template(
81
-                    $metabox['args']['template_path'],
82
-                    '',
83
-                    true
84
-                );
85
-            },
86
-            $this->_current_screen->id,
87
-            'normal',
88
-            'high',
89
-            $callback_args
90
-        );
91
-    }
21
+	public function __construct($routing = true)
22
+	{
23
+		parent::__construct($routing);
24
+		define('EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'support/templates/');
25
+	}
26
+
27
+
28
+
29
+	protected function _extend_page_config()
30
+	{
31
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'support';
32
+		//new routes and new configs (or overrides )
33
+		$new_page_routes    = array(
34
+			'faq' => array(
35
+				'func'       => '_faq',
36
+				'capability' => 'ee_read_ee',
37
+			),
38
+		);
39
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
40
+		$new_page_config    = array(
41
+			'faq' => array(
42
+				'nav'           => array(
43
+					'label' => esc_html__('FAQ', 'event_espresso'),
44
+					'order' => 40,
45
+				),
46
+				'metaboxes'     => array('_espresso_news_post_box', '_espresso_links_post_box'),
47
+				'require_nonce' => false,
48
+			),
49
+		);
50
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
51
+		$this->_page_config['default']['metaboxes'][] = '_installation_boxes';
52
+	}
53
+
54
+
55
+
56
+	protected function _faq()
57
+	{
58
+		$template_path = EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH . 'support_admin_details_faq.template.php';
59
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
60
+			$template_path,
61
+			'',
62
+			true
63
+		);
64
+		$this->display_admin_page_with_sidebar();
65
+	}
66
+
67
+
68
+
69
+	protected function _installation_boxes()
70
+	{
71
+		$callback_args = array(
72
+			'template_path' => EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH
73
+							   . 'support_admin_details_additional_information.template.php',
74
+		);
75
+		add_meta_box(
76
+			'espresso_additional_information_support',
77
+			esc_html__('Additional Information', 'event_espresso'),
78
+			function ($post, $metabox)
79
+			{
80
+				echo EEH_Template::display_template(
81
+					$metabox['args']['template_path'],
82
+					'',
83
+					true
84
+				);
85
+			},
86
+			$this->_current_screen->id,
87
+			'normal',
88
+			'high',
89
+			$callback_args
90
+		);
91
+	}
92 92
 
93 93
 
94 94
 
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 
4
-defined('EVENT_ESPRESSO_VERSION')|| exit('NO direct script access allowed');
4
+defined('EVENT_ESPRESSO_VERSION') || exit('NO direct script access allowed');
5 5
 
6 6
 
7 7
 
@@ -21,16 +21,16 @@  discard block
 block discarded – undo
21 21
     public function __construct($routing = true)
22 22
     {
23 23
         parent::__construct($routing);
24
-        define('EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'support/templates/');
24
+        define('EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'support/templates/');
25 25
     }
26 26
 
27 27
 
28 28
 
29 29
     protected function _extend_page_config()
30 30
     {
31
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'support';
31
+        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'support';
32 32
         //new routes and new configs (or overrides )
33
-        $new_page_routes    = array(
33
+        $new_page_routes = array(
34 34
             'faq' => array(
35 35
                 'func'       => '_faq',
36 36
                 'capability' => 'ee_read_ee',
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
 
56 56
     protected function _faq()
57 57
     {
58
-        $template_path = EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH . 'support_admin_details_faq.template.php';
58
+        $template_path = EE_SUPPORT_CAF_ADMIN_TEMPLATE_PATH.'support_admin_details_faq.template.php';
59 59
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
60 60
             $template_path,
61 61
             '',
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
         add_meta_box(
76 76
             'espresso_additional_information_support',
77 77
             esc_html__('Additional Information', 'event_espresso'),
78
-            function ($post, $metabox)
78
+            function($post, $metabox)
79 79
             {
80 80
                 echo EEH_Template::display_template(
81 81
                     $metabox['args']['template_path'],
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 1 patch
Indentation   +3688 added lines, -3688 removed lines patch added patch discarded remove patch
@@ -30,2299 +30,2299 @@  discard block
 block discarded – undo
30 30
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
31 31
 {
32 32
 
33
-    /**
34
-     * @var EE_Registration
35
-     */
36
-    private $_registration;
37
-
38
-    /**
39
-     * @var EE_Event
40
-     */
41
-    private $_reg_event;
42
-
43
-    /**
44
-     * @var EE_Session
45
-     */
46
-    private $_session;
47
-
48
-    private static $_reg_status;
49
-
50
-    /**
51
-     * Form for displaying the custom questions for this registration.
52
-     * This gets used a few times throughout the request so its best to cache it
53
-     *
54
-     * @var EE_Registration_Custom_Questions_Form
55
-     */
56
-    protected $_reg_custom_questions_form = null;
57
-
58
-
59
-    /**
60
-     *        constructor
61
-     *
62
-     * @Constructor
63
-     * @access public
64
-     * @param bool $routing
65
-     * @return Registrations_Admin_Page
66
-     */
67
-    public function __construct($routing = true)
68
-    {
69
-        parent::__construct($routing);
70
-        add_action('wp_loaded', array($this, 'wp_loaded'));
71
-    }
72
-
73
-
74
-    public function wp_loaded()
75
-    {
76
-        // when adding a new registration...
77
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
78
-            EE_System::do_not_cache();
79
-            if (! isset($this->_req_data['processing_registration'])
80
-                 || absint($this->_req_data['processing_registration']) !== 1
81
-            ) {
82
-                // and it's NOT the attendee information reg step
83
-                // force cookie expiration by setting time to last week
84
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
85
-                // and update the global
86
-                $_COOKIE['ee_registration_added'] = 0;
87
-            }
88
-        }
89
-    }
90
-
91
-
92
-    protected function _init_page_props()
93
-    {
94
-        $this->page_slug        = REG_PG_SLUG;
95
-        $this->_admin_base_url  = REG_ADMIN_URL;
96
-        $this->_admin_base_path = REG_ADMIN;
97
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
98
-        $this->_cpt_routes      = array(
99
-            'add_new_attendee' => 'espresso_attendees',
100
-            'edit_attendee'    => 'espresso_attendees',
101
-            'insert_attendee'  => 'espresso_attendees',
102
-            'update_attendee'  => 'espresso_attendees',
103
-        );
104
-        $this->_cpt_model_names = array(
105
-            'add_new_attendee' => 'EEM_Attendee',
106
-            'edit_attendee'    => 'EEM_Attendee',
107
-        );
108
-        $this->_cpt_edit_routes = array(
109
-            'espresso_attendees' => 'edit_attendee',
110
-        );
111
-        $this->_pagenow_map     = array(
112
-            'add_new_attendee' => 'post-new.php',
113
-            'edit_attendee'    => 'post.php',
114
-            'trash'            => 'post.php',
115
-        );
116
-        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
117
-        //add filters so that the comment urls don't take users to a confusing 404 page
118
-        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
119
-    }
120
-
121
-
122
-    public function clear_comment_link($link, $comment, $args)
123
-    {
124
-        //gotta make sure this only happens on this route
125
-        $post_type = get_post_type($comment->comment_post_ID);
126
-        if ($post_type === 'espresso_attendees') {
127
-            return '#commentsdiv';
128
-        }
129
-        return $link;
130
-    }
131
-
132
-
133
-    protected function _ajax_hooks()
134
-    {
135
-        //todo: all hooks for registrations ajax goes in here
136
-        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
137
-    }
138
-
139
-
140
-    protected function _define_page_props()
141
-    {
142
-        $this->_admin_page_title = $this->page_label;
143
-        $this->_labels           = array(
144
-            'buttons'                      => array(
145
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
146
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
147
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
148
-                'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
149
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
150
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
151
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
152
-                'contact_list_export' => esc_html__("Export Data", "event_espresso"),
153
-            ),
154
-            'publishbox'                   => array(
155
-                'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
156
-                'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
157
-            ),
158
-            'hide_add_button_on_cpt_route' => array(
159
-                'edit_attendee' => true,
160
-            ),
161
-        );
162
-    }
163
-
164
-
165
-    /**
166
-     *        grab url requests and route them
167
-     *
168
-     * @access private
169
-     * @return void
170
-     */
171
-    public function _set_page_routes()
172
-    {
173
-        $this->_get_registration_status_array();
174
-        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
175
-            ? $this->_req_data['_REG_ID'] : 0;
176
-        $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
177
-            ? $this->_req_data['reg_status_change_form']['REG_ID']
178
-            : $reg_id;
179
-        $att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
180
-            ? $this->_req_data['ATT_ID'] : 0;
181
-        $att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
182
-            ? $this->_req_data['post']
183
-            : $att_id;
184
-        $this->_page_routes = array(
185
-            'default'                            => array(
186
-                'func'       => '_registrations_overview_list_table',
187
-                'capability' => 'ee_read_registrations',
188
-            ),
189
-            'view_registration'                  => array(
190
-                'func'       => '_registration_details',
191
-                'capability' => 'ee_read_registration',
192
-                'obj_id'     => $reg_id,
193
-            ),
194
-            'edit_registration'                  => array(
195
-                'func'               => '_update_attendee_registration_form',
196
-                'noheader'           => true,
197
-                'headers_sent_route' => 'view_registration',
198
-                'capability'         => 'ee_edit_registration',
199
-                'obj_id'             => $reg_id,
200
-                '_REG_ID'            => $reg_id,
201
-            ),
202
-            'trash_registrations'                => array(
203
-                'func'       => '_trash_or_restore_registrations',
204
-                'args'       => array('trash' => true),
205
-                'noheader'   => true,
206
-                'capability' => 'ee_delete_registrations',
207
-            ),
208
-            'restore_registrations'              => array(
209
-                'func'       => '_trash_or_restore_registrations',
210
-                'args'       => array('trash' => false),
211
-                'noheader'   => true,
212
-                'capability' => 'ee_delete_registrations',
213
-            ),
214
-            'delete_registrations'               => array(
215
-                'func'       => '_delete_registrations',
216
-                'noheader'   => true,
217
-                'capability' => 'ee_delete_registrations',
218
-            ),
219
-            'new_registration'                   => array(
220
-                'func'       => 'new_registration',
221
-                'capability' => 'ee_edit_registrations',
222
-            ),
223
-            'process_reg_step'                   => array(
224
-                'func'       => 'process_reg_step',
225
-                'noheader'   => true,
226
-                'capability' => 'ee_edit_registrations',
227
-            ),
228
-            'redirect_to_txn'                    => array(
229
-                'func'       => 'redirect_to_txn',
230
-                'noheader'   => true,
231
-                'capability' => 'ee_edit_registrations',
232
-            ),
233
-            'change_reg_status'                  => array(
234
-                'func'       => '_change_reg_status',
235
-                'noheader'   => true,
236
-                'capability' => 'ee_edit_registration',
237
-                'obj_id'     => $reg_id,
238
-            ),
239
-            'approve_registration'               => array(
240
-                'func'       => 'approve_registration',
241
-                'noheader'   => true,
242
-                'capability' => 'ee_edit_registration',
243
-                'obj_id'     => $reg_id,
244
-            ),
245
-            'approve_and_notify_registration'    => array(
246
-                'func'       => 'approve_registration',
247
-                'noheader'   => true,
248
-                'args'       => array(true),
249
-                'capability' => 'ee_edit_registration',
250
-                'obj_id'     => $reg_id,
251
-            ),
252
-            'approve_registrations'               => array(
253
-                'func'       => 'bulk_action_on_registrations',
254
-                'noheader'   => true,
255
-                'capability' => 'ee_edit_registrations',
256
-                'args' => array('approve')
257
-            ),
258
-            'approve_and_notify_registrations'               => array(
259
-                'func'       => 'bulk_action_on_registrations',
260
-                'noheader'   => true,
261
-                'capability' => 'ee_edit_registrations',
262
-                'args' => array('approve', true)
263
-            ),
264
-            'decline_registration'               => array(
265
-                'func'       => 'decline_registration',
266
-                'noheader'   => true,
267
-                'capability' => 'ee_edit_registration',
268
-                'obj_id'     => $reg_id,
269
-            ),
270
-            'decline_and_notify_registration'    => array(
271
-                'func'       => 'decline_registration',
272
-                'noheader'   => true,
273
-                'args'       => array(true),
274
-                'capability' => 'ee_edit_registration',
275
-                'obj_id'     => $reg_id,
276
-            ),
277
-            'decline_registrations'               => array(
278
-                'func'       => 'bulk_action_on_registrations',
279
-                'noheader'   => true,
280
-                'capability' => 'ee_edit_registrations',
281
-                'args' => array('decline')
282
-            ),
283
-            'decline_and_notify_registrations'    => array(
284
-                'func'       => 'bulk_action_on_registrations',
285
-                'noheader'   => true,
286
-                'capability' => 'ee_edit_registrations',
287
-                'args' => array('decline', true)
288
-            ),
289
-            'pending_registration'               => array(
290
-                'func'       => 'pending_registration',
291
-                'noheader'   => true,
292
-                'capability' => 'ee_edit_registration',
293
-                'obj_id'     => $reg_id,
294
-            ),
295
-            'pending_and_notify_registration'    => array(
296
-                'func'       => 'pending_registration',
297
-                'noheader'   => true,
298
-                'args'       => array(true),
299
-                'capability' => 'ee_edit_registration',
300
-                'obj_id'     => $reg_id,
301
-            ),
302
-            'pending_registrations'               => array(
303
-                'func'       => 'bulk_action_on_registrations',
304
-                'noheader'   => true,
305
-                'capability' => 'ee_edit_registrations',
306
-                'args' => array('pending')
307
-            ),
308
-            'pending_and_notify_registrations'    => array(
309
-                'func'       => 'bulk_action_on_registrations',
310
-                'noheader'   => true,
311
-                'capability' => 'ee_edit_registrations',
312
-                'args' => array('pending', true)
313
-            ),
314
-            'no_approve_registration'            => array(
315
-                'func'       => 'not_approve_registration',
316
-                'noheader'   => true,
317
-                'capability' => 'ee_edit_registration',
318
-                'obj_id'     => $reg_id,
319
-            ),
320
-            'no_approve_and_notify_registration' => array(
321
-                'func'       => 'not_approve_registration',
322
-                'noheader'   => true,
323
-                'args'       => array(true),
324
-                'capability' => 'ee_edit_registration',
325
-                'obj_id'     => $reg_id,
326
-            ),
327
-            'no_approve_registrations'            => array(
328
-                'func'       => 'bulk_action_on_registrations',
329
-                'noheader'   => true,
330
-                'capability' => 'ee_edit_registrations',
331
-                'args' => array('not_approve')
332
-            ),
333
-            'no_approve_and_notify_registrations' => array(
334
-                'func'       => 'bulk_action_on_registrations',
335
-                'noheader'   => true,
336
-                'capability' => 'ee_edit_registrations',
337
-                'args' => array('not_approve', true)
338
-            ),
339
-            'cancel_registration'                => array(
340
-                'func'       => 'cancel_registration',
341
-                'noheader'   => true,
342
-                'capability' => 'ee_edit_registration',
343
-                'obj_id'     => $reg_id,
344
-            ),
345
-            'cancel_and_notify_registration'     => array(
346
-                'func'       => 'cancel_registration',
347
-                'noheader'   => true,
348
-                'args'       => array(true),
349
-                'capability' => 'ee_edit_registration',
350
-                'obj_id'     => $reg_id,
351
-            ),
352
-            'cancel_registrations'                => array(
353
-                'func'       => 'bulk_action_on_registrations',
354
-                'noheader'   => true,
355
-                'capability' => 'ee_edit_registrations',
356
-                'args' => array('cancel')
357
-            ),
358
-            'cancel_and_notify_registrations'     => array(
359
-                'func'       => 'bulk_action_on_registrations',
360
-                'noheader'   => true,
361
-                'capability' => 'ee_edit_registrations',
362
-                'args' => array('cancel', true)
363
-            ),
364
-            'wait_list_registration' => array(
365
-                'func'       => 'wait_list_registration',
366
-                'noheader'   => true,
367
-                'capability' => 'ee_edit_registration',
368
-                'obj_id'     => $reg_id,
369
-            ),
370
-            'wait_list_and_notify_registration' => array(
371
-                'func'       => 'wait_list_registration',
372
-                'noheader'   => true,
373
-                'args'       => array(true),
374
-                'capability' => 'ee_edit_registration',
375
-                'obj_id'     => $reg_id,
376
-            ),
377
-            'contact_list'                       => array(
378
-                'func'       => '_attendee_contact_list_table',
379
-                'capability' => 'ee_read_contacts',
380
-            ),
381
-            'add_new_attendee'                   => array(
382
-                'func' => '_create_new_cpt_item',
383
-                'args' => array(
384
-                    'new_attendee' => true,
385
-                    'capability'   => 'ee_edit_contacts',
386
-                ),
387
-            ),
388
-            'edit_attendee'                      => array(
389
-                'func'       => '_edit_cpt_item',
390
-                'capability' => 'ee_edit_contacts',
391
-                'obj_id'     => $att_id,
392
-            ),
393
-            'duplicate_attendee'                 => array(
394
-                'func'       => '_duplicate_attendee',
395
-                'noheader'   => true,
396
-                'capability' => 'ee_edit_contacts',
397
-                'obj_id'     => $att_id,
398
-            ),
399
-            'insert_attendee'                    => array(
400
-                'func'       => '_insert_or_update_attendee',
401
-                'args'       => array(
402
-                    'new_attendee' => true,
403
-                ),
404
-                'noheader'   => true,
405
-                'capability' => 'ee_edit_contacts',
406
-            ),
407
-            'update_attendee'                    => array(
408
-                'func'       => '_insert_or_update_attendee',
409
-                'args'       => array(
410
-                    'new_attendee' => false,
411
-                ),
412
-                'noheader'   => true,
413
-                'capability' => 'ee_edit_contacts',
414
-                'obj_id'     => $att_id,
415
-            ),
416
-            'trash_attendees' => array(
417
-                'func' => '_trash_or_restore_attendees',
418
-                'args' => array(
419
-                    'trash' => 'true'
420
-                ),
421
-                'noheader' => true,
422
-                'capability' => 'ee_delete_contacts'
423
-            ),
424
-            'trash_attendee'                    => array(
425
-                'func'       => '_trash_or_restore_attendees',
426
-                'args'       => array(
427
-                    'trash' => true,
428
-                ),
429
-                'noheader'   => true,
430
-                'capability' => 'ee_delete_contacts',
431
-                'obj_id'     => $att_id,
432
-            ),
433
-            'restore_attendees'                  => array(
434
-                'func'       => '_trash_or_restore_attendees',
435
-                'args'       => array(
436
-                    'trash' => false,
437
-                ),
438
-                'noheader'   => true,
439
-                'capability' => 'ee_delete_contacts',
440
-                'obj_id'     => $att_id,
441
-            ),
442
-            'resend_registration'                => array(
443
-                'func'       => '_resend_registration',
444
-                'noheader'   => true,
445
-                'capability' => 'ee_send_message',
446
-            ),
447
-            'registrations_report'               => array(
448
-                'func'       => '_registrations_report',
449
-                'noheader'   => true,
450
-                'capability' => 'ee_read_registrations',
451
-            ),
452
-            'contact_list_export'                => array(
453
-                'func'       => '_contact_list_export',
454
-                'noheader'   => true,
455
-                'capability' => 'export',
456
-            ),
457
-            'contact_list_report'                => array(
458
-                'func'       => '_contact_list_report',
459
-                'noheader'   => true,
460
-                'capability' => 'ee_read_contacts',
461
-            ),
462
-        );
463
-    }
464
-
465
-
466
-    protected function _set_page_config()
467
-    {
468
-        $this->_page_config = array(
469
-            'default'           => array(
470
-                'nav'           => array(
471
-                    'label' => esc_html__('Overview', 'event_espresso'),
472
-                    'order' => 5,
473
-                ),
474
-                'help_tabs'     => array(
475
-                    'registrations_overview_help_tab'                       => array(
476
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
477
-                        'filename' => 'registrations_overview',
478
-                    ),
479
-                    'registrations_overview_table_column_headings_help_tab' => array(
480
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
481
-                        'filename' => 'registrations_overview_table_column_headings',
482
-                    ),
483
-                    'registrations_overview_filters_help_tab'               => array(
484
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
485
-                        'filename' => 'registrations_overview_filters',
486
-                    ),
487
-                    'registrations_overview_views_help_tab'                 => array(
488
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
489
-                        'filename' => 'registrations_overview_views',
490
-                    ),
491
-                    'registrations_regoverview_other_help_tab'              => array(
492
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
493
-                        'filename' => 'registrations_overview_other',
494
-                    ),
495
-                ),
496
-                'help_tour'     => array('Registration_Overview_Help_Tour'),
497
-                'qtips'         => array('Registration_List_Table_Tips'),
498
-                'list_table'    => 'EE_Registrations_List_Table',
499
-                'require_nonce' => false,
500
-            ),
501
-            'view_registration' => array(
502
-                'nav'           => array(
503
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
504
-                    'order'      => 15,
505
-                    'url'        => isset($this->_req_data['_REG_ID'])
506
-                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
507
-                        : $this->_admin_base_url,
508
-                    'persistent' => false,
509
-                ),
510
-                'help_tabs'     => array(
511
-                    'registrations_details_help_tab'                    => array(
512
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
513
-                        'filename' => 'registrations_details',
514
-                    ),
515
-                    'registrations_details_table_help_tab'              => array(
516
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
517
-                        'filename' => 'registrations_details_table',
518
-                    ),
519
-                    'registrations_details_form_answers_help_tab'       => array(
520
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
521
-                        'filename' => 'registrations_details_form_answers',
522
-                    ),
523
-                    'registrations_details_registrant_details_help_tab' => array(
524
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
525
-                        'filename' => 'registrations_details_registrant_details',
526
-                    ),
527
-                ),
528
-                'help_tour'     => array('Registration_Details_Help_Tour'),
529
-                'metaboxes'     => array_merge(
530
-                    $this->_default_espresso_metaboxes,
531
-                    array('_registration_details_metaboxes')
532
-                ),
533
-                'require_nonce' => false,
534
-            ),
535
-            'new_registration'  => array(
536
-                'nav'           => array(
537
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
538
-                    'url'        => '#',
539
-                    'order'      => 15,
540
-                    'persistent' => false,
541
-                ),
542
-                'metaboxes'     => $this->_default_espresso_metaboxes,
543
-                'labels'        => array(
544
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
545
-                ),
546
-                'require_nonce' => false,
547
-            ),
548
-            'add_new_attendee'  => array(
549
-                'nav'           => array(
550
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
551
-                    'order'      => 15,
552
-                    'persistent' => false,
553
-                ),
554
-                'metaboxes'     => array_merge(
555
-                    $this->_default_espresso_metaboxes,
556
-                    array('_publish_post_box', 'attendee_editor_metaboxes')
557
-                ),
558
-                'require_nonce' => false,
559
-            ),
560
-            'edit_attendee'     => array(
561
-                'nav'           => array(
562
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
563
-                    'order'      => 15,
564
-                    'persistent' => false,
565
-                    'url'        => isset($this->_req_data['ATT_ID'])
566
-                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
567
-                        : $this->_admin_base_url,
568
-                ),
569
-                'metaboxes'     => array('attendee_editor_metaboxes'),
570
-                'require_nonce' => false,
571
-            ),
572
-            'contact_list'      => array(
573
-                'nav'           => array(
574
-                    'label' => esc_html__('Contact List', 'event_espresso'),
575
-                    'order' => 20,
576
-                ),
577
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
578
-                'help_tabs'     => array(
579
-                    'registrations_contact_list_help_tab'                       => array(
580
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
581
-                        'filename' => 'registrations_contact_list',
582
-                    ),
583
-                    'registrations_contact-list_table_column_headings_help_tab' => array(
584
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
585
-                        'filename' => 'registrations_contact_list_table_column_headings',
586
-                    ),
587
-                    'registrations_contact_list_views_help_tab'                 => array(
588
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
589
-                        'filename' => 'registrations_contact_list_views',
590
-                    ),
591
-                    'registrations_contact_list_other_help_tab'                 => array(
592
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
593
-                        'filename' => 'registrations_contact_list_other',
594
-                    ),
595
-                ),
596
-                'help_tour'     => array('Contact_List_Help_Tour'),
597
-                'metaboxes'     => array(),
598
-                'require_nonce' => false,
599
-            ),
600
-            //override default cpt routes
601
-            'create_new'        => '',
602
-            'edit'              => '',
603
-        );
604
-    }
605
-
606
-
607
-    /**
608
-     * The below methods aren't used by this class currently
609
-     */
610
-    protected function _add_screen_options()
611
-    {
612
-    }
613
-
614
-
615
-    protected function _add_feature_pointers()
616
-    {
617
-    }
618
-
619
-
620
-    public function admin_init()
621
-    {
622
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
623
-            'click "Update Registration Questions" to save your changes',
624
-            'event_espresso'
625
-        );
626
-    }
627
-
628
-
629
-    public function admin_notices()
630
-    {
631
-    }
632
-
633
-
634
-    public function admin_footer_scripts()
635
-    {
636
-    }
637
-
638
-
639
-    /**
640
-     *        get list of registration statuses
641
-     *
642
-     * @access private
643
-     * @return void
644
-     * @throws EE_Error
645
-     */
646
-    private function _get_registration_status_array()
647
-    {
648
-        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
649
-    }
650
-
651
-
652
-    protected function _add_screen_options_default()
653
-    {
654
-        $this->_per_page_screen_option();
655
-    }
656
-
657
-
658
-    protected function _add_screen_options_contact_list()
659
-    {
660
-        $page_title              = $this->_admin_page_title;
661
-        $this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
662
-        $this->_per_page_screen_option();
663
-        $this->_admin_page_title = $page_title;
664
-    }
665
-
666
-
667
-    public function load_scripts_styles()
668
-    {
669
-        //style
670
-        wp_register_style(
671
-            'espresso_reg',
672
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
673
-            array('ee-admin-css'),
674
-            EVENT_ESPRESSO_VERSION
675
-        );
676
-        wp_enqueue_style('espresso_reg');
677
-        //script
678
-        wp_register_script(
679
-            'espresso_reg',
680
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
681
-            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
682
-            EVENT_ESPRESSO_VERSION,
683
-            true
684
-        );
685
-        wp_enqueue_script('espresso_reg');
686
-    }
687
-
688
-
689
-    public function load_scripts_styles_edit_attendee()
690
-    {
691
-        //stuff to only show up on our attendee edit details page.
692
-        $attendee_details_translations = array(
693
-            'att_publish_text' => sprintf(
694
-                esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
695
-                $this->_cpt_model_obj->get_datetime('ATT_created')
696
-            ),
697
-        );
698
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
699
-        wp_enqueue_script('jquery-validate');
700
-    }
701
-
702
-
703
-    public function load_scripts_styles_view_registration()
704
-    {
705
-        //styles
706
-        wp_enqueue_style('espresso-ui-theme');
707
-        //scripts
708
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
709
-        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
710
-    }
711
-
712
-
713
-    public function load_scripts_styles_contact_list()
714
-    {
715
-        wp_deregister_style('espresso_reg');
716
-        wp_register_style(
717
-            'espresso_att',
718
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
719
-            array('ee-admin-css'),
720
-            EVENT_ESPRESSO_VERSION
721
-        );
722
-        wp_enqueue_style('espresso_att');
723
-    }
724
-
725
-
726
-    public function load_scripts_styles_new_registration()
727
-    {
728
-        wp_register_script(
729
-            'ee-spco-for-admin',
730
-            REG_ASSETS_URL . 'spco_for_admin.js',
731
-            array('underscore', 'jquery'),
732
-            EVENT_ESPRESSO_VERSION,
733
-            true
734
-        );
735
-        wp_enqueue_script('ee-spco-for-admin');
736
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
737
-        EE_Form_Section_Proper::wp_enqueue_scripts();
738
-        EED_Ticket_Selector::load_tckt_slctr_assets();
739
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
740
-    }
741
-
742
-
743
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
744
-    {
745
-        add_filter('FHEE_load_EE_messages', '__return_true');
746
-    }
747
-
748
-
749
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
750
-    {
751
-        add_filter('FHEE_load_EE_messages', '__return_true');
752
-    }
753
-
754
-
755
-    protected function _set_list_table_views_default()
756
-    {
757
-        //for notification related bulk actions we need to make sure only active messengers have an option.
758
-        EED_Messages::set_autoloaders();
759
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
760
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
761
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
762
-        //key= bulk_action_slug, value= message type.
763
-        $match_array = array(
764
-            'approve_registrations'    => 'registration',
765
-            'decline_registrations'    => 'declined_registration',
766
-            'pending_registrations'    => 'pending_approval',
767
-            'no_approve_registrations' => 'not_approved_registration',
768
-            'cancel_registrations'     => 'cancelled_registration',
769
-        );
770
-        $can_send = EE_Registry::instance()->CAP->current_user_can(
771
-            'ee_send_message',
772
-            'batch_send_messages'
773
-        );
774
-        /** setup reg status bulk actions **/
775
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
776
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
777
-                $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
778
-                    'Approve and Notify Registrations',
779
-                    'event_espresso'
780
-                );
781
-        }
782
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
783
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
784
-                $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
785
-                    'Decline and Notify Registrations',
786
-                    'event_espresso'
787
-                );
788
-        }
789
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
790
-            'Set Registrations to Pending Payment',
791
-            'event_espresso'
792
-        );
793
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
794
-                $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
795
-                    'Set Registrations to Pending Payment and Notify',
796
-                    'event_espresso'
797
-                );
798
-        }
799
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
800
-            'Set Registrations to Not Approved',
801
-            'event_espresso'
802
-        );
803
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
804
-                $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
805
-                    'Set Registrations to Not Approved and Notify',
806
-                    'event_espresso'
807
-                );
808
-        }
809
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
810
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
811
-                $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
812
-                    'Cancel Registrations and Notify',
813
-                    'event_espresso'
814
-                );
815
-        }
816
-        $def_reg_status_actions = apply_filters(
817
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
818
-            $def_reg_status_actions,
819
-            $active_mts,
820
-            $can_send
821
-        );
822
-
823
-        $this->_views = array(
824
-            'all'   => array(
825
-                'slug'        => 'all',
826
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
827
-                'count'       => 0,
828
-                'bulk_action' => array_merge($def_reg_status_actions, array(
829
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
830
-                )),
831
-            ),
832
-            'month' => array(
833
-                'slug'        => 'month',
834
-                'label'       => esc_html__('This Month', 'event_espresso'),
835
-                'count'       => 0,
836
-                'bulk_action' => array_merge($def_reg_status_actions, array(
837
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
838
-                )),
839
-            ),
840
-            'today' => array(
841
-                'slug'        => 'today',
842
-                'label'       => sprintf(
843
-                    esc_html__('Today - %s', 'event_espresso'),
844
-                    date('M d, Y', current_time('timestamp'))
845
-                ),
846
-                'count'       => 0,
847
-                'bulk_action' => array_merge($def_reg_status_actions, array(
848
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
849
-                )),
850
-            ),
851
-        );
852
-        if (EE_Registry::instance()->CAP->current_user_can(
853
-            'ee_delete_registrations',
854
-            'espresso_registrations_delete_registration'
855
-        )) {
856
-            $this->_views['incomplete'] = array(
857
-                'slug'        => 'incomplete',
858
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
859
-                'count'       => 0,
860
-                'bulk_action' => array(
861
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
862
-                ),
863
-            );
864
-            $this->_views['trash']      = array(
865
-                'slug'        => 'trash',
866
-                'label'       => esc_html__('Trash', 'event_espresso'),
867
-                'count'       => 0,
868
-                'bulk_action' => array(
869
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
870
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
871
-                ),
872
-            );
873
-        }
874
-    }
875
-
876
-
877
-    protected function _set_list_table_views_contact_list()
878
-    {
879
-        $this->_views = array(
880
-            'in_use' => array(
881
-                'slug'        => 'in_use',
882
-                'label'       => esc_html__('In Use', 'event_espresso'),
883
-                'count'       => 0,
884
-                'bulk_action' => array(
885
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
886
-                ),
887
-            ),
888
-        );
889
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
890
-            'espresso_registrations_trash_attendees')
891
-        ) {
892
-            $this->_views['trash'] = array(
893
-                'slug'        => 'trash',
894
-                'label'       => esc_html__('Trash', 'event_espresso'),
895
-                'count'       => 0,
896
-                'bulk_action' => array(
897
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
898
-                ),
899
-            );
900
-        }
901
-    }
902
-
903
-
904
-    protected function _registration_legend_items()
905
-    {
906
-        $fc_items = array(
907
-            'star-icon'        => array(
908
-                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
909
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
910
-            ),
911
-            'view_details'     => array(
912
-                'class' => 'dashicons dashicons-clipboard',
913
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
914
-            ),
915
-            'edit_attendee'    => array(
916
-                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
917
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
918
-            ),
919
-            'view_transaction' => array(
920
-                'class' => 'dashicons dashicons-cart',
921
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
922
-            ),
923
-            'view_invoice'     => array(
924
-                'class' => 'dashicons dashicons-media-spreadsheet',
925
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
926
-            ),
927
-        );
928
-        if (EE_Registry::instance()->CAP->current_user_can(
929
-            'ee_send_message',
930
-            'espresso_registrations_resend_registration'
931
-        )) {
932
-            $fc_items['resend_registration'] = array(
933
-                'class' => 'dashicons dashicons-email-alt',
934
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
935
-            );
936
-        } else {
937
-            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
938
-        }
939
-        if (EE_Registry::instance()->CAP->current_user_can(
940
-            'ee_read_global_messages',
941
-            'view_filtered_messages'
942
-        )) {
943
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
944
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
945
-                $fc_items['view_related_messages'] = array(
946
-                    'class' => $related_for_icon['css_class'],
947
-                    'desc'  => $related_for_icon['label'],
948
-                );
949
-            }
950
-        }
951
-        $sc_items = array(
952
-            'approved_status'   => array(
953
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
954
-                'desc'  => EEH_Template::pretty_status(
955
-                    EEM_Registration::status_id_approved,
956
-                    false,
957
-                    'sentence'
958
-                ),
959
-            ),
960
-            'pending_status'    => array(
961
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
962
-                'desc'  => EEH_Template::pretty_status(
963
-                    EEM_Registration::status_id_pending_payment,
964
-                    false,
965
-                    'sentence'
966
-                ),
967
-            ),
968
-            'wait_list'         => array(
969
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
970
-                'desc'  => EEH_Template::pretty_status(
971
-                    EEM_Registration::status_id_wait_list,
972
-                    false,
973
-                    'sentence'
974
-                ),
975
-            ),
976
-            'incomplete_status' => array(
977
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
978
-                'desc'  => EEH_Template::pretty_status(
979
-                    EEM_Registration::status_id_incomplete,
980
-                    false,
981
-                    'sentence'
982
-                ),
983
-            ),
984
-            'not_approved'      => array(
985
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
986
-                'desc'  => EEH_Template::pretty_status(
987
-                    EEM_Registration::status_id_not_approved,
988
-                    false,
989
-                    'sentence'
990
-                ),
991
-            ),
992
-            'declined_status'   => array(
993
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
994
-                'desc'  => EEH_Template::pretty_status(
995
-                    EEM_Registration::status_id_declined,
996
-                    false,
997
-                    'sentence'
998
-                ),
999
-            ),
1000
-            'cancelled_status'  => array(
1001
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1002
-                'desc'  => EEH_Template::pretty_status(
1003
-                    EEM_Registration::status_id_cancelled,
1004
-                    false,
1005
-                    'sentence'
1006
-                ),
1007
-            ),
1008
-        );
1009
-        return array_merge($fc_items, $sc_items);
1010
-    }
1011
-
1012
-
1013
-
1014
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1015
-    /**
1016
-     * @throws \EE_Error
1017
-     */
1018
-    protected function _registrations_overview_list_table()
1019
-    {
1020
-        $this->_template_args['admin_page_header'] = '';
1021
-        $EVT_ID                                    = ! empty($this->_req_data['event_id'])
1022
-            ? absint($this->_req_data['event_id'])
1023
-            : 0;
1024
-        if ($EVT_ID) {
1025
-            if (EE_Registry::instance()->CAP->current_user_can(
1026
-                'ee_edit_registrations',
1027
-                'espresso_registrations_new_registration',
1028
-                $EVT_ID
1029
-            )) {
1030
-                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1031
-                    'new_registration',
1032
-                    'add-registrant',
1033
-                    array('event_id' => $EVT_ID),
1034
-                    'add-new-h2'
1035
-                );
1036
-            }
1037
-            $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1038
-            if ($event instanceof EE_Event) {
1039
-                $this->_template_args['admin_page_header'] = sprintf(
1040
-                    esc_html__(
1041
-                        '%s Viewing registrations for the event: %s%s',
1042
-                        'event_espresso'
1043
-                    ),
1044
-                    '<h3 style="line-height:1.5em;">',
1045
-                    '<br /><a href="'
1046
-                        . EE_Admin_Page::add_query_args_and_nonce(
1047
-                            array(
1048
-                                'action' => 'edit',
1049
-                                'post'   => $event->ID(),
1050
-                            ),
1051
-                            EVENTS_ADMIN_URL
1052
-                        )
1053
-                        . '">&nbsp;'
1054
-                        . $event->get('EVT_name')
1055
-                        . '&nbsp;</a>&nbsp;',
1056
-                    '</h3>'
1057
-                );
1058
-            }
1059
-            $DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1060
-            $datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1061
-            if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1062
-                $this->_template_args['admin_page_header'] = substr(
1063
-                    $this->_template_args['admin_page_header'],
1064
-                    0,
1065
-                    -5
1066
-                );
1067
-                $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1068
-                $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1069
-                $this->_template_args['admin_page_header'] .= $datetime->name();
1070
-                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1071
-                $this->_template_args['admin_page_header'] .= '</span></h3>';
1072
-            }
1073
-        }
1074
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1075
-        $this->display_admin_list_table_page_with_no_sidebar();
1076
-    }
1077
-
1078
-
1079
-    /**
1080
-     * This sets the _registration property for the registration details screen
1081
-     *
1082
-     * @access private
1083
-     * @return bool
1084
-     * @throws EE_Error
1085
-     * @throws InvalidArgumentException
1086
-     * @throws InvalidDataTypeException
1087
-     * @throws InvalidInterfaceException
1088
-     */
1089
-    private function _set_registration_object()
1090
-    {
1091
-        //get out if we've already set the object
1092
-        if ($this->_registration instanceof EE_Registration) {
1093
-            return true;
1094
-        }
1095
-        $REG    = EEM_Registration::instance();
1096
-        $REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1097
-        if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1098
-            return true;
1099
-        } else {
1100
-            $error_msg = sprintf(
1101
-                esc_html__(
1102
-                    'An error occurred and the details for Registration ID #%s could not be retrieved.',
1103
-                    'event_espresso'
1104
-                ),
1105
-                $REG_ID
1106
-            );
1107
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1108
-            $this->_registration = null;
1109
-            return false;
1110
-        }
1111
-    }
1112
-
1113
-
1114
-    /**
1115
-     * Used to retrieve registrations for the list table.
1116
-     *
1117
-     * @param int  $per_page
1118
-     * @param bool $count
1119
-     * @param bool $this_month
1120
-     * @param bool $today
1121
-     * @return EE_Registration[]|int
1122
-     * @throws EE_Error
1123
-     * @throws InvalidArgumentException
1124
-     * @throws InvalidDataTypeException
1125
-     * @throws InvalidInterfaceException
1126
-     */
1127
-    public function get_registrations(
1128
-        $per_page = 10,
1129
-        $count = false,
1130
-        $this_month = false,
1131
-        $today = false
1132
-    ) {
1133
-        if ($this_month) {
1134
-            $this->_req_data['status'] = 'month';
1135
-        }
1136
-        if ($today) {
1137
-            $this->_req_data['status'] = 'today';
1138
-        }
1139
-        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1140
-        /**
1141
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1142
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1143
-         * @see EEM_Base::get_all()
1144
-         */
1145
-        $query_params['group_by'] = '';
1146
-
1147
-        return $count
1148
-            ? EEM_Registration::instance()->count($query_params)
1149
-            /** @type EE_Registration[] */
1150
-            : EEM_Registration::instance()->get_all($query_params);
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1156
-     * Note: this listens to values on the request for some of the query parameters.
1157
-     *
1158
-     * @param array $request
1159
-     * @param int   $per_page
1160
-     * @param bool  $count
1161
-     * @return array
1162
-     * @throws EE_Error
1163
-     */
1164
-    protected function _get_registration_query_parameters(
1165
-        $request = array(),
1166
-        $per_page = 10,
1167
-        $count = false
1168
-    ) {
1169
-
1170
-        $query_params = array(
1171
-            0                          => $this->_get_where_conditions_for_registrations_query(
1172
-                $request
1173
-            ),
1174
-            'caps'                     => EEM_Registration::caps_read_admin,
1175
-            'default_where_conditions' => 'this_model_only',
1176
-        );
1177
-        if (! $count) {
1178
-            $query_params = array_merge(
1179
-                $query_params,
1180
-                $this->_get_orderby_for_registrations_query(),
1181
-                $this->_get_limit($per_page)
1182
-            );
1183
-        }
1184
-
1185
-        return $query_params;
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * This will add EVT_ID to the provided $where array for EE model query parameters.
1191
-     *
1192
-     * @param array $request usually the same as $this->_req_data but not necessarily
1193
-     * @return array
1194
-     */
1195
-    protected function _add_event_id_to_where_conditions(array $request)
1196
-    {
1197
-        $where = array();
1198
-        if (! empty($request['event_id'])) {
1199
-            $where['EVT_ID'] = absint($request['event_id']);
1200
-        }
1201
-        return $where;
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * Adds category ID if it exists in the request to the where conditions for the registrations query.
1207
-     *
1208
-     * @param array $request usually the same as $this->_req_data but not necessarily
1209
-     * @return array
1210
-     */
1211
-    protected function _add_category_id_to_where_conditions(array $request)
1212
-    {
1213
-        $where = array();
1214
-        if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1215
-            $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1216
-        }
1217
-        return $where;
1218
-    }
1219
-
1220
-
1221
-    /**
1222
-     * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1223
-     *
1224
-     * @param array $request usually the same as $this->_req_data but not necessarily
1225
-     * @return array
1226
-     */
1227
-    protected function _add_datetime_id_to_where_conditions(array $request)
1228
-    {
1229
-        $where = array();
1230
-        if (! empty($request['datetime_id'])) {
1231
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1232
-        }
1233
-        if (! empty($request['DTT_ID'])) {
1234
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1235
-        }
1236
-        return $where;
1237
-    }
1238
-
1239
-
1240
-    /**
1241
-     * Adds the correct registration status to the where conditions for the registrations query.
1242
-     *
1243
-     * @param array $request usually the same as $this->_req_data but not necessarily
1244
-     * @return array
1245
-     */
1246
-    protected function _add_registration_status_to_where_conditions(array $request)
1247
-    {
1248
-        $where = array();
1249
-        $view = EEH_Array::is_set($request, 'status', '');
1250
-        $registration_status = ! empty($request['_reg_status'])
1251
-            ? sanitize_text_field($request['_reg_status'])
1252
-            : '';
1253
-
1254
-        /*
33
+	/**
34
+	 * @var EE_Registration
35
+	 */
36
+	private $_registration;
37
+
38
+	/**
39
+	 * @var EE_Event
40
+	 */
41
+	private $_reg_event;
42
+
43
+	/**
44
+	 * @var EE_Session
45
+	 */
46
+	private $_session;
47
+
48
+	private static $_reg_status;
49
+
50
+	/**
51
+	 * Form for displaying the custom questions for this registration.
52
+	 * This gets used a few times throughout the request so its best to cache it
53
+	 *
54
+	 * @var EE_Registration_Custom_Questions_Form
55
+	 */
56
+	protected $_reg_custom_questions_form = null;
57
+
58
+
59
+	/**
60
+	 *        constructor
61
+	 *
62
+	 * @Constructor
63
+	 * @access public
64
+	 * @param bool $routing
65
+	 * @return Registrations_Admin_Page
66
+	 */
67
+	public function __construct($routing = true)
68
+	{
69
+		parent::__construct($routing);
70
+		add_action('wp_loaded', array($this, 'wp_loaded'));
71
+	}
72
+
73
+
74
+	public function wp_loaded()
75
+	{
76
+		// when adding a new registration...
77
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
78
+			EE_System::do_not_cache();
79
+			if (! isset($this->_req_data['processing_registration'])
80
+				 || absint($this->_req_data['processing_registration']) !== 1
81
+			) {
82
+				// and it's NOT the attendee information reg step
83
+				// force cookie expiration by setting time to last week
84
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
85
+				// and update the global
86
+				$_COOKIE['ee_registration_added'] = 0;
87
+			}
88
+		}
89
+	}
90
+
91
+
92
+	protected function _init_page_props()
93
+	{
94
+		$this->page_slug        = REG_PG_SLUG;
95
+		$this->_admin_base_url  = REG_ADMIN_URL;
96
+		$this->_admin_base_path = REG_ADMIN;
97
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
98
+		$this->_cpt_routes      = array(
99
+			'add_new_attendee' => 'espresso_attendees',
100
+			'edit_attendee'    => 'espresso_attendees',
101
+			'insert_attendee'  => 'espresso_attendees',
102
+			'update_attendee'  => 'espresso_attendees',
103
+		);
104
+		$this->_cpt_model_names = array(
105
+			'add_new_attendee' => 'EEM_Attendee',
106
+			'edit_attendee'    => 'EEM_Attendee',
107
+		);
108
+		$this->_cpt_edit_routes = array(
109
+			'espresso_attendees' => 'edit_attendee',
110
+		);
111
+		$this->_pagenow_map     = array(
112
+			'add_new_attendee' => 'post-new.php',
113
+			'edit_attendee'    => 'post.php',
114
+			'trash'            => 'post.php',
115
+		);
116
+		add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
117
+		//add filters so that the comment urls don't take users to a confusing 404 page
118
+		add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
119
+	}
120
+
121
+
122
+	public function clear_comment_link($link, $comment, $args)
123
+	{
124
+		//gotta make sure this only happens on this route
125
+		$post_type = get_post_type($comment->comment_post_ID);
126
+		if ($post_type === 'espresso_attendees') {
127
+			return '#commentsdiv';
128
+		}
129
+		return $link;
130
+	}
131
+
132
+
133
+	protected function _ajax_hooks()
134
+	{
135
+		//todo: all hooks for registrations ajax goes in here
136
+		add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
137
+	}
138
+
139
+
140
+	protected function _define_page_props()
141
+	{
142
+		$this->_admin_page_title = $this->page_label;
143
+		$this->_labels           = array(
144
+			'buttons'                      => array(
145
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
146
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
147
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
148
+				'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
149
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
150
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
151
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
152
+				'contact_list_export' => esc_html__("Export Data", "event_espresso"),
153
+			),
154
+			'publishbox'                   => array(
155
+				'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
156
+				'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
157
+			),
158
+			'hide_add_button_on_cpt_route' => array(
159
+				'edit_attendee' => true,
160
+			),
161
+		);
162
+	}
163
+
164
+
165
+	/**
166
+	 *        grab url requests and route them
167
+	 *
168
+	 * @access private
169
+	 * @return void
170
+	 */
171
+	public function _set_page_routes()
172
+	{
173
+		$this->_get_registration_status_array();
174
+		$reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
175
+			? $this->_req_data['_REG_ID'] : 0;
176
+		$reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
177
+			? $this->_req_data['reg_status_change_form']['REG_ID']
178
+			: $reg_id;
179
+		$att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
180
+			? $this->_req_data['ATT_ID'] : 0;
181
+		$att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
182
+			? $this->_req_data['post']
183
+			: $att_id;
184
+		$this->_page_routes = array(
185
+			'default'                            => array(
186
+				'func'       => '_registrations_overview_list_table',
187
+				'capability' => 'ee_read_registrations',
188
+			),
189
+			'view_registration'                  => array(
190
+				'func'       => '_registration_details',
191
+				'capability' => 'ee_read_registration',
192
+				'obj_id'     => $reg_id,
193
+			),
194
+			'edit_registration'                  => array(
195
+				'func'               => '_update_attendee_registration_form',
196
+				'noheader'           => true,
197
+				'headers_sent_route' => 'view_registration',
198
+				'capability'         => 'ee_edit_registration',
199
+				'obj_id'             => $reg_id,
200
+				'_REG_ID'            => $reg_id,
201
+			),
202
+			'trash_registrations'                => array(
203
+				'func'       => '_trash_or_restore_registrations',
204
+				'args'       => array('trash' => true),
205
+				'noheader'   => true,
206
+				'capability' => 'ee_delete_registrations',
207
+			),
208
+			'restore_registrations'              => array(
209
+				'func'       => '_trash_or_restore_registrations',
210
+				'args'       => array('trash' => false),
211
+				'noheader'   => true,
212
+				'capability' => 'ee_delete_registrations',
213
+			),
214
+			'delete_registrations'               => array(
215
+				'func'       => '_delete_registrations',
216
+				'noheader'   => true,
217
+				'capability' => 'ee_delete_registrations',
218
+			),
219
+			'new_registration'                   => array(
220
+				'func'       => 'new_registration',
221
+				'capability' => 'ee_edit_registrations',
222
+			),
223
+			'process_reg_step'                   => array(
224
+				'func'       => 'process_reg_step',
225
+				'noheader'   => true,
226
+				'capability' => 'ee_edit_registrations',
227
+			),
228
+			'redirect_to_txn'                    => array(
229
+				'func'       => 'redirect_to_txn',
230
+				'noheader'   => true,
231
+				'capability' => 'ee_edit_registrations',
232
+			),
233
+			'change_reg_status'                  => array(
234
+				'func'       => '_change_reg_status',
235
+				'noheader'   => true,
236
+				'capability' => 'ee_edit_registration',
237
+				'obj_id'     => $reg_id,
238
+			),
239
+			'approve_registration'               => array(
240
+				'func'       => 'approve_registration',
241
+				'noheader'   => true,
242
+				'capability' => 'ee_edit_registration',
243
+				'obj_id'     => $reg_id,
244
+			),
245
+			'approve_and_notify_registration'    => array(
246
+				'func'       => 'approve_registration',
247
+				'noheader'   => true,
248
+				'args'       => array(true),
249
+				'capability' => 'ee_edit_registration',
250
+				'obj_id'     => $reg_id,
251
+			),
252
+			'approve_registrations'               => array(
253
+				'func'       => 'bulk_action_on_registrations',
254
+				'noheader'   => true,
255
+				'capability' => 'ee_edit_registrations',
256
+				'args' => array('approve')
257
+			),
258
+			'approve_and_notify_registrations'               => array(
259
+				'func'       => 'bulk_action_on_registrations',
260
+				'noheader'   => true,
261
+				'capability' => 'ee_edit_registrations',
262
+				'args' => array('approve', true)
263
+			),
264
+			'decline_registration'               => array(
265
+				'func'       => 'decline_registration',
266
+				'noheader'   => true,
267
+				'capability' => 'ee_edit_registration',
268
+				'obj_id'     => $reg_id,
269
+			),
270
+			'decline_and_notify_registration'    => array(
271
+				'func'       => 'decline_registration',
272
+				'noheader'   => true,
273
+				'args'       => array(true),
274
+				'capability' => 'ee_edit_registration',
275
+				'obj_id'     => $reg_id,
276
+			),
277
+			'decline_registrations'               => array(
278
+				'func'       => 'bulk_action_on_registrations',
279
+				'noheader'   => true,
280
+				'capability' => 'ee_edit_registrations',
281
+				'args' => array('decline')
282
+			),
283
+			'decline_and_notify_registrations'    => array(
284
+				'func'       => 'bulk_action_on_registrations',
285
+				'noheader'   => true,
286
+				'capability' => 'ee_edit_registrations',
287
+				'args' => array('decline', true)
288
+			),
289
+			'pending_registration'               => array(
290
+				'func'       => 'pending_registration',
291
+				'noheader'   => true,
292
+				'capability' => 'ee_edit_registration',
293
+				'obj_id'     => $reg_id,
294
+			),
295
+			'pending_and_notify_registration'    => array(
296
+				'func'       => 'pending_registration',
297
+				'noheader'   => true,
298
+				'args'       => array(true),
299
+				'capability' => 'ee_edit_registration',
300
+				'obj_id'     => $reg_id,
301
+			),
302
+			'pending_registrations'               => array(
303
+				'func'       => 'bulk_action_on_registrations',
304
+				'noheader'   => true,
305
+				'capability' => 'ee_edit_registrations',
306
+				'args' => array('pending')
307
+			),
308
+			'pending_and_notify_registrations'    => array(
309
+				'func'       => 'bulk_action_on_registrations',
310
+				'noheader'   => true,
311
+				'capability' => 'ee_edit_registrations',
312
+				'args' => array('pending', true)
313
+			),
314
+			'no_approve_registration'            => array(
315
+				'func'       => 'not_approve_registration',
316
+				'noheader'   => true,
317
+				'capability' => 'ee_edit_registration',
318
+				'obj_id'     => $reg_id,
319
+			),
320
+			'no_approve_and_notify_registration' => array(
321
+				'func'       => 'not_approve_registration',
322
+				'noheader'   => true,
323
+				'args'       => array(true),
324
+				'capability' => 'ee_edit_registration',
325
+				'obj_id'     => $reg_id,
326
+			),
327
+			'no_approve_registrations'            => array(
328
+				'func'       => 'bulk_action_on_registrations',
329
+				'noheader'   => true,
330
+				'capability' => 'ee_edit_registrations',
331
+				'args' => array('not_approve')
332
+			),
333
+			'no_approve_and_notify_registrations' => array(
334
+				'func'       => 'bulk_action_on_registrations',
335
+				'noheader'   => true,
336
+				'capability' => 'ee_edit_registrations',
337
+				'args' => array('not_approve', true)
338
+			),
339
+			'cancel_registration'                => array(
340
+				'func'       => 'cancel_registration',
341
+				'noheader'   => true,
342
+				'capability' => 'ee_edit_registration',
343
+				'obj_id'     => $reg_id,
344
+			),
345
+			'cancel_and_notify_registration'     => array(
346
+				'func'       => 'cancel_registration',
347
+				'noheader'   => true,
348
+				'args'       => array(true),
349
+				'capability' => 'ee_edit_registration',
350
+				'obj_id'     => $reg_id,
351
+			),
352
+			'cancel_registrations'                => array(
353
+				'func'       => 'bulk_action_on_registrations',
354
+				'noheader'   => true,
355
+				'capability' => 'ee_edit_registrations',
356
+				'args' => array('cancel')
357
+			),
358
+			'cancel_and_notify_registrations'     => array(
359
+				'func'       => 'bulk_action_on_registrations',
360
+				'noheader'   => true,
361
+				'capability' => 'ee_edit_registrations',
362
+				'args' => array('cancel', true)
363
+			),
364
+			'wait_list_registration' => array(
365
+				'func'       => 'wait_list_registration',
366
+				'noheader'   => true,
367
+				'capability' => 'ee_edit_registration',
368
+				'obj_id'     => $reg_id,
369
+			),
370
+			'wait_list_and_notify_registration' => array(
371
+				'func'       => 'wait_list_registration',
372
+				'noheader'   => true,
373
+				'args'       => array(true),
374
+				'capability' => 'ee_edit_registration',
375
+				'obj_id'     => $reg_id,
376
+			),
377
+			'contact_list'                       => array(
378
+				'func'       => '_attendee_contact_list_table',
379
+				'capability' => 'ee_read_contacts',
380
+			),
381
+			'add_new_attendee'                   => array(
382
+				'func' => '_create_new_cpt_item',
383
+				'args' => array(
384
+					'new_attendee' => true,
385
+					'capability'   => 'ee_edit_contacts',
386
+				),
387
+			),
388
+			'edit_attendee'                      => array(
389
+				'func'       => '_edit_cpt_item',
390
+				'capability' => 'ee_edit_contacts',
391
+				'obj_id'     => $att_id,
392
+			),
393
+			'duplicate_attendee'                 => array(
394
+				'func'       => '_duplicate_attendee',
395
+				'noheader'   => true,
396
+				'capability' => 'ee_edit_contacts',
397
+				'obj_id'     => $att_id,
398
+			),
399
+			'insert_attendee'                    => array(
400
+				'func'       => '_insert_or_update_attendee',
401
+				'args'       => array(
402
+					'new_attendee' => true,
403
+				),
404
+				'noheader'   => true,
405
+				'capability' => 'ee_edit_contacts',
406
+			),
407
+			'update_attendee'                    => array(
408
+				'func'       => '_insert_or_update_attendee',
409
+				'args'       => array(
410
+					'new_attendee' => false,
411
+				),
412
+				'noheader'   => true,
413
+				'capability' => 'ee_edit_contacts',
414
+				'obj_id'     => $att_id,
415
+			),
416
+			'trash_attendees' => array(
417
+				'func' => '_trash_or_restore_attendees',
418
+				'args' => array(
419
+					'trash' => 'true'
420
+				),
421
+				'noheader' => true,
422
+				'capability' => 'ee_delete_contacts'
423
+			),
424
+			'trash_attendee'                    => array(
425
+				'func'       => '_trash_or_restore_attendees',
426
+				'args'       => array(
427
+					'trash' => true,
428
+				),
429
+				'noheader'   => true,
430
+				'capability' => 'ee_delete_contacts',
431
+				'obj_id'     => $att_id,
432
+			),
433
+			'restore_attendees'                  => array(
434
+				'func'       => '_trash_or_restore_attendees',
435
+				'args'       => array(
436
+					'trash' => false,
437
+				),
438
+				'noheader'   => true,
439
+				'capability' => 'ee_delete_contacts',
440
+				'obj_id'     => $att_id,
441
+			),
442
+			'resend_registration'                => array(
443
+				'func'       => '_resend_registration',
444
+				'noheader'   => true,
445
+				'capability' => 'ee_send_message',
446
+			),
447
+			'registrations_report'               => array(
448
+				'func'       => '_registrations_report',
449
+				'noheader'   => true,
450
+				'capability' => 'ee_read_registrations',
451
+			),
452
+			'contact_list_export'                => array(
453
+				'func'       => '_contact_list_export',
454
+				'noheader'   => true,
455
+				'capability' => 'export',
456
+			),
457
+			'contact_list_report'                => array(
458
+				'func'       => '_contact_list_report',
459
+				'noheader'   => true,
460
+				'capability' => 'ee_read_contacts',
461
+			),
462
+		);
463
+	}
464
+
465
+
466
+	protected function _set_page_config()
467
+	{
468
+		$this->_page_config = array(
469
+			'default'           => array(
470
+				'nav'           => array(
471
+					'label' => esc_html__('Overview', 'event_espresso'),
472
+					'order' => 5,
473
+				),
474
+				'help_tabs'     => array(
475
+					'registrations_overview_help_tab'                       => array(
476
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
477
+						'filename' => 'registrations_overview',
478
+					),
479
+					'registrations_overview_table_column_headings_help_tab' => array(
480
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
481
+						'filename' => 'registrations_overview_table_column_headings',
482
+					),
483
+					'registrations_overview_filters_help_tab'               => array(
484
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
485
+						'filename' => 'registrations_overview_filters',
486
+					),
487
+					'registrations_overview_views_help_tab'                 => array(
488
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
489
+						'filename' => 'registrations_overview_views',
490
+					),
491
+					'registrations_regoverview_other_help_tab'              => array(
492
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
493
+						'filename' => 'registrations_overview_other',
494
+					),
495
+				),
496
+				'help_tour'     => array('Registration_Overview_Help_Tour'),
497
+				'qtips'         => array('Registration_List_Table_Tips'),
498
+				'list_table'    => 'EE_Registrations_List_Table',
499
+				'require_nonce' => false,
500
+			),
501
+			'view_registration' => array(
502
+				'nav'           => array(
503
+					'label'      => esc_html__('REG Details', 'event_espresso'),
504
+					'order'      => 15,
505
+					'url'        => isset($this->_req_data['_REG_ID'])
506
+						? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
507
+						: $this->_admin_base_url,
508
+					'persistent' => false,
509
+				),
510
+				'help_tabs'     => array(
511
+					'registrations_details_help_tab'                    => array(
512
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
513
+						'filename' => 'registrations_details',
514
+					),
515
+					'registrations_details_table_help_tab'              => array(
516
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
517
+						'filename' => 'registrations_details_table',
518
+					),
519
+					'registrations_details_form_answers_help_tab'       => array(
520
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
521
+						'filename' => 'registrations_details_form_answers',
522
+					),
523
+					'registrations_details_registrant_details_help_tab' => array(
524
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
525
+						'filename' => 'registrations_details_registrant_details',
526
+					),
527
+				),
528
+				'help_tour'     => array('Registration_Details_Help_Tour'),
529
+				'metaboxes'     => array_merge(
530
+					$this->_default_espresso_metaboxes,
531
+					array('_registration_details_metaboxes')
532
+				),
533
+				'require_nonce' => false,
534
+			),
535
+			'new_registration'  => array(
536
+				'nav'           => array(
537
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
538
+					'url'        => '#',
539
+					'order'      => 15,
540
+					'persistent' => false,
541
+				),
542
+				'metaboxes'     => $this->_default_espresso_metaboxes,
543
+				'labels'        => array(
544
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
545
+				),
546
+				'require_nonce' => false,
547
+			),
548
+			'add_new_attendee'  => array(
549
+				'nav'           => array(
550
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
551
+					'order'      => 15,
552
+					'persistent' => false,
553
+				),
554
+				'metaboxes'     => array_merge(
555
+					$this->_default_espresso_metaboxes,
556
+					array('_publish_post_box', 'attendee_editor_metaboxes')
557
+				),
558
+				'require_nonce' => false,
559
+			),
560
+			'edit_attendee'     => array(
561
+				'nav'           => array(
562
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
563
+					'order'      => 15,
564
+					'persistent' => false,
565
+					'url'        => isset($this->_req_data['ATT_ID'])
566
+						? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
567
+						: $this->_admin_base_url,
568
+				),
569
+				'metaboxes'     => array('attendee_editor_metaboxes'),
570
+				'require_nonce' => false,
571
+			),
572
+			'contact_list'      => array(
573
+				'nav'           => array(
574
+					'label' => esc_html__('Contact List', 'event_espresso'),
575
+					'order' => 20,
576
+				),
577
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
578
+				'help_tabs'     => array(
579
+					'registrations_contact_list_help_tab'                       => array(
580
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
581
+						'filename' => 'registrations_contact_list',
582
+					),
583
+					'registrations_contact-list_table_column_headings_help_tab' => array(
584
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
585
+						'filename' => 'registrations_contact_list_table_column_headings',
586
+					),
587
+					'registrations_contact_list_views_help_tab'                 => array(
588
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
589
+						'filename' => 'registrations_contact_list_views',
590
+					),
591
+					'registrations_contact_list_other_help_tab'                 => array(
592
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
593
+						'filename' => 'registrations_contact_list_other',
594
+					),
595
+				),
596
+				'help_tour'     => array('Contact_List_Help_Tour'),
597
+				'metaboxes'     => array(),
598
+				'require_nonce' => false,
599
+			),
600
+			//override default cpt routes
601
+			'create_new'        => '',
602
+			'edit'              => '',
603
+		);
604
+	}
605
+
606
+
607
+	/**
608
+	 * The below methods aren't used by this class currently
609
+	 */
610
+	protected function _add_screen_options()
611
+	{
612
+	}
613
+
614
+
615
+	protected function _add_feature_pointers()
616
+	{
617
+	}
618
+
619
+
620
+	public function admin_init()
621
+	{
622
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
623
+			'click "Update Registration Questions" to save your changes',
624
+			'event_espresso'
625
+		);
626
+	}
627
+
628
+
629
+	public function admin_notices()
630
+	{
631
+	}
632
+
633
+
634
+	public function admin_footer_scripts()
635
+	{
636
+	}
637
+
638
+
639
+	/**
640
+	 *        get list of registration statuses
641
+	 *
642
+	 * @access private
643
+	 * @return void
644
+	 * @throws EE_Error
645
+	 */
646
+	private function _get_registration_status_array()
647
+	{
648
+		self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
649
+	}
650
+
651
+
652
+	protected function _add_screen_options_default()
653
+	{
654
+		$this->_per_page_screen_option();
655
+	}
656
+
657
+
658
+	protected function _add_screen_options_contact_list()
659
+	{
660
+		$page_title              = $this->_admin_page_title;
661
+		$this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
662
+		$this->_per_page_screen_option();
663
+		$this->_admin_page_title = $page_title;
664
+	}
665
+
666
+
667
+	public function load_scripts_styles()
668
+	{
669
+		//style
670
+		wp_register_style(
671
+			'espresso_reg',
672
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
673
+			array('ee-admin-css'),
674
+			EVENT_ESPRESSO_VERSION
675
+		);
676
+		wp_enqueue_style('espresso_reg');
677
+		//script
678
+		wp_register_script(
679
+			'espresso_reg',
680
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
681
+			array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
682
+			EVENT_ESPRESSO_VERSION,
683
+			true
684
+		);
685
+		wp_enqueue_script('espresso_reg');
686
+	}
687
+
688
+
689
+	public function load_scripts_styles_edit_attendee()
690
+	{
691
+		//stuff to only show up on our attendee edit details page.
692
+		$attendee_details_translations = array(
693
+			'att_publish_text' => sprintf(
694
+				esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
695
+				$this->_cpt_model_obj->get_datetime('ATT_created')
696
+			),
697
+		);
698
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
699
+		wp_enqueue_script('jquery-validate');
700
+	}
701
+
702
+
703
+	public function load_scripts_styles_view_registration()
704
+	{
705
+		//styles
706
+		wp_enqueue_style('espresso-ui-theme');
707
+		//scripts
708
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
709
+		$this->_reg_custom_questions_form->wp_enqueue_scripts(true);
710
+	}
711
+
712
+
713
+	public function load_scripts_styles_contact_list()
714
+	{
715
+		wp_deregister_style('espresso_reg');
716
+		wp_register_style(
717
+			'espresso_att',
718
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
719
+			array('ee-admin-css'),
720
+			EVENT_ESPRESSO_VERSION
721
+		);
722
+		wp_enqueue_style('espresso_att');
723
+	}
724
+
725
+
726
+	public function load_scripts_styles_new_registration()
727
+	{
728
+		wp_register_script(
729
+			'ee-spco-for-admin',
730
+			REG_ASSETS_URL . 'spco_for_admin.js',
731
+			array('underscore', 'jquery'),
732
+			EVENT_ESPRESSO_VERSION,
733
+			true
734
+		);
735
+		wp_enqueue_script('ee-spco-for-admin');
736
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
737
+		EE_Form_Section_Proper::wp_enqueue_scripts();
738
+		EED_Ticket_Selector::load_tckt_slctr_assets();
739
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
740
+	}
741
+
742
+
743
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
744
+	{
745
+		add_filter('FHEE_load_EE_messages', '__return_true');
746
+	}
747
+
748
+
749
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
750
+	{
751
+		add_filter('FHEE_load_EE_messages', '__return_true');
752
+	}
753
+
754
+
755
+	protected function _set_list_table_views_default()
756
+	{
757
+		//for notification related bulk actions we need to make sure only active messengers have an option.
758
+		EED_Messages::set_autoloaders();
759
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
760
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
761
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
762
+		//key= bulk_action_slug, value= message type.
763
+		$match_array = array(
764
+			'approve_registrations'    => 'registration',
765
+			'decline_registrations'    => 'declined_registration',
766
+			'pending_registrations'    => 'pending_approval',
767
+			'no_approve_registrations' => 'not_approved_registration',
768
+			'cancel_registrations'     => 'cancelled_registration',
769
+		);
770
+		$can_send = EE_Registry::instance()->CAP->current_user_can(
771
+			'ee_send_message',
772
+			'batch_send_messages'
773
+		);
774
+		/** setup reg status bulk actions **/
775
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
776
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
777
+				$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
778
+					'Approve and Notify Registrations',
779
+					'event_espresso'
780
+				);
781
+		}
782
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
783
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
784
+				$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
785
+					'Decline and Notify Registrations',
786
+					'event_espresso'
787
+				);
788
+		}
789
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
790
+			'Set Registrations to Pending Payment',
791
+			'event_espresso'
792
+		);
793
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
794
+				$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
795
+					'Set Registrations to Pending Payment and Notify',
796
+					'event_espresso'
797
+				);
798
+		}
799
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
800
+			'Set Registrations to Not Approved',
801
+			'event_espresso'
802
+		);
803
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
804
+				$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
805
+					'Set Registrations to Not Approved and Notify',
806
+					'event_espresso'
807
+				);
808
+		}
809
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
810
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
811
+				$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
812
+					'Cancel Registrations and Notify',
813
+					'event_espresso'
814
+				);
815
+		}
816
+		$def_reg_status_actions = apply_filters(
817
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
818
+			$def_reg_status_actions,
819
+			$active_mts,
820
+			$can_send
821
+		);
822
+
823
+		$this->_views = array(
824
+			'all'   => array(
825
+				'slug'        => 'all',
826
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
827
+				'count'       => 0,
828
+				'bulk_action' => array_merge($def_reg_status_actions, array(
829
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
830
+				)),
831
+			),
832
+			'month' => array(
833
+				'slug'        => 'month',
834
+				'label'       => esc_html__('This Month', 'event_espresso'),
835
+				'count'       => 0,
836
+				'bulk_action' => array_merge($def_reg_status_actions, array(
837
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
838
+				)),
839
+			),
840
+			'today' => array(
841
+				'slug'        => 'today',
842
+				'label'       => sprintf(
843
+					esc_html__('Today - %s', 'event_espresso'),
844
+					date('M d, Y', current_time('timestamp'))
845
+				),
846
+				'count'       => 0,
847
+				'bulk_action' => array_merge($def_reg_status_actions, array(
848
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
849
+				)),
850
+			),
851
+		);
852
+		if (EE_Registry::instance()->CAP->current_user_can(
853
+			'ee_delete_registrations',
854
+			'espresso_registrations_delete_registration'
855
+		)) {
856
+			$this->_views['incomplete'] = array(
857
+				'slug'        => 'incomplete',
858
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
859
+				'count'       => 0,
860
+				'bulk_action' => array(
861
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
862
+				),
863
+			);
864
+			$this->_views['trash']      = array(
865
+				'slug'        => 'trash',
866
+				'label'       => esc_html__('Trash', 'event_espresso'),
867
+				'count'       => 0,
868
+				'bulk_action' => array(
869
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
870
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
871
+				),
872
+			);
873
+		}
874
+	}
875
+
876
+
877
+	protected function _set_list_table_views_contact_list()
878
+	{
879
+		$this->_views = array(
880
+			'in_use' => array(
881
+				'slug'        => 'in_use',
882
+				'label'       => esc_html__('In Use', 'event_espresso'),
883
+				'count'       => 0,
884
+				'bulk_action' => array(
885
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
886
+				),
887
+			),
888
+		);
889
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
890
+			'espresso_registrations_trash_attendees')
891
+		) {
892
+			$this->_views['trash'] = array(
893
+				'slug'        => 'trash',
894
+				'label'       => esc_html__('Trash', 'event_espresso'),
895
+				'count'       => 0,
896
+				'bulk_action' => array(
897
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
898
+				),
899
+			);
900
+		}
901
+	}
902
+
903
+
904
+	protected function _registration_legend_items()
905
+	{
906
+		$fc_items = array(
907
+			'star-icon'        => array(
908
+				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
909
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
910
+			),
911
+			'view_details'     => array(
912
+				'class' => 'dashicons dashicons-clipboard',
913
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
914
+			),
915
+			'edit_attendee'    => array(
916
+				'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
917
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
918
+			),
919
+			'view_transaction' => array(
920
+				'class' => 'dashicons dashicons-cart',
921
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
922
+			),
923
+			'view_invoice'     => array(
924
+				'class' => 'dashicons dashicons-media-spreadsheet',
925
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
926
+			),
927
+		);
928
+		if (EE_Registry::instance()->CAP->current_user_can(
929
+			'ee_send_message',
930
+			'espresso_registrations_resend_registration'
931
+		)) {
932
+			$fc_items['resend_registration'] = array(
933
+				'class' => 'dashicons dashicons-email-alt',
934
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
935
+			);
936
+		} else {
937
+			$fc_items['blank'] = array('class' => 'blank', 'desc' => '');
938
+		}
939
+		if (EE_Registry::instance()->CAP->current_user_can(
940
+			'ee_read_global_messages',
941
+			'view_filtered_messages'
942
+		)) {
943
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
944
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
945
+				$fc_items['view_related_messages'] = array(
946
+					'class' => $related_for_icon['css_class'],
947
+					'desc'  => $related_for_icon['label'],
948
+				);
949
+			}
950
+		}
951
+		$sc_items = array(
952
+			'approved_status'   => array(
953
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
954
+				'desc'  => EEH_Template::pretty_status(
955
+					EEM_Registration::status_id_approved,
956
+					false,
957
+					'sentence'
958
+				),
959
+			),
960
+			'pending_status'    => array(
961
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
962
+				'desc'  => EEH_Template::pretty_status(
963
+					EEM_Registration::status_id_pending_payment,
964
+					false,
965
+					'sentence'
966
+				),
967
+			),
968
+			'wait_list'         => array(
969
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
970
+				'desc'  => EEH_Template::pretty_status(
971
+					EEM_Registration::status_id_wait_list,
972
+					false,
973
+					'sentence'
974
+				),
975
+			),
976
+			'incomplete_status' => array(
977
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
978
+				'desc'  => EEH_Template::pretty_status(
979
+					EEM_Registration::status_id_incomplete,
980
+					false,
981
+					'sentence'
982
+				),
983
+			),
984
+			'not_approved'      => array(
985
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
986
+				'desc'  => EEH_Template::pretty_status(
987
+					EEM_Registration::status_id_not_approved,
988
+					false,
989
+					'sentence'
990
+				),
991
+			),
992
+			'declined_status'   => array(
993
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
994
+				'desc'  => EEH_Template::pretty_status(
995
+					EEM_Registration::status_id_declined,
996
+					false,
997
+					'sentence'
998
+				),
999
+			),
1000
+			'cancelled_status'  => array(
1001
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1002
+				'desc'  => EEH_Template::pretty_status(
1003
+					EEM_Registration::status_id_cancelled,
1004
+					false,
1005
+					'sentence'
1006
+				),
1007
+			),
1008
+		);
1009
+		return array_merge($fc_items, $sc_items);
1010
+	}
1011
+
1012
+
1013
+
1014
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1015
+	/**
1016
+	 * @throws \EE_Error
1017
+	 */
1018
+	protected function _registrations_overview_list_table()
1019
+	{
1020
+		$this->_template_args['admin_page_header'] = '';
1021
+		$EVT_ID                                    = ! empty($this->_req_data['event_id'])
1022
+			? absint($this->_req_data['event_id'])
1023
+			: 0;
1024
+		if ($EVT_ID) {
1025
+			if (EE_Registry::instance()->CAP->current_user_can(
1026
+				'ee_edit_registrations',
1027
+				'espresso_registrations_new_registration',
1028
+				$EVT_ID
1029
+			)) {
1030
+				$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1031
+					'new_registration',
1032
+					'add-registrant',
1033
+					array('event_id' => $EVT_ID),
1034
+					'add-new-h2'
1035
+				);
1036
+			}
1037
+			$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1038
+			if ($event instanceof EE_Event) {
1039
+				$this->_template_args['admin_page_header'] = sprintf(
1040
+					esc_html__(
1041
+						'%s Viewing registrations for the event: %s%s',
1042
+						'event_espresso'
1043
+					),
1044
+					'<h3 style="line-height:1.5em;">',
1045
+					'<br /><a href="'
1046
+						. EE_Admin_Page::add_query_args_and_nonce(
1047
+							array(
1048
+								'action' => 'edit',
1049
+								'post'   => $event->ID(),
1050
+							),
1051
+							EVENTS_ADMIN_URL
1052
+						)
1053
+						. '">&nbsp;'
1054
+						. $event->get('EVT_name')
1055
+						. '&nbsp;</a>&nbsp;',
1056
+					'</h3>'
1057
+				);
1058
+			}
1059
+			$DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1060
+			$datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1061
+			if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1062
+				$this->_template_args['admin_page_header'] = substr(
1063
+					$this->_template_args['admin_page_header'],
1064
+					0,
1065
+					-5
1066
+				);
1067
+				$this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1068
+				$this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1069
+				$this->_template_args['admin_page_header'] .= $datetime->name();
1070
+				$this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1071
+				$this->_template_args['admin_page_header'] .= '</span></h3>';
1072
+			}
1073
+		}
1074
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1075
+		$this->display_admin_list_table_page_with_no_sidebar();
1076
+	}
1077
+
1078
+
1079
+	/**
1080
+	 * This sets the _registration property for the registration details screen
1081
+	 *
1082
+	 * @access private
1083
+	 * @return bool
1084
+	 * @throws EE_Error
1085
+	 * @throws InvalidArgumentException
1086
+	 * @throws InvalidDataTypeException
1087
+	 * @throws InvalidInterfaceException
1088
+	 */
1089
+	private function _set_registration_object()
1090
+	{
1091
+		//get out if we've already set the object
1092
+		if ($this->_registration instanceof EE_Registration) {
1093
+			return true;
1094
+		}
1095
+		$REG    = EEM_Registration::instance();
1096
+		$REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1097
+		if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1098
+			return true;
1099
+		} else {
1100
+			$error_msg = sprintf(
1101
+				esc_html__(
1102
+					'An error occurred and the details for Registration ID #%s could not be retrieved.',
1103
+					'event_espresso'
1104
+				),
1105
+				$REG_ID
1106
+			);
1107
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1108
+			$this->_registration = null;
1109
+			return false;
1110
+		}
1111
+	}
1112
+
1113
+
1114
+	/**
1115
+	 * Used to retrieve registrations for the list table.
1116
+	 *
1117
+	 * @param int  $per_page
1118
+	 * @param bool $count
1119
+	 * @param bool $this_month
1120
+	 * @param bool $today
1121
+	 * @return EE_Registration[]|int
1122
+	 * @throws EE_Error
1123
+	 * @throws InvalidArgumentException
1124
+	 * @throws InvalidDataTypeException
1125
+	 * @throws InvalidInterfaceException
1126
+	 */
1127
+	public function get_registrations(
1128
+		$per_page = 10,
1129
+		$count = false,
1130
+		$this_month = false,
1131
+		$today = false
1132
+	) {
1133
+		if ($this_month) {
1134
+			$this->_req_data['status'] = 'month';
1135
+		}
1136
+		if ($today) {
1137
+			$this->_req_data['status'] = 'today';
1138
+		}
1139
+		$query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1140
+		/**
1141
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1142
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1143
+		 * @see EEM_Base::get_all()
1144
+		 */
1145
+		$query_params['group_by'] = '';
1146
+
1147
+		return $count
1148
+			? EEM_Registration::instance()->count($query_params)
1149
+			/** @type EE_Registration[] */
1150
+			: EEM_Registration::instance()->get_all($query_params);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1156
+	 * Note: this listens to values on the request for some of the query parameters.
1157
+	 *
1158
+	 * @param array $request
1159
+	 * @param int   $per_page
1160
+	 * @param bool  $count
1161
+	 * @return array
1162
+	 * @throws EE_Error
1163
+	 */
1164
+	protected function _get_registration_query_parameters(
1165
+		$request = array(),
1166
+		$per_page = 10,
1167
+		$count = false
1168
+	) {
1169
+
1170
+		$query_params = array(
1171
+			0                          => $this->_get_where_conditions_for_registrations_query(
1172
+				$request
1173
+			),
1174
+			'caps'                     => EEM_Registration::caps_read_admin,
1175
+			'default_where_conditions' => 'this_model_only',
1176
+		);
1177
+		if (! $count) {
1178
+			$query_params = array_merge(
1179
+				$query_params,
1180
+				$this->_get_orderby_for_registrations_query(),
1181
+				$this->_get_limit($per_page)
1182
+			);
1183
+		}
1184
+
1185
+		return $query_params;
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * This will add EVT_ID to the provided $where array for EE model query parameters.
1191
+	 *
1192
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1193
+	 * @return array
1194
+	 */
1195
+	protected function _add_event_id_to_where_conditions(array $request)
1196
+	{
1197
+		$where = array();
1198
+		if (! empty($request['event_id'])) {
1199
+			$where['EVT_ID'] = absint($request['event_id']);
1200
+		}
1201
+		return $where;
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * Adds category ID if it exists in the request to the where conditions for the registrations query.
1207
+	 *
1208
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1209
+	 * @return array
1210
+	 */
1211
+	protected function _add_category_id_to_where_conditions(array $request)
1212
+	{
1213
+		$where = array();
1214
+		if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1215
+			$where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1216
+		}
1217
+		return $where;
1218
+	}
1219
+
1220
+
1221
+	/**
1222
+	 * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1223
+	 *
1224
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1225
+	 * @return array
1226
+	 */
1227
+	protected function _add_datetime_id_to_where_conditions(array $request)
1228
+	{
1229
+		$where = array();
1230
+		if (! empty($request['datetime_id'])) {
1231
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1232
+		}
1233
+		if (! empty($request['DTT_ID'])) {
1234
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1235
+		}
1236
+		return $where;
1237
+	}
1238
+
1239
+
1240
+	/**
1241
+	 * Adds the correct registration status to the where conditions for the registrations query.
1242
+	 *
1243
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1244
+	 * @return array
1245
+	 */
1246
+	protected function _add_registration_status_to_where_conditions(array $request)
1247
+	{
1248
+		$where = array();
1249
+		$view = EEH_Array::is_set($request, 'status', '');
1250
+		$registration_status = ! empty($request['_reg_status'])
1251
+			? sanitize_text_field($request['_reg_status'])
1252
+			: '';
1253
+
1254
+		/*
1255 1255
          * If filtering by registration status, then we show registrations matching that status.
1256 1256
          * If not filtering by specified status, then we show all registrations excluding incomplete registrations
1257 1257
          * UNLESS viewing trashed registrations.
1258 1258
          */
1259
-        if (! empty($registration_status)) {
1260
-            $where['STS_ID'] = $registration_status;
1261
-        } else {
1262
-            //make sure we exclude incomplete registrations, but only if not trashed.
1263
-            if ($view === 'trash') {
1264
-                $where['REG_deleted'] = true;
1265
-            } elseif ($view === 'incomplete') {
1266
-                $where['STS_ID'] = EEM_Registration::status_id_incomplete;
1267
-            } else {
1268
-                $where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1269
-            }
1270
-        }
1271
-        return $where;
1272
-    }
1273
-
1274
-
1275
-    /**
1276
-     * Adds any provided date restraints to the where conditions for the registrations query.
1277
-     *
1278
-     * @param array $request usually the same as $this->_req_data but not necessarily
1279
-     * @return array
1280
-     * @throws EE_Error
1281
-     * @throws InvalidArgumentException
1282
-     * @throws InvalidDataTypeException
1283
-     * @throws InvalidInterfaceException
1284
-     */
1285
-    protected function _add_date_to_where_conditions(array $request)
1286
-    {
1287
-        $where = array();
1288
-        $view = EEH_Array::is_set($request, 'status', '');
1289
-        $month_range             = ! empty($request['month_range'])
1290
-            ? sanitize_text_field($request['month_range'])
1291
-            : '';
1292
-        $retrieve_for_today      = $view === 'today';
1293
-        $retrieve_for_this_month = $view === 'month';
1294
-
1295
-        if ($retrieve_for_today) {
1296
-            $now               = date('Y-m-d', current_time('timestamp'));
1297
-            $where['REG_date'] = array(
1298
-                'BETWEEN',
1299
-                array(
1300
-                    EEM_Registration::instance()->convert_datetime_for_query(
1301
-                        'REG_date',
1302
-                        $now . ' 00:00:00',
1303
-                        'Y-m-d H:i:s'
1304
-                    ),
1305
-                    EEM_Registration::instance()->convert_datetime_for_query(
1306
-                        'REG_date',
1307
-                        $now . ' 23:59:59',
1308
-                        'Y-m-d H:i:s'
1309
-                    ),
1310
-                ),
1311
-            );
1312
-        } elseif ($retrieve_for_this_month) {
1313
-            $current_year_and_month = date('Y-m', current_time('timestamp'));
1314
-            $days_this_month        = date('t', current_time('timestamp'));
1315
-            $where['REG_date']      = array(
1316
-                'BETWEEN',
1317
-                array(
1318
-                    EEM_Registration::instance()->convert_datetime_for_query(
1319
-                        'REG_date',
1320
-                        $current_year_and_month . '-01 00:00:00',
1321
-                        'Y-m-d H:i:s'
1322
-                    ),
1323
-                    EEM_Registration::instance()->convert_datetime_for_query(
1324
-                        'REG_date',
1325
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1326
-                        'Y-m-d H:i:s'
1327
-                    ),
1328
-                ),
1329
-            );
1330
-        } elseif ($month_range) {
1331
-            $pieces          = explode(' ', $month_range, 3);
1332
-            $month_requested = ! empty($pieces[0])
1333
-                ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1334
-                : '';
1335
-            $year_requested  = ! empty($pieces[1])
1336
-                ? $pieces[1]
1337
-                : '';
1338
-            //if there is not a month or year then we can't go further
1339
-            if ($month_requested && $year_requested) {
1340
-                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1341
-                $where['REG_date'] = array(
1342
-                    'BETWEEN',
1343
-                    array(
1344
-                        EEM_Registration::instance()->convert_datetime_for_query(
1345
-                            'REG_date',
1346
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1347
-                            'Y-m-d H:i:s'
1348
-                        ),
1349
-                        EEM_Registration::instance()->convert_datetime_for_query(
1350
-                            'REG_date',
1351
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1352
-                            'Y-m-d H:i:s'
1353
-                        ),
1354
-                    ),
1355
-                );
1356
-            }
1357
-        }
1358
-        return $where;
1359
-    }
1360
-
1361
-
1362
-    /**
1363
-     * Adds any provided search restraints to the where conditions for the registrations query
1364
-     *
1365
-     * @param array $request usually the same as $this->_req_data but not necessarily
1366
-     * @return array
1367
-     */
1368
-    protected function _add_search_to_where_conditions(array $request)
1369
-    {
1370
-        $where = array();
1371
-        if (! empty($request['s'])) {
1372
-            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1373
-            $where['OR*search_conditions'] = array(
1374
-                'Event.EVT_name'                          => array('LIKE', $search_string),
1375
-                'Event.EVT_desc'                          => array('LIKE', $search_string),
1376
-                'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1377
-                'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1378
-                'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1379
-                'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1380
-                'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1381
-                'Attendee.ATT_email'                      => array('LIKE', $search_string),
1382
-                'Attendee.ATT_address'                    => array('LIKE', $search_string),
1383
-                'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1384
-                'Attendee.ATT_city'                       => array('LIKE', $search_string),
1385
-                'REG_final_price'                         => array('LIKE', $search_string),
1386
-                'REG_code'                                => array('LIKE', $search_string),
1387
-                'REG_count'                               => array('LIKE', $search_string),
1388
-                'REG_group_size'                          => array('LIKE', $search_string),
1389
-                'Ticket.TKT_name'                         => array('LIKE', $search_string),
1390
-                'Ticket.TKT_description'                  => array('LIKE', $search_string),
1391
-                'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1392
-            );
1393
-        }
1394
-        return $where;
1395
-    }
1396
-
1397
-
1398
-    /**
1399
-     * Sets up the where conditions for the registrations query.
1400
-     *
1401
-     * @param array $request
1402
-     * @return array
1403
-     * @throws EE_Error
1404
-     */
1405
-    protected function _get_where_conditions_for_registrations_query($request)
1406
-    {
1407
-        return apply_filters(
1408
-            'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1409
-            array_merge(
1410
-                $this->_add_event_id_to_where_conditions($request),
1411
-                $this->_add_category_id_to_where_conditions($request),
1412
-                $this->_add_datetime_id_to_where_conditions($request),
1413
-                $this->_add_registration_status_to_where_conditions($request),
1414
-                $this->_add_date_to_where_conditions($request),
1415
-                $this->_add_search_to_where_conditions($request)
1416
-            ),
1417
-            $request
1418
-        );
1419
-    }
1420
-
1421
-
1422
-    /**
1423
-     * Sets up the orderby for the registrations query.
1424
-     *
1425
-     * @return array
1426
-     */
1427
-    protected function _get_orderby_for_registrations_query()
1428
-    {
1429
-        $orderby_field = ! empty($this->_req_data['orderby'])
1430
-            ? sanitize_text_field($this->_req_data['orderby'])
1431
-            : '';
1432
-        switch ($orderby_field) {
1433
-            case '_REG_ID':
1434
-                $orderby = array('REG_ID');
1435
-                break;
1436
-            case '_Reg_status':
1437
-                $orderby = array('STS_ID');
1438
-                break;
1439
-            case 'ATT_fname':
1440
-                $orderby = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1441
-                break;
1442
-            case 'ATT_lname':
1443
-                $orderby = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1444
-                break;
1445
-            case 'event_name':
1446
-                $orderby = array('Event.EVT_name');
1447
-                break;
1448
-            case 'DTT_EVT_start':
1449
-                $orderby = array('Event.Datetime.DTT_EVT_start');
1450
-                break;
1451
-            default: //'REG_date'
1452
-                $orderby = array('REG_date');
1453
-        }
1454
-
1455
-        //order
1456
-        $order = ! empty($this->_req_data['order'])
1457
-            ? sanitize_text_field($this->_req_data['order'])
1458
-            : 'DESC';
1459
-        $orderby = array_combine(
1460
-            $orderby,
1461
-            array_fill(0, count($orderby), $order)
1462
-        );
1463
-        //because there are many registrations with the same date, define
1464
-        //a secondary way to order them, otherwise MySQL seems to be a bit random
1465
-        if (empty($orderby['REG_ID'])) {
1466
-            $orderby['REG_ID'] = $order;
1467
-        }
1468
-        return array('order_by' => $orderby);
1469
-    }
1470
-
1471
-
1472
-    /**
1473
-     * Sets up the limit for the registrations query.
1474
-     *
1475
-     * @param $per_page
1476
-     * @return array
1477
-     */
1478
-    protected function _get_limit($per_page)
1479
-    {
1480
-        $current_page = ! empty($this->_req_data['paged'])
1481
-            ? absint($this->_req_data['paged'])
1482
-            : 1;
1483
-        $per_page     = ! empty($this->_req_data['perpage'])
1484
-            ? $this->_req_data['perpage']
1485
-            : $per_page;
1486
-
1487
-        //-1 means return all results so get out if that's set.
1488
-        if ((int)$per_page === -1) {
1489
-            return array();
1490
-        }
1491
-        $per_page = absint($per_page);
1492
-        $offset   = ($current_page - 1) * $per_page;
1493
-        return array('limit' => array($offset, $per_page));
1494
-    }
1495
-
1496
-
1497
-    public function get_registration_status_array()
1498
-    {
1499
-        return self::$_reg_status;
1500
-    }
1501
-
1502
-
1503
-
1504
-
1505
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1506
-    /**
1507
-     *        generates HTML for the View Registration Details Admin page
1508
-     *
1509
-     * @access protected
1510
-     * @return void
1511
-     * @throws DomainException
1512
-     * @throws EE_Error
1513
-     * @throws InvalidArgumentException
1514
-     * @throws InvalidDataTypeException
1515
-     * @throws InvalidInterfaceException
1516
-     * @throws EntityNotFoundException
1517
-     */
1518
-    protected function _registration_details()
1519
-    {
1520
-        $this->_template_args = array();
1521
-        $this->_set_registration_object();
1522
-        if (is_object($this->_registration)) {
1523
-            $transaction                                   = $this->_registration->transaction()
1524
-                ? $this->_registration->transaction()
1525
-                : EE_Transaction::new_instance();
1526
-            $this->_session                                = $transaction->session_data();
1527
-            $event_id                                      = $this->_registration->event_ID();
1528
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1529
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1530
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1531
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1532
-            $this->_template_args['grand_total']           = $transaction->total();
1533
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1534
-            // link back to overview
1535
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1536
-            $this->_template_args['registration']                = $this->_registration;
1537
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1538
-                array(
1539
-                    'action'   => 'default',
1540
-                    'event_id' => $event_id,
1541
-                ),
1542
-                REG_ADMIN_URL
1543
-            );
1544
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1545
-                array(
1546
-                    'action' => 'default',
1547
-                    'EVT_ID' => $event_id,
1548
-                    'page'   => 'espresso_transactions',
1549
-                ),
1550
-                admin_url('admin.php')
1551
-            );
1552
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1553
-                array(
1554
-                    'page'   => 'espresso_events',
1555
-                    'action' => 'edit',
1556
-                    'post'   => $event_id,
1557
-                ),
1558
-                admin_url('admin.php')
1559
-            );
1560
-            //next and previous links
1561
-            $next_reg                                      = $this->_registration->next(
1562
-                null,
1563
-                array(),
1564
-                'REG_ID'
1565
-            );
1566
-            $this->_template_args['next_registration']     = $next_reg
1567
-                ? $this->_next_link(
1568
-                    EE_Admin_Page::add_query_args_and_nonce(
1569
-                        array(
1570
-                            'action'  => 'view_registration',
1571
-                            '_REG_ID' => $next_reg['REG_ID'],
1572
-                        ),
1573
-                        REG_ADMIN_URL
1574
-                    ),
1575
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1576
-                )
1577
-                : '';
1578
-            $previous_reg                                  = $this->_registration->previous(
1579
-                null,
1580
-                array(),
1581
-                'REG_ID'
1582
-            );
1583
-            $this->_template_args['previous_registration'] = $previous_reg
1584
-                ? $this->_previous_link(
1585
-                    EE_Admin_Page::add_query_args_and_nonce(
1586
-                        array(
1587
-                            'action'  => 'view_registration',
1588
-                            '_REG_ID' => $previous_reg['REG_ID'],
1589
-                        ),
1590
-                        REG_ADMIN_URL
1591
-                    ),
1592
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1593
-                )
1594
-                : '';
1595
-            // grab header
1596
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1597
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1598
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1599
-                $template_path,
1600
-                $this->_template_args,
1601
-                true
1602
-            );
1603
-        } else {
1604
-            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1605
-        }
1606
-        // the details template wrapper
1607
-        $this->display_admin_page_with_sidebar();
1608
-    }
1609
-
1610
-
1611
-    protected function _registration_details_metaboxes()
1612
-    {
1613
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1614
-        $this->_set_registration_object();
1615
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1616
-        add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1617
-            array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1618
-        add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1619
-            array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1620
-        if ($attendee instanceof EE_Attendee
1621
-            && EE_Registry::instance()->CAP->current_user_can(
1622
-                'ee_edit_registration',
1623
-                'edit-reg-questions-mbox',
1624
-                $this->_registration->ID()
1625
-            )
1626
-        ) {
1627
-            add_meta_box(
1628
-                'edit-reg-questions-mbox',
1629
-                esc_html__('Registration Form Answers', 'event_espresso'),
1630
-                array($this, '_reg_questions_meta_box'),
1631
-                $this->wp_page_slug,
1632
-                'normal',
1633
-                'high'
1634
-            );
1635
-        }
1636
-        add_meta_box(
1637
-            'edit-reg-registrant-mbox',
1638
-            esc_html__('Contact Details', 'event_espresso'),
1639
-            array($this, '_reg_registrant_side_meta_box'),
1640
-            $this->wp_page_slug,
1641
-            'side',
1642
-            'high'
1643
-        );
1644
-        if ($this->_registration->group_size() > 1) {
1645
-            add_meta_box(
1646
-                'edit-reg-attendees-mbox',
1647
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1648
-                array($this, '_reg_attendees_meta_box'),
1649
-                $this->wp_page_slug,
1650
-                'normal',
1651
-                'high'
1652
-            );
1653
-        }
1654
-    }
1655
-
1656
-
1657
-    /**
1658
-     * set_reg_status_buttons_metabox
1659
-     *
1660
-     * @access protected
1661
-     * @return string
1662
-     * @throws \EE_Error
1663
-     */
1664
-    public function set_reg_status_buttons_metabox()
1665
-    {
1666
-        $this->_set_registration_object();
1667
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1668
-        echo $change_reg_status_form->form_open(
1669
-            self::add_query_args_and_nonce(
1670
-                array(
1671
-                    'action' => 'change_reg_status',
1672
-                ),
1673
-                REG_ADMIN_URL
1674
-            )
1675
-        );
1676
-        echo $change_reg_status_form->get_html();
1677
-        echo $change_reg_status_form->form_close();
1678
-    }
1679
-
1680
-
1681
-    /**
1682
-     * @return EE_Form_Section_Proper
1683
-     * @throws EE_Error
1684
-     * @throws InvalidArgumentException
1685
-     * @throws InvalidDataTypeException
1686
-     * @throws InvalidInterfaceException
1687
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1688
-     */
1689
-    protected function _generate_reg_status_change_form()
1690
-    {
1691
-        return new EE_Form_Section_Proper(array(
1692
-            'name'            => 'reg_status_change_form',
1693
-            'html_id'         => 'reg-status-change-form',
1694
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1695
-            'subsections'     => array(
1696
-                'return'             => new EE_Hidden_Input(array(
1697
-                    'name'    => 'return',
1698
-                    'default' => 'view_registration',
1699
-                )),
1700
-                'REG_ID'             => new EE_Hidden_Input(array(
1701
-                    'name'    => 'REG_ID',
1702
-                    'default' => $this->_registration->ID(),
1703
-                )),
1704
-                'current_status'     => new EE_Form_Section_HTML(
1705
-                    EEH_HTML::tr(
1706
-                        EEH_HTML::th(
1707
-                            EEH_HTML::label(
1708
-                                EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1709
-                                )
1710
-                            )
1711
-                        )
1712
-                        . EEH_HTML::td(
1713
-                            EEH_HTML::strong(
1714
-                                $this->_registration->pretty_status(),
1715
-                                '',
1716
-                                'status-' . $this->_registration->status_ID(),
1717
-                                'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1718
-                            )
1719
-                        )
1720
-                    )
1721
-                ),
1722
-                'reg_status'         => new EE_Select_Input(
1723
-                    $this->_get_reg_statuses(),
1724
-                    array(
1725
-                        'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1726
-                        'default'         => $this->_registration->status_ID(),
1727
-                    )
1728
-                ),
1729
-                'send_notifications' => new EE_Yes_No_Input(
1730
-                    array(
1731
-                        'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1732
-                        'default'         => false,
1733
-                        'html_help_text'  => esc_html__(
1734
-                            'If set to "Yes", then the related messages will be sent to the registrant.',
1735
-                            'event_espresso'
1736
-                        ),
1737
-                    )
1738
-                ),
1739
-                'submit'             => new EE_Submit_Input(
1740
-                    array(
1741
-                        'html_class'      => 'button-primary',
1742
-                        'html_label_text' => '&nbsp;',
1743
-                        'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1744
-                    )
1745
-                ),
1746
-            ),
1747
-        ));
1748
-    }
1749
-
1750
-
1751
-    /**
1752
-     * Returns an array of all the buttons for the various statuses and switch status actions
1753
-     *
1754
-     * @return array
1755
-     * @throws EE_Error
1756
-     * @throws InvalidArgumentException
1757
-     * @throws InvalidDataTypeException
1758
-     * @throws InvalidInterfaceException
1759
-     * @throws EntityNotFoundException
1760
-     */
1761
-    protected function _get_reg_statuses()
1762
-    {
1763
-        $reg_status_array = EEM_Registration::instance()->reg_status_array();
1764
-        unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1765
-        // get current reg status
1766
-        $current_status = $this->_registration->status_ID();
1767
-        // is registration for free event? This will determine whether to display the pending payment option
1768
-        if (
1769
-            $current_status !== EEM_Registration::status_id_pending_payment
1770
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1771
-        ) {
1772
-            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1773
-        }
1774
-        return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1775
-    }
1776
-
1777
-
1778
-    /**
1779
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1780
-     *
1781
-     * @param bool $status REG status given for changing registrations to.
1782
-     * @param bool $notify Whether to send messages notifications or not.
1783
-     * @return array (array with reg_id(s) updated and whether update was successful.
1784
-     * @throws EE_Error
1785
-     * @throws InvalidArgumentException
1786
-     * @throws InvalidDataTypeException
1787
-     * @throws InvalidInterfaceException
1788
-     * @throws ReflectionException
1789
-     * @throws RuntimeException
1790
-     * @throws EntityNotFoundException
1791
-     */
1792
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1793
-    {
1794
-        if (isset($this->_req_data['reg_status_change_form'])) {
1795
-            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1796
-                ? (array)$this->_req_data['reg_status_change_form']['REG_ID']
1797
-                : array();
1798
-        } else {
1799
-            $REG_IDs = isset($this->_req_data['_REG_ID'])
1800
-                ? (array)$this->_req_data['_REG_ID']
1801
-                : array();
1802
-        }
1803
-        // sanitize $REG_IDs
1804
-        $REG_IDs = array_map('absint', $REG_IDs);
1805
-        // and remove empty entries
1806
-        $REG_IDs = array_filter($REG_IDs);
1807
-
1808
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1809
-
1810
-        /**
1811
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1812
-         * Currently this value is used downstream by the _process_resend_registration method.
1813
-         *
1814
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1815
-         * @param bool                     $status           The status registrations were changed to.
1816
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1817
-         * @param Registrations_Admin_Page $admin_page_object
1818
-         */
1819
-        $this->_req_data['_REG_ID'] = apply_filters(
1820
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1821
-            $result['REG_ID'],
1822
-            $status,
1823
-            $result['success'],
1824
-            $this
1825
-        );
1826
-
1827
-        //notify?
1828
-        if ($notify
1829
-            && $result['success']
1830
-            && ! empty($this->_req_data['_REG_ID'])
1831
-            && EE_Registry::instance()->CAP->current_user_can(
1832
-                'ee_send_message',
1833
-                'espresso_registrations_resend_registration'
1834
-            )
1835
-        ) {
1836
-            $this->_process_resend_registration();
1837
-        }
1838
-        return $result;
1839
-    }
1840
-
1841
-
1842
-    /**
1843
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1844
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1845
-     *
1846
-     * @param array  $REG_IDs
1847
-     * @param string $status
1848
-     * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1849
-     *                        slug sent with setting the registration status.
1850
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1851
-     * @throws EE_Error
1852
-     * @throws InvalidArgumentException
1853
-     * @throws InvalidDataTypeException
1854
-     * @throws InvalidInterfaceException
1855
-     * @throws ReflectionException
1856
-     * @throws RuntimeException
1857
-     * @throws EntityNotFoundException
1858
-     */
1859
-    protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1860
-    {
1861
-        $success = false;
1862
-        // typecast $REG_IDs
1863
-        $REG_IDs = (array)$REG_IDs;
1864
-        if ( ! empty($REG_IDs)) {
1865
-            $success = true;
1866
-            // set default status if none is passed
1867
-            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1868
-            $status_context = $notify
1869
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1870
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1871
-            //loop through REG_ID's and change status
1872
-            foreach ($REG_IDs as $REG_ID) {
1873
-                $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1874
-                if ($registration instanceof EE_Registration) {
1875
-                    $registration->set_status(
1876
-                        $status,
1877
-                        false,
1878
-                        new Context(
1879
-                            $status_context,
1880
-                            esc_html__(
1881
-                                'Manually triggered status change on a Registration Admin Page route.',
1882
-                                'event_espresso'
1883
-                            )
1884
-                        )
1885
-                    );
1886
-                    $result = $registration->save();
1887
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1888
-                    $success = $result !== false ? $success : false;
1889
-                }
1890
-            }
1891
-        }
1892
-
1893
-        //return $success and processed registrations
1894
-        return array('REG_ID' => $REG_IDs, 'success' => $success);
1895
-    }
1896
-
1897
-
1898
-    /**
1899
-     * Common logic for setting up success message and redirecting to appropriate route
1900
-     *
1901
-     * @param  string $STS_ID status id for the registration changed to
1902
-     * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1903
-     * @return void
1904
-     * @throws EE_Error
1905
-     */
1906
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1907
-    {
1908
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1909
-            : array('success' => false);
1910
-        $success = isset($result['success']) && $result['success'];
1911
-        //setup success message
1912
-        if ($success) {
1913
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1914
-                $msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1915
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1916
-            } else {
1917
-                $msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1918
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1919
-            }
1920
-            EE_Error::add_success($msg);
1921
-        } else {
1922
-            EE_Error::add_error(
1923
-                esc_html__(
1924
-                    'Something went wrong, and the status was not changed',
1925
-                    'event_espresso'
1926
-                ), __FILE__, __LINE__, __FUNCTION__
1927
-            );
1928
-        }
1929
-        if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1930
-            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1931
-        } else {
1932
-            $route = array('action' => 'default');
1933
-        }
1934
-        //unset nonces
1935
-        foreach ($this->_req_data as $ref => $value) {
1936
-            if (strpos($ref, 'nonce') !== false) {
1937
-                unset($this->_req_data[$ref]);
1938
-                continue;
1939
-            }
1940
-            $value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1941
-            $this->_req_data[$ref] = $value;
1942
-        }
1943
-        //merge request vars so that the reloaded list table contains any existing filter query params
1944
-        $route = array_merge($this->_req_data, $route);
1945
-        $this->_redirect_after_action($success, '', '', $route, true);
1946
-    }
1947
-
1948
-
1949
-    /**
1950
-     * incoming reg status change from reg details page.
1951
-     *
1952
-     * @return void
1953
-     */
1954
-    protected function _change_reg_status()
1955
-    {
1956
-        $this->_req_data['return'] = 'view_registration';
1957
-        //set notify based on whether the send notifications toggle is set or not
1958
-        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1959
-        //$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1960
-        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1961
-            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1962
-        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1963
-            case EEM_Registration::status_id_approved :
1964
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
1965
-                $this->approve_registration($notify);
1966
-                break;
1967
-            case EEM_Registration::status_id_pending_payment :
1968
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
1969
-                $this->pending_registration($notify);
1970
-                break;
1971
-            case EEM_Registration::status_id_not_approved :
1972
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
1973
-                $this->not_approve_registration($notify);
1974
-                break;
1975
-            case EEM_Registration::status_id_declined :
1976
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
1977
-                $this->decline_registration($notify);
1978
-                break;
1979
-            case EEM_Registration::status_id_cancelled :
1980
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
1981
-                $this->cancel_registration($notify);
1982
-                break;
1983
-            case EEM_Registration::status_id_wait_list :
1984
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
1985
-                $this->wait_list_registration($notify);
1986
-                break;
1987
-            case EEM_Registration::status_id_incomplete :
1988
-            default :
1989
-                $result['success'] = false;
1990
-                unset($this->_req_data['return']);
1991
-                $this->_reg_status_change_return('', false);
1992
-                break;
1993
-        }
1994
-    }
1995
-
1996
-
1997
-    /**
1998
-     * Callback for bulk action routes.
1999
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
2000
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
2001
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
2002
-     * when an action is happening on just a single registration).
2003
-     * @param      $action
2004
-     * @param bool $notify
2005
-     */
2006
-    protected function bulk_action_on_registrations($action, $notify = false) {
2007
-        do_action(
2008
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
2009
-            $this,
2010
-            $action,
2011
-            $notify
2012
-        );
2013
-        $method = $action . '_registration';
2014
-        if (method_exists($this, $method)) {
2015
-            $this->$method($notify);
2016
-        }
2017
-    }
2018
-
2019
-
2020
-    /**
2021
-     * approve_registration
2022
-     *
2023
-     * @access protected
2024
-     * @param bool $notify whether or not to notify the registrant about their approval.
2025
-     * @return void
2026
-     */
2027
-    protected function approve_registration($notify = false)
2028
-    {
2029
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
2030
-    }
2031
-
2032
-
2033
-    /**
2034
-     *        decline_registration
2035
-     *
2036
-     * @access protected
2037
-     * @param bool $notify whether or not to notify the registrant about their status change.
2038
-     * @return void
2039
-     */
2040
-    protected function decline_registration($notify = false)
2041
-    {
2042
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
2043
-    }
2044
-
2045
-
2046
-    /**
2047
-     *        cancel_registration
2048
-     *
2049
-     * @access protected
2050
-     * @param bool $notify whether or not to notify the registrant about their status change.
2051
-     * @return void
2052
-     */
2053
-    protected function cancel_registration($notify = false)
2054
-    {
2055
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
2056
-    }
2057
-
2058
-
2059
-    /**
2060
-     *        not_approve_registration
2061
-     *
2062
-     * @access protected
2063
-     * @param bool $notify whether or not to notify the registrant about their status change.
2064
-     * @return void
2065
-     */
2066
-    protected function not_approve_registration($notify = false)
2067
-    {
2068
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
2069
-    }
2070
-
2071
-
2072
-    /**
2073
-     *        decline_registration
2074
-     *
2075
-     * @access protected
2076
-     * @param bool $notify whether or not to notify the registrant about their status change.
2077
-     * @return void
2078
-     */
2079
-    protected function pending_registration($notify = false)
2080
-    {
2081
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
2082
-    }
2083
-
2084
-
2085
-    /**
2086
-     * waitlist_registration
2087
-     *
2088
-     * @access protected
2089
-     * @param bool $notify whether or not to notify the registrant about their status change.
2090
-     * @return void
2091
-     */
2092
-    protected function wait_list_registration($notify = false)
2093
-    {
2094
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2095
-    }
2096
-
2097
-
2098
-    /**
2099
-     *        generates HTML for the Registration main meta box
2100
-     *
2101
-     * @access public
2102
-     * @return void
2103
-     * @throws DomainException
2104
-     * @throws EE_Error
2105
-     * @throws InvalidArgumentException
2106
-     * @throws InvalidDataTypeException
2107
-     * @throws InvalidInterfaceException
2108
-     * @throws ReflectionException
2109
-     * @throws EntityNotFoundException
2110
-     */
2111
-    public function _reg_details_meta_box()
2112
-    {
2113
-        EEH_Autoloader::register_line_item_display_autoloaders();
2114
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2115
-        EE_Registry::instance()->load_helper('Line_Item');
2116
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2117
-            : EE_Transaction::new_instance();
2118
-        $this->_session = $transaction->session_data();
2119
-        $filters        = new EE_Line_Item_Filter_Collection();
2120
-        //$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2121
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2122
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2123
-            $transaction->total_line_item());
2124
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2125
-        $line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2126
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2127
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2128
-            $filtered_line_item_tree,
2129
-            array('EE_Registration' => $this->_registration)
2130
-        );
2131
-        $attendee                                = $this->_registration->attendee();
2132
-        if (EE_Registry::instance()->CAP->current_user_can(
2133
-            'ee_read_transaction',
2134
-            'espresso_transactions_view_transaction'
2135
-        )) {
2136
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2137
-                EE_Admin_Page::add_query_args_and_nonce(
2138
-                    array(
2139
-                        'action' => 'view_transaction',
2140
-                        'TXN_ID' => $transaction->ID(),
2141
-                    ),
2142
-                    TXN_ADMIN_URL
2143
-                ),
2144
-                esc_html__(' View Transaction', 'event_espresso'),
2145
-                'button secondary-button right',
2146
-                'dashicons dashicons-cart'
2147
-            );
2148
-        } else {
2149
-            $this->_template_args['view_transaction_button'] = '';
2150
-        }
2151
-        if ($attendee instanceof EE_Attendee
2152
-            && EE_Registry::instance()->CAP->current_user_can(
2153
-                'ee_send_message',
2154
-                'espresso_registrations_resend_registration'
2155
-            )
2156
-        ) {
2157
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2158
-                EE_Admin_Page::add_query_args_and_nonce(
2159
-                    array(
2160
-                        'action'      => 'resend_registration',
2161
-                        '_REG_ID'     => $this->_registration->ID(),
2162
-                        'redirect_to' => 'view_registration',
2163
-                    ),
2164
-                    REG_ADMIN_URL
2165
-                ),
2166
-                esc_html__(' Resend Registration', 'event_espresso'),
2167
-                'button secondary-button right',
2168
-                'dashicons dashicons-email-alt'
2169
-            );
2170
-        } else {
2171
-            $this->_template_args['resend_registration_button'] = '';
2172
-        }
2173
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2174
-        $payment                               = $transaction->get_first_related('Payment');
2175
-        $payment                               = ! $payment instanceof EE_Payment
2176
-            ? EE_Payment::new_instance()
2177
-            : $payment;
2178
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2179
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2180
-            ? EE_Payment_Method::new_instance()
2181
-            : $payment_method;
2182
-        $reg_details                           = array(
2183
-            'payment_method'       => $payment_method->name(),
2184
-            'response_msg'         => $payment->gateway_response(),
2185
-            'registration_id'      => $this->_registration->get('REG_code'),
2186
-            'registration_session' => $this->_registration->session_ID(),
2187
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2188
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2189
-        );
2190
-        if (isset($reg_details['registration_id'])) {
2191
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2192
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2193
-                'Registration ID',
2194
-                'event_espresso'
2195
-            );
2196
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2197
-        }
2198
-        if (isset($reg_details['payment_method'])) {
2199
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2200
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2201
-                'Most Recent Payment Method',
2202
-                'event_espresso'
2203
-            );
2204
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2205
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2206
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2207
-                'Payment method response',
2208
-                'event_espresso'
2209
-            );
2210
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2211
-        }
2212
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2213
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2214
-            'Registration Session',
2215
-            'event_espresso'
2216
-        );
2217
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2218
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2219
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2220
-            'Registration placed from IP',
2221
-            'event_espresso'
2222
-        );
2223
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2224
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2225
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2226
-            'event_espresso');
2227
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2228
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2229
-            array(
2230
-                'action'   => 'default',
2231
-                'event_id' => $this->_registration->event_ID(),
2232
-            ),
2233
-            REG_ADMIN_URL
2234
-        );
2235
-        $this->_template_args['REG_ID']                                       = $this->_registration->ID();
2236
-        $this->_template_args['event_id']                                     = $this->_registration->event_ID();
2237
-        $template_path                                                        =
2238
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2239
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2240
-    }
2241
-
2242
-
2243
-    /**
2244
-     * generates HTML for the Registration Questions meta box.
2245
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2246
-     * otherwise uses new forms system
2247
-     *
2248
-     * @access public
2249
-     * @return void
2250
-     * @throws DomainException
2251
-     * @throws EE_Error
2252
-     */
2253
-    public function _reg_questions_meta_box()
2254
-    {
2255
-        //allow someone to override this method entirely
2256
-        if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2257
-            $this->_registration)) {
2258
-            $form                                              = $this->_get_reg_custom_questions_form(
2259
-                $this->_registration->ID()
2260
-            );
2261
-            $this->_template_args['att_questions']             = count($form->subforms()) > 0
2262
-                ? $form->get_html_and_js()
2263
-                : '';
2264
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2265
-            $this->_template_args['REG_ID']                    = $this->_registration->ID();
2266
-            $template_path                                     =
2267
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2268
-            echo EEH_Template::display_template($template_path, $this->_template_args, true);
2269
-        }
2270
-    }
2271
-
2272
-
2273
-    /**
2274
-     * form_before_question_group
2275
-     *
2276
-     * @deprecated    as of 4.8.32.rc.000
2277
-     * @access        public
2278
-     * @param        string $output
2279
-     * @return        string
2280
-     */
2281
-    public function form_before_question_group($output)
2282
-    {
2283
-        EE_Error::doing_it_wrong(
2284
-            __CLASS__ . '::' . __FUNCTION__,
2285
-            esc_html__(
2286
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2287
-                'event_espresso'
2288
-            ),
2289
-            '4.8.32.rc.000'
2290
-        );
2291
-        return '
1259
+		if (! empty($registration_status)) {
1260
+			$where['STS_ID'] = $registration_status;
1261
+		} else {
1262
+			//make sure we exclude incomplete registrations, but only if not trashed.
1263
+			if ($view === 'trash') {
1264
+				$where['REG_deleted'] = true;
1265
+			} elseif ($view === 'incomplete') {
1266
+				$where['STS_ID'] = EEM_Registration::status_id_incomplete;
1267
+			} else {
1268
+				$where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1269
+			}
1270
+		}
1271
+		return $where;
1272
+	}
1273
+
1274
+
1275
+	/**
1276
+	 * Adds any provided date restraints to the where conditions for the registrations query.
1277
+	 *
1278
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1279
+	 * @return array
1280
+	 * @throws EE_Error
1281
+	 * @throws InvalidArgumentException
1282
+	 * @throws InvalidDataTypeException
1283
+	 * @throws InvalidInterfaceException
1284
+	 */
1285
+	protected function _add_date_to_where_conditions(array $request)
1286
+	{
1287
+		$where = array();
1288
+		$view = EEH_Array::is_set($request, 'status', '');
1289
+		$month_range             = ! empty($request['month_range'])
1290
+			? sanitize_text_field($request['month_range'])
1291
+			: '';
1292
+		$retrieve_for_today      = $view === 'today';
1293
+		$retrieve_for_this_month = $view === 'month';
1294
+
1295
+		if ($retrieve_for_today) {
1296
+			$now               = date('Y-m-d', current_time('timestamp'));
1297
+			$where['REG_date'] = array(
1298
+				'BETWEEN',
1299
+				array(
1300
+					EEM_Registration::instance()->convert_datetime_for_query(
1301
+						'REG_date',
1302
+						$now . ' 00:00:00',
1303
+						'Y-m-d H:i:s'
1304
+					),
1305
+					EEM_Registration::instance()->convert_datetime_for_query(
1306
+						'REG_date',
1307
+						$now . ' 23:59:59',
1308
+						'Y-m-d H:i:s'
1309
+					),
1310
+				),
1311
+			);
1312
+		} elseif ($retrieve_for_this_month) {
1313
+			$current_year_and_month = date('Y-m', current_time('timestamp'));
1314
+			$days_this_month        = date('t', current_time('timestamp'));
1315
+			$where['REG_date']      = array(
1316
+				'BETWEEN',
1317
+				array(
1318
+					EEM_Registration::instance()->convert_datetime_for_query(
1319
+						'REG_date',
1320
+						$current_year_and_month . '-01 00:00:00',
1321
+						'Y-m-d H:i:s'
1322
+					),
1323
+					EEM_Registration::instance()->convert_datetime_for_query(
1324
+						'REG_date',
1325
+						$current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1326
+						'Y-m-d H:i:s'
1327
+					),
1328
+				),
1329
+			);
1330
+		} elseif ($month_range) {
1331
+			$pieces          = explode(' ', $month_range, 3);
1332
+			$month_requested = ! empty($pieces[0])
1333
+				? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1334
+				: '';
1335
+			$year_requested  = ! empty($pieces[1])
1336
+				? $pieces[1]
1337
+				: '';
1338
+			//if there is not a month or year then we can't go further
1339
+			if ($month_requested && $year_requested) {
1340
+				$days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1341
+				$where['REG_date'] = array(
1342
+					'BETWEEN',
1343
+					array(
1344
+						EEM_Registration::instance()->convert_datetime_for_query(
1345
+							'REG_date',
1346
+							$year_requested . '-' . $month_requested . '-01 00:00:00',
1347
+							'Y-m-d H:i:s'
1348
+						),
1349
+						EEM_Registration::instance()->convert_datetime_for_query(
1350
+							'REG_date',
1351
+							$year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1352
+							'Y-m-d H:i:s'
1353
+						),
1354
+					),
1355
+				);
1356
+			}
1357
+		}
1358
+		return $where;
1359
+	}
1360
+
1361
+
1362
+	/**
1363
+	 * Adds any provided search restraints to the where conditions for the registrations query
1364
+	 *
1365
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1366
+	 * @return array
1367
+	 */
1368
+	protected function _add_search_to_where_conditions(array $request)
1369
+	{
1370
+		$where = array();
1371
+		if (! empty($request['s'])) {
1372
+			$search_string = '%' . sanitize_text_field($request['s']) . '%';
1373
+			$where['OR*search_conditions'] = array(
1374
+				'Event.EVT_name'                          => array('LIKE', $search_string),
1375
+				'Event.EVT_desc'                          => array('LIKE', $search_string),
1376
+				'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1377
+				'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1378
+				'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1379
+				'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1380
+				'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1381
+				'Attendee.ATT_email'                      => array('LIKE', $search_string),
1382
+				'Attendee.ATT_address'                    => array('LIKE', $search_string),
1383
+				'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1384
+				'Attendee.ATT_city'                       => array('LIKE', $search_string),
1385
+				'REG_final_price'                         => array('LIKE', $search_string),
1386
+				'REG_code'                                => array('LIKE', $search_string),
1387
+				'REG_count'                               => array('LIKE', $search_string),
1388
+				'REG_group_size'                          => array('LIKE', $search_string),
1389
+				'Ticket.TKT_name'                         => array('LIKE', $search_string),
1390
+				'Ticket.TKT_description'                  => array('LIKE', $search_string),
1391
+				'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1392
+			);
1393
+		}
1394
+		return $where;
1395
+	}
1396
+
1397
+
1398
+	/**
1399
+	 * Sets up the where conditions for the registrations query.
1400
+	 *
1401
+	 * @param array $request
1402
+	 * @return array
1403
+	 * @throws EE_Error
1404
+	 */
1405
+	protected function _get_where_conditions_for_registrations_query($request)
1406
+	{
1407
+		return apply_filters(
1408
+			'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1409
+			array_merge(
1410
+				$this->_add_event_id_to_where_conditions($request),
1411
+				$this->_add_category_id_to_where_conditions($request),
1412
+				$this->_add_datetime_id_to_where_conditions($request),
1413
+				$this->_add_registration_status_to_where_conditions($request),
1414
+				$this->_add_date_to_where_conditions($request),
1415
+				$this->_add_search_to_where_conditions($request)
1416
+			),
1417
+			$request
1418
+		);
1419
+	}
1420
+
1421
+
1422
+	/**
1423
+	 * Sets up the orderby for the registrations query.
1424
+	 *
1425
+	 * @return array
1426
+	 */
1427
+	protected function _get_orderby_for_registrations_query()
1428
+	{
1429
+		$orderby_field = ! empty($this->_req_data['orderby'])
1430
+			? sanitize_text_field($this->_req_data['orderby'])
1431
+			: '';
1432
+		switch ($orderby_field) {
1433
+			case '_REG_ID':
1434
+				$orderby = array('REG_ID');
1435
+				break;
1436
+			case '_Reg_status':
1437
+				$orderby = array('STS_ID');
1438
+				break;
1439
+			case 'ATT_fname':
1440
+				$orderby = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1441
+				break;
1442
+			case 'ATT_lname':
1443
+				$orderby = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1444
+				break;
1445
+			case 'event_name':
1446
+				$orderby = array('Event.EVT_name');
1447
+				break;
1448
+			case 'DTT_EVT_start':
1449
+				$orderby = array('Event.Datetime.DTT_EVT_start');
1450
+				break;
1451
+			default: //'REG_date'
1452
+				$orderby = array('REG_date');
1453
+		}
1454
+
1455
+		//order
1456
+		$order = ! empty($this->_req_data['order'])
1457
+			? sanitize_text_field($this->_req_data['order'])
1458
+			: 'DESC';
1459
+		$orderby = array_combine(
1460
+			$orderby,
1461
+			array_fill(0, count($orderby), $order)
1462
+		);
1463
+		//because there are many registrations with the same date, define
1464
+		//a secondary way to order them, otherwise MySQL seems to be a bit random
1465
+		if (empty($orderby['REG_ID'])) {
1466
+			$orderby['REG_ID'] = $order;
1467
+		}
1468
+		return array('order_by' => $orderby);
1469
+	}
1470
+
1471
+
1472
+	/**
1473
+	 * Sets up the limit for the registrations query.
1474
+	 *
1475
+	 * @param $per_page
1476
+	 * @return array
1477
+	 */
1478
+	protected function _get_limit($per_page)
1479
+	{
1480
+		$current_page = ! empty($this->_req_data['paged'])
1481
+			? absint($this->_req_data['paged'])
1482
+			: 1;
1483
+		$per_page     = ! empty($this->_req_data['perpage'])
1484
+			? $this->_req_data['perpage']
1485
+			: $per_page;
1486
+
1487
+		//-1 means return all results so get out if that's set.
1488
+		if ((int)$per_page === -1) {
1489
+			return array();
1490
+		}
1491
+		$per_page = absint($per_page);
1492
+		$offset   = ($current_page - 1) * $per_page;
1493
+		return array('limit' => array($offset, $per_page));
1494
+	}
1495
+
1496
+
1497
+	public function get_registration_status_array()
1498
+	{
1499
+		return self::$_reg_status;
1500
+	}
1501
+
1502
+
1503
+
1504
+
1505
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1506
+	/**
1507
+	 *        generates HTML for the View Registration Details Admin page
1508
+	 *
1509
+	 * @access protected
1510
+	 * @return void
1511
+	 * @throws DomainException
1512
+	 * @throws EE_Error
1513
+	 * @throws InvalidArgumentException
1514
+	 * @throws InvalidDataTypeException
1515
+	 * @throws InvalidInterfaceException
1516
+	 * @throws EntityNotFoundException
1517
+	 */
1518
+	protected function _registration_details()
1519
+	{
1520
+		$this->_template_args = array();
1521
+		$this->_set_registration_object();
1522
+		if (is_object($this->_registration)) {
1523
+			$transaction                                   = $this->_registration->transaction()
1524
+				? $this->_registration->transaction()
1525
+				: EE_Transaction::new_instance();
1526
+			$this->_session                                = $transaction->session_data();
1527
+			$event_id                                      = $this->_registration->event_ID();
1528
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1529
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1530
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1531
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1532
+			$this->_template_args['grand_total']           = $transaction->total();
1533
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1534
+			// link back to overview
1535
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1536
+			$this->_template_args['registration']                = $this->_registration;
1537
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1538
+				array(
1539
+					'action'   => 'default',
1540
+					'event_id' => $event_id,
1541
+				),
1542
+				REG_ADMIN_URL
1543
+			);
1544
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1545
+				array(
1546
+					'action' => 'default',
1547
+					'EVT_ID' => $event_id,
1548
+					'page'   => 'espresso_transactions',
1549
+				),
1550
+				admin_url('admin.php')
1551
+			);
1552
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1553
+				array(
1554
+					'page'   => 'espresso_events',
1555
+					'action' => 'edit',
1556
+					'post'   => $event_id,
1557
+				),
1558
+				admin_url('admin.php')
1559
+			);
1560
+			//next and previous links
1561
+			$next_reg                                      = $this->_registration->next(
1562
+				null,
1563
+				array(),
1564
+				'REG_ID'
1565
+			);
1566
+			$this->_template_args['next_registration']     = $next_reg
1567
+				? $this->_next_link(
1568
+					EE_Admin_Page::add_query_args_and_nonce(
1569
+						array(
1570
+							'action'  => 'view_registration',
1571
+							'_REG_ID' => $next_reg['REG_ID'],
1572
+						),
1573
+						REG_ADMIN_URL
1574
+					),
1575
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1576
+				)
1577
+				: '';
1578
+			$previous_reg                                  = $this->_registration->previous(
1579
+				null,
1580
+				array(),
1581
+				'REG_ID'
1582
+			);
1583
+			$this->_template_args['previous_registration'] = $previous_reg
1584
+				? $this->_previous_link(
1585
+					EE_Admin_Page::add_query_args_and_nonce(
1586
+						array(
1587
+							'action'  => 'view_registration',
1588
+							'_REG_ID' => $previous_reg['REG_ID'],
1589
+						),
1590
+						REG_ADMIN_URL
1591
+					),
1592
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1593
+				)
1594
+				: '';
1595
+			// grab header
1596
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1597
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1598
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1599
+				$template_path,
1600
+				$this->_template_args,
1601
+				true
1602
+			);
1603
+		} else {
1604
+			$this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1605
+		}
1606
+		// the details template wrapper
1607
+		$this->display_admin_page_with_sidebar();
1608
+	}
1609
+
1610
+
1611
+	protected function _registration_details_metaboxes()
1612
+	{
1613
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1614
+		$this->_set_registration_object();
1615
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1616
+		add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1617
+			array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1618
+		add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1619
+			array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1620
+		if ($attendee instanceof EE_Attendee
1621
+			&& EE_Registry::instance()->CAP->current_user_can(
1622
+				'ee_edit_registration',
1623
+				'edit-reg-questions-mbox',
1624
+				$this->_registration->ID()
1625
+			)
1626
+		) {
1627
+			add_meta_box(
1628
+				'edit-reg-questions-mbox',
1629
+				esc_html__('Registration Form Answers', 'event_espresso'),
1630
+				array($this, '_reg_questions_meta_box'),
1631
+				$this->wp_page_slug,
1632
+				'normal',
1633
+				'high'
1634
+			);
1635
+		}
1636
+		add_meta_box(
1637
+			'edit-reg-registrant-mbox',
1638
+			esc_html__('Contact Details', 'event_espresso'),
1639
+			array($this, '_reg_registrant_side_meta_box'),
1640
+			$this->wp_page_slug,
1641
+			'side',
1642
+			'high'
1643
+		);
1644
+		if ($this->_registration->group_size() > 1) {
1645
+			add_meta_box(
1646
+				'edit-reg-attendees-mbox',
1647
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1648
+				array($this, '_reg_attendees_meta_box'),
1649
+				$this->wp_page_slug,
1650
+				'normal',
1651
+				'high'
1652
+			);
1653
+		}
1654
+	}
1655
+
1656
+
1657
+	/**
1658
+	 * set_reg_status_buttons_metabox
1659
+	 *
1660
+	 * @access protected
1661
+	 * @return string
1662
+	 * @throws \EE_Error
1663
+	 */
1664
+	public function set_reg_status_buttons_metabox()
1665
+	{
1666
+		$this->_set_registration_object();
1667
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1668
+		echo $change_reg_status_form->form_open(
1669
+			self::add_query_args_and_nonce(
1670
+				array(
1671
+					'action' => 'change_reg_status',
1672
+				),
1673
+				REG_ADMIN_URL
1674
+			)
1675
+		);
1676
+		echo $change_reg_status_form->get_html();
1677
+		echo $change_reg_status_form->form_close();
1678
+	}
1679
+
1680
+
1681
+	/**
1682
+	 * @return EE_Form_Section_Proper
1683
+	 * @throws EE_Error
1684
+	 * @throws InvalidArgumentException
1685
+	 * @throws InvalidDataTypeException
1686
+	 * @throws InvalidInterfaceException
1687
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1688
+	 */
1689
+	protected function _generate_reg_status_change_form()
1690
+	{
1691
+		return new EE_Form_Section_Proper(array(
1692
+			'name'            => 'reg_status_change_form',
1693
+			'html_id'         => 'reg-status-change-form',
1694
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1695
+			'subsections'     => array(
1696
+				'return'             => new EE_Hidden_Input(array(
1697
+					'name'    => 'return',
1698
+					'default' => 'view_registration',
1699
+				)),
1700
+				'REG_ID'             => new EE_Hidden_Input(array(
1701
+					'name'    => 'REG_ID',
1702
+					'default' => $this->_registration->ID(),
1703
+				)),
1704
+				'current_status'     => new EE_Form_Section_HTML(
1705
+					EEH_HTML::tr(
1706
+						EEH_HTML::th(
1707
+							EEH_HTML::label(
1708
+								EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1709
+								)
1710
+							)
1711
+						)
1712
+						. EEH_HTML::td(
1713
+							EEH_HTML::strong(
1714
+								$this->_registration->pretty_status(),
1715
+								'',
1716
+								'status-' . $this->_registration->status_ID(),
1717
+								'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1718
+							)
1719
+						)
1720
+					)
1721
+				),
1722
+				'reg_status'         => new EE_Select_Input(
1723
+					$this->_get_reg_statuses(),
1724
+					array(
1725
+						'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1726
+						'default'         => $this->_registration->status_ID(),
1727
+					)
1728
+				),
1729
+				'send_notifications' => new EE_Yes_No_Input(
1730
+					array(
1731
+						'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1732
+						'default'         => false,
1733
+						'html_help_text'  => esc_html__(
1734
+							'If set to "Yes", then the related messages will be sent to the registrant.',
1735
+							'event_espresso'
1736
+						),
1737
+					)
1738
+				),
1739
+				'submit'             => new EE_Submit_Input(
1740
+					array(
1741
+						'html_class'      => 'button-primary',
1742
+						'html_label_text' => '&nbsp;',
1743
+						'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1744
+					)
1745
+				),
1746
+			),
1747
+		));
1748
+	}
1749
+
1750
+
1751
+	/**
1752
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1753
+	 *
1754
+	 * @return array
1755
+	 * @throws EE_Error
1756
+	 * @throws InvalidArgumentException
1757
+	 * @throws InvalidDataTypeException
1758
+	 * @throws InvalidInterfaceException
1759
+	 * @throws EntityNotFoundException
1760
+	 */
1761
+	protected function _get_reg_statuses()
1762
+	{
1763
+		$reg_status_array = EEM_Registration::instance()->reg_status_array();
1764
+		unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1765
+		// get current reg status
1766
+		$current_status = $this->_registration->status_ID();
1767
+		// is registration for free event? This will determine whether to display the pending payment option
1768
+		if (
1769
+			$current_status !== EEM_Registration::status_id_pending_payment
1770
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1771
+		) {
1772
+			unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1773
+		}
1774
+		return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1775
+	}
1776
+
1777
+
1778
+	/**
1779
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1780
+	 *
1781
+	 * @param bool $status REG status given for changing registrations to.
1782
+	 * @param bool $notify Whether to send messages notifications or not.
1783
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1784
+	 * @throws EE_Error
1785
+	 * @throws InvalidArgumentException
1786
+	 * @throws InvalidDataTypeException
1787
+	 * @throws InvalidInterfaceException
1788
+	 * @throws ReflectionException
1789
+	 * @throws RuntimeException
1790
+	 * @throws EntityNotFoundException
1791
+	 */
1792
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1793
+	{
1794
+		if (isset($this->_req_data['reg_status_change_form'])) {
1795
+			$REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1796
+				? (array)$this->_req_data['reg_status_change_form']['REG_ID']
1797
+				: array();
1798
+		} else {
1799
+			$REG_IDs = isset($this->_req_data['_REG_ID'])
1800
+				? (array)$this->_req_data['_REG_ID']
1801
+				: array();
1802
+		}
1803
+		// sanitize $REG_IDs
1804
+		$REG_IDs = array_map('absint', $REG_IDs);
1805
+		// and remove empty entries
1806
+		$REG_IDs = array_filter($REG_IDs);
1807
+
1808
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1809
+
1810
+		/**
1811
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1812
+		 * Currently this value is used downstream by the _process_resend_registration method.
1813
+		 *
1814
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1815
+		 * @param bool                     $status           The status registrations were changed to.
1816
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1817
+		 * @param Registrations_Admin_Page $admin_page_object
1818
+		 */
1819
+		$this->_req_data['_REG_ID'] = apply_filters(
1820
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1821
+			$result['REG_ID'],
1822
+			$status,
1823
+			$result['success'],
1824
+			$this
1825
+		);
1826
+
1827
+		//notify?
1828
+		if ($notify
1829
+			&& $result['success']
1830
+			&& ! empty($this->_req_data['_REG_ID'])
1831
+			&& EE_Registry::instance()->CAP->current_user_can(
1832
+				'ee_send_message',
1833
+				'espresso_registrations_resend_registration'
1834
+			)
1835
+		) {
1836
+			$this->_process_resend_registration();
1837
+		}
1838
+		return $result;
1839
+	}
1840
+
1841
+
1842
+	/**
1843
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1844
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1845
+	 *
1846
+	 * @param array  $REG_IDs
1847
+	 * @param string $status
1848
+	 * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1849
+	 *                        slug sent with setting the registration status.
1850
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1851
+	 * @throws EE_Error
1852
+	 * @throws InvalidArgumentException
1853
+	 * @throws InvalidDataTypeException
1854
+	 * @throws InvalidInterfaceException
1855
+	 * @throws ReflectionException
1856
+	 * @throws RuntimeException
1857
+	 * @throws EntityNotFoundException
1858
+	 */
1859
+	protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1860
+	{
1861
+		$success = false;
1862
+		// typecast $REG_IDs
1863
+		$REG_IDs = (array)$REG_IDs;
1864
+		if ( ! empty($REG_IDs)) {
1865
+			$success = true;
1866
+			// set default status if none is passed
1867
+			$status = $status ? $status : EEM_Registration::status_id_pending_payment;
1868
+			$status_context = $notify
1869
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1870
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1871
+			//loop through REG_ID's and change status
1872
+			foreach ($REG_IDs as $REG_ID) {
1873
+				$registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1874
+				if ($registration instanceof EE_Registration) {
1875
+					$registration->set_status(
1876
+						$status,
1877
+						false,
1878
+						new Context(
1879
+							$status_context,
1880
+							esc_html__(
1881
+								'Manually triggered status change on a Registration Admin Page route.',
1882
+								'event_espresso'
1883
+							)
1884
+						)
1885
+					);
1886
+					$result = $registration->save();
1887
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1888
+					$success = $result !== false ? $success : false;
1889
+				}
1890
+			}
1891
+		}
1892
+
1893
+		//return $success and processed registrations
1894
+		return array('REG_ID' => $REG_IDs, 'success' => $success);
1895
+	}
1896
+
1897
+
1898
+	/**
1899
+	 * Common logic for setting up success message and redirecting to appropriate route
1900
+	 *
1901
+	 * @param  string $STS_ID status id for the registration changed to
1902
+	 * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1903
+	 * @return void
1904
+	 * @throws EE_Error
1905
+	 */
1906
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1907
+	{
1908
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1909
+			: array('success' => false);
1910
+		$success = isset($result['success']) && $result['success'];
1911
+		//setup success message
1912
+		if ($success) {
1913
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1914
+				$msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1915
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1916
+			} else {
1917
+				$msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1918
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1919
+			}
1920
+			EE_Error::add_success($msg);
1921
+		} else {
1922
+			EE_Error::add_error(
1923
+				esc_html__(
1924
+					'Something went wrong, and the status was not changed',
1925
+					'event_espresso'
1926
+				), __FILE__, __LINE__, __FUNCTION__
1927
+			);
1928
+		}
1929
+		if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1930
+			$route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1931
+		} else {
1932
+			$route = array('action' => 'default');
1933
+		}
1934
+		//unset nonces
1935
+		foreach ($this->_req_data as $ref => $value) {
1936
+			if (strpos($ref, 'nonce') !== false) {
1937
+				unset($this->_req_data[$ref]);
1938
+				continue;
1939
+			}
1940
+			$value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1941
+			$this->_req_data[$ref] = $value;
1942
+		}
1943
+		//merge request vars so that the reloaded list table contains any existing filter query params
1944
+		$route = array_merge($this->_req_data, $route);
1945
+		$this->_redirect_after_action($success, '', '', $route, true);
1946
+	}
1947
+
1948
+
1949
+	/**
1950
+	 * incoming reg status change from reg details page.
1951
+	 *
1952
+	 * @return void
1953
+	 */
1954
+	protected function _change_reg_status()
1955
+	{
1956
+		$this->_req_data['return'] = 'view_registration';
1957
+		//set notify based on whether the send notifications toggle is set or not
1958
+		$notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1959
+		//$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1960
+		$this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1961
+			? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1962
+		switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1963
+			case EEM_Registration::status_id_approved :
1964
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
1965
+				$this->approve_registration($notify);
1966
+				break;
1967
+			case EEM_Registration::status_id_pending_payment :
1968
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
1969
+				$this->pending_registration($notify);
1970
+				break;
1971
+			case EEM_Registration::status_id_not_approved :
1972
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
1973
+				$this->not_approve_registration($notify);
1974
+				break;
1975
+			case EEM_Registration::status_id_declined :
1976
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
1977
+				$this->decline_registration($notify);
1978
+				break;
1979
+			case EEM_Registration::status_id_cancelled :
1980
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
1981
+				$this->cancel_registration($notify);
1982
+				break;
1983
+			case EEM_Registration::status_id_wait_list :
1984
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
1985
+				$this->wait_list_registration($notify);
1986
+				break;
1987
+			case EEM_Registration::status_id_incomplete :
1988
+			default :
1989
+				$result['success'] = false;
1990
+				unset($this->_req_data['return']);
1991
+				$this->_reg_status_change_return('', false);
1992
+				break;
1993
+		}
1994
+	}
1995
+
1996
+
1997
+	/**
1998
+	 * Callback for bulk action routes.
1999
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
2000
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
2001
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
2002
+	 * when an action is happening on just a single registration).
2003
+	 * @param      $action
2004
+	 * @param bool $notify
2005
+	 */
2006
+	protected function bulk_action_on_registrations($action, $notify = false) {
2007
+		do_action(
2008
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
2009
+			$this,
2010
+			$action,
2011
+			$notify
2012
+		);
2013
+		$method = $action . '_registration';
2014
+		if (method_exists($this, $method)) {
2015
+			$this->$method($notify);
2016
+		}
2017
+	}
2018
+
2019
+
2020
+	/**
2021
+	 * approve_registration
2022
+	 *
2023
+	 * @access protected
2024
+	 * @param bool $notify whether or not to notify the registrant about their approval.
2025
+	 * @return void
2026
+	 */
2027
+	protected function approve_registration($notify = false)
2028
+	{
2029
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
2030
+	}
2031
+
2032
+
2033
+	/**
2034
+	 *        decline_registration
2035
+	 *
2036
+	 * @access protected
2037
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2038
+	 * @return void
2039
+	 */
2040
+	protected function decline_registration($notify = false)
2041
+	{
2042
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
2043
+	}
2044
+
2045
+
2046
+	/**
2047
+	 *        cancel_registration
2048
+	 *
2049
+	 * @access protected
2050
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2051
+	 * @return void
2052
+	 */
2053
+	protected function cancel_registration($notify = false)
2054
+	{
2055
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
2056
+	}
2057
+
2058
+
2059
+	/**
2060
+	 *        not_approve_registration
2061
+	 *
2062
+	 * @access protected
2063
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2064
+	 * @return void
2065
+	 */
2066
+	protected function not_approve_registration($notify = false)
2067
+	{
2068
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
2069
+	}
2070
+
2071
+
2072
+	/**
2073
+	 *        decline_registration
2074
+	 *
2075
+	 * @access protected
2076
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2077
+	 * @return void
2078
+	 */
2079
+	protected function pending_registration($notify = false)
2080
+	{
2081
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
2082
+	}
2083
+
2084
+
2085
+	/**
2086
+	 * waitlist_registration
2087
+	 *
2088
+	 * @access protected
2089
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2090
+	 * @return void
2091
+	 */
2092
+	protected function wait_list_registration($notify = false)
2093
+	{
2094
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2095
+	}
2096
+
2097
+
2098
+	/**
2099
+	 *        generates HTML for the Registration main meta box
2100
+	 *
2101
+	 * @access public
2102
+	 * @return void
2103
+	 * @throws DomainException
2104
+	 * @throws EE_Error
2105
+	 * @throws InvalidArgumentException
2106
+	 * @throws InvalidDataTypeException
2107
+	 * @throws InvalidInterfaceException
2108
+	 * @throws ReflectionException
2109
+	 * @throws EntityNotFoundException
2110
+	 */
2111
+	public function _reg_details_meta_box()
2112
+	{
2113
+		EEH_Autoloader::register_line_item_display_autoloaders();
2114
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2115
+		EE_Registry::instance()->load_helper('Line_Item');
2116
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2117
+			: EE_Transaction::new_instance();
2118
+		$this->_session = $transaction->session_data();
2119
+		$filters        = new EE_Line_Item_Filter_Collection();
2120
+		//$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2121
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2122
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2123
+			$transaction->total_line_item());
2124
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2125
+		$line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2126
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2127
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2128
+			$filtered_line_item_tree,
2129
+			array('EE_Registration' => $this->_registration)
2130
+		);
2131
+		$attendee                                = $this->_registration->attendee();
2132
+		if (EE_Registry::instance()->CAP->current_user_can(
2133
+			'ee_read_transaction',
2134
+			'espresso_transactions_view_transaction'
2135
+		)) {
2136
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2137
+				EE_Admin_Page::add_query_args_and_nonce(
2138
+					array(
2139
+						'action' => 'view_transaction',
2140
+						'TXN_ID' => $transaction->ID(),
2141
+					),
2142
+					TXN_ADMIN_URL
2143
+				),
2144
+				esc_html__(' View Transaction', 'event_espresso'),
2145
+				'button secondary-button right',
2146
+				'dashicons dashicons-cart'
2147
+			);
2148
+		} else {
2149
+			$this->_template_args['view_transaction_button'] = '';
2150
+		}
2151
+		if ($attendee instanceof EE_Attendee
2152
+			&& EE_Registry::instance()->CAP->current_user_can(
2153
+				'ee_send_message',
2154
+				'espresso_registrations_resend_registration'
2155
+			)
2156
+		) {
2157
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2158
+				EE_Admin_Page::add_query_args_and_nonce(
2159
+					array(
2160
+						'action'      => 'resend_registration',
2161
+						'_REG_ID'     => $this->_registration->ID(),
2162
+						'redirect_to' => 'view_registration',
2163
+					),
2164
+					REG_ADMIN_URL
2165
+				),
2166
+				esc_html__(' Resend Registration', 'event_espresso'),
2167
+				'button secondary-button right',
2168
+				'dashicons dashicons-email-alt'
2169
+			);
2170
+		} else {
2171
+			$this->_template_args['resend_registration_button'] = '';
2172
+		}
2173
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2174
+		$payment                               = $transaction->get_first_related('Payment');
2175
+		$payment                               = ! $payment instanceof EE_Payment
2176
+			? EE_Payment::new_instance()
2177
+			: $payment;
2178
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2179
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2180
+			? EE_Payment_Method::new_instance()
2181
+			: $payment_method;
2182
+		$reg_details                           = array(
2183
+			'payment_method'       => $payment_method->name(),
2184
+			'response_msg'         => $payment->gateway_response(),
2185
+			'registration_id'      => $this->_registration->get('REG_code'),
2186
+			'registration_session' => $this->_registration->session_ID(),
2187
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2188
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2189
+		);
2190
+		if (isset($reg_details['registration_id'])) {
2191
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2192
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2193
+				'Registration ID',
2194
+				'event_espresso'
2195
+			);
2196
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2197
+		}
2198
+		if (isset($reg_details['payment_method'])) {
2199
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2200
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2201
+				'Most Recent Payment Method',
2202
+				'event_espresso'
2203
+			);
2204
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2205
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2206
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2207
+				'Payment method response',
2208
+				'event_espresso'
2209
+			);
2210
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2211
+		}
2212
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2213
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2214
+			'Registration Session',
2215
+			'event_espresso'
2216
+		);
2217
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2218
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2219
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2220
+			'Registration placed from IP',
2221
+			'event_espresso'
2222
+		);
2223
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2224
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2225
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2226
+			'event_espresso');
2227
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2228
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2229
+			array(
2230
+				'action'   => 'default',
2231
+				'event_id' => $this->_registration->event_ID(),
2232
+			),
2233
+			REG_ADMIN_URL
2234
+		);
2235
+		$this->_template_args['REG_ID']                                       = $this->_registration->ID();
2236
+		$this->_template_args['event_id']                                     = $this->_registration->event_ID();
2237
+		$template_path                                                        =
2238
+			REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2239
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2240
+	}
2241
+
2242
+
2243
+	/**
2244
+	 * generates HTML for the Registration Questions meta box.
2245
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2246
+	 * otherwise uses new forms system
2247
+	 *
2248
+	 * @access public
2249
+	 * @return void
2250
+	 * @throws DomainException
2251
+	 * @throws EE_Error
2252
+	 */
2253
+	public function _reg_questions_meta_box()
2254
+	{
2255
+		//allow someone to override this method entirely
2256
+		if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2257
+			$this->_registration)) {
2258
+			$form                                              = $this->_get_reg_custom_questions_form(
2259
+				$this->_registration->ID()
2260
+			);
2261
+			$this->_template_args['att_questions']             = count($form->subforms()) > 0
2262
+				? $form->get_html_and_js()
2263
+				: '';
2264
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2265
+			$this->_template_args['REG_ID']                    = $this->_registration->ID();
2266
+			$template_path                                     =
2267
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2268
+			echo EEH_Template::display_template($template_path, $this->_template_args, true);
2269
+		}
2270
+	}
2271
+
2272
+
2273
+	/**
2274
+	 * form_before_question_group
2275
+	 *
2276
+	 * @deprecated    as of 4.8.32.rc.000
2277
+	 * @access        public
2278
+	 * @param        string $output
2279
+	 * @return        string
2280
+	 */
2281
+	public function form_before_question_group($output)
2282
+	{
2283
+		EE_Error::doing_it_wrong(
2284
+			__CLASS__ . '::' . __FUNCTION__,
2285
+			esc_html__(
2286
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2287
+				'event_espresso'
2288
+			),
2289
+			'4.8.32.rc.000'
2290
+		);
2291
+		return '
2292 2292
 	<table class="form-table ee-width-100">
2293 2293
 		<tbody>
2294 2294
 			';
2295
-    }
2296
-
2297
-
2298
-    /**
2299
-     * form_after_question_group
2300
-     *
2301
-     * @deprecated    as of 4.8.32.rc.000
2302
-     * @access        public
2303
-     * @param        string $output
2304
-     * @return        string
2305
-     */
2306
-    public function form_after_question_group($output)
2307
-    {
2308
-        EE_Error::doing_it_wrong(
2309
-            __CLASS__ . '::' . __FUNCTION__,
2310
-            esc_html__(
2311
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2312
-                'event_espresso'
2313
-            ),
2314
-            '4.8.32.rc.000'
2315
-        );
2316
-        return '
2295
+	}
2296
+
2297
+
2298
+	/**
2299
+	 * form_after_question_group
2300
+	 *
2301
+	 * @deprecated    as of 4.8.32.rc.000
2302
+	 * @access        public
2303
+	 * @param        string $output
2304
+	 * @return        string
2305
+	 */
2306
+	public function form_after_question_group($output)
2307
+	{
2308
+		EE_Error::doing_it_wrong(
2309
+			__CLASS__ . '::' . __FUNCTION__,
2310
+			esc_html__(
2311
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2312
+				'event_espresso'
2313
+			),
2314
+			'4.8.32.rc.000'
2315
+		);
2316
+		return '
2317 2317
 			<tr class="hide-if-no-js">
2318 2318
 				<th> </th>
2319 2319
 				<td class="reg-admin-edit-attendee-question-td">
2320 2320
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2321
-               . esc_attr__('click to edit question', 'event_espresso')
2322
-               . '">
2321
+			   . esc_attr__('click to edit question', 'event_espresso')
2322
+			   . '">
2323 2323
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2324
-               . esc_html__('edit the above question group', 'event_espresso')
2325
-               . '</span>
2324
+			   . esc_html__('edit the above question group', 'event_espresso')
2325
+			   . '</span>
2326 2326
 						<div class="dashicons dashicons-edit"></div>
2327 2327
 					</a>
2328 2328
 				</td>
@@ -2330,579 +2330,579 @@  discard block
 block discarded – undo
2330 2330
 		</tbody>
2331 2331
 	</table>
2332 2332
 ';
2333
-    }
2334
-
2335
-
2336
-    /**
2337
-     * form_form_field_label_wrap
2338
-     *
2339
-     * @deprecated    as of 4.8.32.rc.000
2340
-     * @access        public
2341
-     * @param        string $label
2342
-     * @return        string
2343
-     */
2344
-    public function form_form_field_label_wrap($label)
2345
-    {
2346
-        EE_Error::doing_it_wrong(
2347
-            __CLASS__ . '::' . __FUNCTION__,
2348
-            esc_html__(
2349
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2350
-                'event_espresso'
2351
-            ),
2352
-            '4.8.32.rc.000'
2353
-        );
2354
-        return '
2333
+	}
2334
+
2335
+
2336
+	/**
2337
+	 * form_form_field_label_wrap
2338
+	 *
2339
+	 * @deprecated    as of 4.8.32.rc.000
2340
+	 * @access        public
2341
+	 * @param        string $label
2342
+	 * @return        string
2343
+	 */
2344
+	public function form_form_field_label_wrap($label)
2345
+	{
2346
+		EE_Error::doing_it_wrong(
2347
+			__CLASS__ . '::' . __FUNCTION__,
2348
+			esc_html__(
2349
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2350
+				'event_espresso'
2351
+			),
2352
+			'4.8.32.rc.000'
2353
+		);
2354
+		return '
2355 2355
 			<tr>
2356 2356
 				<th>
2357 2357
 					' . $label . '
2358 2358
 				</th>';
2359
-    }
2360
-
2361
-
2362
-    /**
2363
-     * form_form_field_input__wrap
2364
-     *
2365
-     * @deprecated    as of 4.8.32.rc.000
2366
-     * @access        public
2367
-     * @param        string $input
2368
-     * @return        string
2369
-     */
2370
-    public function form_form_field_input__wrap($input)
2371
-    {
2372
-        EE_Error::doing_it_wrong(
2373
-            __CLASS__ . '::' . __FUNCTION__,
2374
-            esc_html__(
2375
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2376
-                'event_espresso'
2377
-            ),
2378
-            '4.8.32.rc.000'
2379
-        );
2380
-        return '
2359
+	}
2360
+
2361
+
2362
+	/**
2363
+	 * form_form_field_input__wrap
2364
+	 *
2365
+	 * @deprecated    as of 4.8.32.rc.000
2366
+	 * @access        public
2367
+	 * @param        string $input
2368
+	 * @return        string
2369
+	 */
2370
+	public function form_form_field_input__wrap($input)
2371
+	{
2372
+		EE_Error::doing_it_wrong(
2373
+			__CLASS__ . '::' . __FUNCTION__,
2374
+			esc_html__(
2375
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2376
+				'event_espresso'
2377
+			),
2378
+			'4.8.32.rc.000'
2379
+		);
2380
+		return '
2381 2381
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2382 2382
 					' . $input . '
2383 2383
 				</td>
2384 2384
 			</tr>';
2385
-    }
2386
-
2387
-
2388
-    /**
2389
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2390
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2391
-     * to display the page
2392
-     *
2393
-     * @access protected
2394
-     * @return void
2395
-     * @throws EE_Error
2396
-     */
2397
-    protected function _update_attendee_registration_form()
2398
-    {
2399
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2400
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2401
-            $REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2402
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2403
-            if ($success) {
2404
-                $what  = esc_html__('Registration Form', 'event_espresso');
2405
-                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2406
-                    : array('action' => 'default');
2407
-                $this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2408
-            }
2409
-        }
2410
-    }
2411
-
2412
-
2413
-    /**
2414
-     * Gets the form for saving registrations custom questions (if done
2415
-     * previously retrieves the cached form object, which may have validation errors in it)
2416
-     *
2417
-     * @param int $REG_ID
2418
-     * @return EE_Registration_Custom_Questions_Form
2419
-     * @throws EE_Error
2420
-     * @throws InvalidArgumentException
2421
-     * @throws InvalidDataTypeException
2422
-     * @throws InvalidInterfaceException
2423
-     */
2424
-    protected function _get_reg_custom_questions_form($REG_ID)
2425
-    {
2426
-        if ( ! $this->_reg_custom_questions_form) {
2427
-            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2428
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2429
-                EEM_Registration::instance()->get_one_by_ID($REG_ID)
2430
-            );
2431
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2432
-        }
2433
-        return $this->_reg_custom_questions_form;
2434
-    }
2435
-
2436
-
2437
-    /**
2438
-     * Saves
2439
-     *
2440
-     * @access private
2441
-     * @param bool $REG_ID
2442
-     * @return bool
2443
-     * @throws EE_Error
2444
-     * @throws InvalidArgumentException
2445
-     * @throws InvalidDataTypeException
2446
-     * @throws InvalidInterfaceException
2447
-     */
2448
-    private function _save_reg_custom_questions_form($REG_ID = false)
2449
-    {
2450
-        if ( ! $REG_ID) {
2451
-            EE_Error::add_error(
2452
-                esc_html__(
2453
-                    'An error occurred. No registration ID was received.', 'event_espresso'),
2454
-                __FILE__, __FUNCTION__, __LINE__
2455
-            );
2456
-        }
2457
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2458
-        $form->receive_form_submission($this->_req_data);
2459
-        $success = false;
2460
-        if ($form->is_valid()) {
2461
-            foreach ($form->subforms() as $question_group_id => $question_group_form) {
2462
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2463
-                    $where_conditions    = array(
2464
-                        'QST_ID' => $question_id,
2465
-                        'REG_ID' => $REG_ID,
2466
-                    );
2467
-                    $possibly_new_values = array(
2468
-                        'ANS_value' => $input->normalized_value(),
2469
-                    );
2470
-                    $answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2471
-                    if ($answer instanceof EE_Answer) {
2472
-                        $success = $answer->save($possibly_new_values);
2473
-                    } else {
2474
-                        //insert it then
2475
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2476
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2477
-                        $success     = $answer->save();
2478
-                    }
2479
-                }
2480
-            }
2481
-        } else {
2482
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2483
-        }
2484
-        return $success;
2485
-    }
2486
-
2487
-
2488
-    /**
2489
-     *        generates HTML for the Registration main meta box
2490
-     *
2491
-     * @access public
2492
-     * @return void
2493
-     * @throws DomainException
2494
-     * @throws EE_Error
2495
-     * @throws InvalidArgumentException
2496
-     * @throws InvalidDataTypeException
2497
-     * @throws InvalidInterfaceException
2498
-     */
2499
-    public function _reg_attendees_meta_box()
2500
-    {
2501
-        $REG = EEM_Registration::instance();
2502
-        //get all other registrations on this transaction, and cache
2503
-        //the attendees for them so we don't have to run another query using force_join
2504
-        $registrations                           = $REG->get_all(array(
2505
-            array(
2506
-                'TXN_ID' => $this->_registration->transaction_ID(),
2507
-                'REG_ID' => array('!=', $this->_registration->ID()),
2508
-            ),
2509
-            'force_join' => array('Attendee'),
2510
-        ));
2511
-        $this->_template_args['attendees']       = array();
2512
-        $this->_template_args['attendee_notice'] = '';
2513
-        if (empty($registrations)
2514
-            || (is_array($registrations)
2515
-                && ! EEH_Array::get_one_item_from_array($registrations))
2516
-        ) {
2517
-            EE_Error::add_error(
2518
-                esc_html__(
2519
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2520
-                    'event_espresso'
2521
-                ), __FILE__, __FUNCTION__, __LINE__
2522
-            );
2523
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2524
-        } else {
2525
-            $att_nmbr = 1;
2526
-            foreach ($registrations as $registration) {
2527
-                /* @var $registration EE_Registration */
2528
-                $attendee                                                    = $registration->attendee()
2529
-                    ? $registration->attendee()
2530
-                    : EEM_Attendee::instance()
2531
-                                  ->create_default_object();
2532
-                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2533
-                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2534
-                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2535
-                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2536
-                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2537
-                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2538
-                    ', ',
2539
-                    $attendee->full_address_as_array()
2540
-                );
2541
-                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2542
-                    array(
2543
-                        'action' => 'edit_attendee',
2544
-                        'post'   => $attendee->ID(),
2545
-                    ),
2546
-                    REG_ADMIN_URL
2547
-                );
2548
-                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2549
-                $att_nmbr++;
2550
-            }
2551
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2552
-        }
2553
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2554
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2555
-    }
2556
-
2557
-
2558
-    /**
2559
-     *        generates HTML for the Edit Registration side meta box
2560
-     *
2561
-     * @access public
2562
-     * @return void
2563
-     * @throws DomainException
2564
-     * @throws EE_Error
2565
-     * @throws InvalidArgumentException
2566
-     * @throws InvalidDataTypeException
2567
-     * @throws InvalidInterfaceException
2568
-     */
2569
-    public function _reg_registrant_side_meta_box()
2570
-    {
2571
-        /*@var $attendee EE_Attendee */
2572
-        $att_check = $this->_registration->attendee();
2573
-        $attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2574
-        //now let's determine if this is not the primary registration.  If it isn't then we set the
2575
-        //primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2576
-        //primary registration object (that way we know if we need to show create button or not)
2577
-        if ( ! $this->_registration->is_primary_registrant()) {
2578
-            $primary_registration = $this->_registration->get_primary_registration();
2579
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2580
-                : null;
2581
-            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2582
-                //in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2583
-                //custom attendee object so let's not worry about the primary reg.
2584
-                $primary_registration = null;
2585
-            }
2586
-        } else {
2587
-            $primary_registration = null;
2588
-        }
2589
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2590
-        $this->_template_args['fname']             = $attendee->fname();
2591
-        $this->_template_args['lname']             = $attendee->lname();
2592
-        $this->_template_args['email']             = $attendee->email();
2593
-        $this->_template_args['phone']             = $attendee->phone();
2594
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2595
-        //edit link
2596
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2597
-            'action' => 'edit_attendee',
2598
-            'post'   => $attendee->ID(),
2599
-        ), REG_ADMIN_URL);
2600
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2601
-        //create link
2602
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2603
-            ? EE_Admin_Page::add_query_args_and_nonce(array(
2604
-                'action'  => 'duplicate_attendee',
2605
-                '_REG_ID' => $this->_registration->ID(),
2606
-            ), REG_ADMIN_URL) : '';
2607
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2608
-        $this->_template_args['att_check']    = $att_check;
2609
-        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2610
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2611
-    }
2612
-
2613
-
2614
-    /**
2615
-     * trash or restore registrations
2616
-     *
2617
-     * @param  boolean $trash whether to archive or restore
2618
-     * @return void
2619
-     * @throws EE_Error
2620
-     * @throws InvalidArgumentException
2621
-     * @throws InvalidDataTypeException
2622
-     * @throws InvalidInterfaceException
2623
-     * @throws RuntimeException
2624
-     * @access protected
2625
-     */
2626
-    protected function _trash_or_restore_registrations($trash = true)
2627
-    {
2628
-        //if empty _REG_ID then get out because there's nothing to do
2629
-        if (empty($this->_req_data['_REG_ID'])) {
2630
-            EE_Error::add_error(
2631
-                sprintf(
2632
-                    esc_html__(
2633
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2634
-                        'event_espresso'
2635
-                    ),
2636
-                    $trash ? 'trash' : 'restore'
2637
-                ),
2638
-                __FILE__, __LINE__, __FUNCTION__
2639
-            );
2640
-            $this->_redirect_after_action(false, '', '', array(), true);
2641
-        }
2642
-        $success = 0;
2643
-        $overwrite_msgs = false;
2644
-        //Checkboxes
2645
-        if ( ! is_array($this->_req_data['_REG_ID'])) {
2646
-            $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2647
-        }
2648
-        $reg_count = count($this->_req_data['_REG_ID']);
2649
-        // cycle thru checkboxes
2650
-        foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2651
-            /** @var EE_Registration $REG */
2652
-            $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2653
-            $payments = $REG->registration_payments();
2654
-            if (! empty($payments)) {
2655
-                $name = $REG->attendee() instanceof EE_Attendee
2656
-                    ? $REG->attendee()->full_name()
2657
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2658
-                $overwrite_msgs = true;
2659
-                EE_Error::add_error(
2660
-                    sprintf(
2661
-                        esc_html__(
2662
-                            'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2663
-                            'event_espresso'
2664
-                        ),
2665
-                        $name
2666
-                    ),
2667
-                    __FILE__, __FUNCTION__, __LINE__
2668
-                );
2669
-                //can't trash this registration because it has payments.
2670
-                continue;
2671
-            }
2672
-            $updated = $trash ? $REG->delete() : $REG->restore();
2673
-            if ($updated) {
2674
-                $success++;
2675
-            }
2676
-        }
2677
-        $this->_redirect_after_action(
2678
-            $success === $reg_count, // were ALL registrations affected?
2679
-            $success > 1
2680
-                ? esc_html__('Registrations', 'event_espresso')
2681
-                : esc_html__('Registration', 'event_espresso'),
2682
-            $trash
2683
-                ? esc_html__('moved to the trash', 'event_espresso')
2684
-                : esc_html__('restored', 'event_espresso'),
2685
-            array('action' => 'default'),
2686
-            $overwrite_msgs
2687
-        );
2688
-    }
2689
-
2690
-
2691
-    /**
2692
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2693
-     * registration but also.
2694
-     * 1. Removing relations to EE_Attendee
2695
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2696
-     * ALSO trashed.
2697
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2698
-     * 4. Removing relationships between all tickets and the related registrations
2699
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2700
-     * 6. Deleting permanently any related Checkins.
2701
-     *
2702
-     * @return void
2703
-     * @throws EE_Error
2704
-     * @throws InvalidArgumentException
2705
-     * @throws InvalidDataTypeException
2706
-     * @throws InvalidInterfaceException
2707
-     */
2708
-    protected function _delete_registrations()
2709
-    {
2710
-        $REG_MDL = EEM_Registration::instance();
2711
-        $success = 1;
2712
-        //Checkboxes
2713
-        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2714
-            // if array has more than one element than success message should be plural
2715
-            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2716
-            // cycle thru checkboxes
2717
-            while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2718
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2719
-                if ( ! $REG instanceof EE_Registration) {
2720
-                    continue;
2721
-                }
2722
-                $deleted = $this->_delete_registration($REG);
2723
-                if ( ! $deleted) {
2724
-                    $success = 0;
2725
-                }
2726
-            }
2727
-        } else {
2728
-            // grab single id and delete
2729
-            $REG_ID  = $this->_req_data['_REG_ID'];
2730
-            $REG     = $REG_MDL->get_one_by_ID($REG_ID);
2731
-            $deleted = $this->_delete_registration($REG);
2732
-            if ( ! $deleted) {
2733
-                $success = 0;
2734
-            }
2735
-        }
2736
-        $what        = $success > 1
2737
-            ? esc_html__('Registrations', 'event_espresso')
2738
-            : esc_html__('Registration', 'event_espresso');
2739
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2740
-        $this->_redirect_after_action(
2741
-            $success,
2742
-            $what,
2743
-            $action_desc,
2744
-            array('action' => 'default'),
2745
-            true
2746
-        );
2747
-    }
2748
-
2749
-
2750
-    /**
2751
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2752
-     * models get affected.
2753
-     *
2754
-     * @param  EE_Registration $REG registration to be deleted permenantly
2755
-     * @return bool true = successful deletion, false = fail.
2756
-     * @throws EE_Error
2757
-     */
2758
-    protected function _delete_registration(EE_Registration $REG)
2759
-    {
2760
-        //first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2761
-        //registrations on the transaction that are NOT trashed.
2762
-        $TXN         = $REG->get_first_related('Transaction');
2763
-        $REGS        = $TXN->get_many_related('Registration');
2764
-        $all_trashed = true;
2765
-        foreach ($REGS as $registration) {
2766
-            if ( ! $registration->get('REG_deleted')) {
2767
-                $all_trashed = false;
2768
-            }
2769
-        }
2770
-        if ( ! $all_trashed) {
2771
-            EE_Error::add_error(
2772
-                esc_html__(
2773
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2774
-                    'event_espresso'
2775
-                ),
2776
-                __FILE__, __FUNCTION__, __LINE__
2777
-            );
2778
-            return false;
2779
-        }
2780
-        //k made it here so that means we can delete all the related transactions and their answers (but let's do them
2781
-        //separately from THIS one).
2782
-        foreach ($REGS as $registration) {
2783
-            //delete related answers
2784
-            $registration->delete_related_permanently('Answer');
2785
-            //remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2786
-            $attendee = $registration->get_first_related('Attendee');
2787
-            if ($attendee instanceof EE_Attendee) {
2788
-                $registration->_remove_relation_to($attendee, 'Attendee');
2789
-            }
2790
-            //now remove relationships to tickets on this registration.
2791
-            $registration->_remove_relations('Ticket');
2792
-            //now delete permanently the checkins related to this registration.
2793
-            $registration->delete_related_permanently('Checkin');
2794
-            if ($registration->ID() === $REG->ID()) {
2795
-                continue;
2796
-            } //we don't want to delete permanently the existing registration just yet.
2797
-            //remove relation to transaction for these registrations if NOT the existing registrations
2798
-            $registration->_remove_relations('Transaction');
2799
-            //delete permanently any related messages.
2800
-            $registration->delete_related_permanently('Message');
2801
-            //now delete this registration permanently
2802
-            $registration->delete_permanently();
2803
-        }
2804
-        //now all related registrations on the transaction are handled.  So let's just handle this registration itself
2805
-        // (the transaction and line items should be all that's left).
2806
-        // delete the line items related to the transaction for this registration.
2807
-        $TXN->delete_related_permanently('Line_Item');
2808
-        //we need to remove all the relationships on the transaction
2809
-        $TXN->delete_related_permanently('Payment');
2810
-        $TXN->delete_related_permanently('Extra_Meta');
2811
-        $TXN->delete_related_permanently('Message');
2812
-        //now we can delete this REG permanently (and the transaction of course)
2813
-        $REG->delete_related_permanently('Transaction');
2814
-        return $REG->delete_permanently();
2815
-    }
2816
-
2817
-
2818
-    /**
2819
-     *    generates HTML for the Register New Attendee Admin page
2820
-     *
2821
-     * @access private
2822
-     * @throws DomainException
2823
-     * @throws EE_Error
2824
-     */
2825
-    public function new_registration()
2826
-    {
2827
-        if ( ! $this->_set_reg_event()) {
2828
-            throw new EE_Error(
2829
-                esc_html__(
2830
-                    'Unable to continue with registering because there is no Event ID in the request',
2831
-                    'event_espresso'
2832
-                )
2833
-            );
2834
-        }
2835
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2836
-        // gotta start with a clean slate if we're not coming here via ajax
2837
-        if ( ! defined('DOING_AJAX')
2838
-             && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2839
-        ) {
2840
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2841
-        }
2842
-        $this->_template_args['event_name'] = '';
2843
-        // event name
2844
-        if ($this->_reg_event) {
2845
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2846
-            $edit_event_url                     = self::add_query_args_and_nonce(array(
2847
-                'action' => 'edit',
2848
-                'post'   => $this->_reg_event->ID(),
2849
-            ), EVENTS_ADMIN_URL);
2850
-            $edit_event_lnk                     = '<a href="'
2851
-                                                  . $edit_event_url
2852
-                                                  . '" title="'
2853
-                                                  . esc_attr__('Edit ', 'event_espresso')
2854
-                                                  . $this->_reg_event->name()
2855
-                                                  . '">'
2856
-                                                  . esc_html__('Edit Event', 'event_espresso')
2857
-                                                  . '</a>';
2858
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2859
-                                                   . $edit_event_lnk
2860
-                                                   . '</span>';
2861
-        }
2862
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2863
-        if (defined('DOING_AJAX')) {
2864
-            $this->_return_json();
2865
-        }
2866
-        // grab header
2867
-        $template_path                              =
2868
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2869
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2870
-            $this->_template_args, true);
2871
-        //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2872
-        // the details template wrapper
2873
-        $this->display_admin_page_with_sidebar();
2874
-    }
2875
-
2876
-
2877
-    /**
2878
-     * This returns the content for a registration step
2879
-     *
2880
-     * @access protected
2881
-     * @return string html
2882
-     * @throws DomainException
2883
-     * @throws EE_Error
2884
-     * @throws InvalidArgumentException
2885
-     * @throws InvalidDataTypeException
2886
-     * @throws InvalidInterfaceException
2887
-     */
2888
-    protected function _get_registration_step_content()
2889
-    {
2890
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2891
-            $warning_msg = sprintf(
2892
-                esc_html__(
2893
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2894
-                    'event_espresso'
2895
-                ),
2896
-                '<br />',
2897
-                '<h3 class="important-notice">',
2898
-                '</h3>',
2899
-                '<div class="float-right">',
2900
-                '<span id="redirect_timer" class="important-notice">30</span>',
2901
-                '</div>',
2902
-                '<b>',
2903
-                '</b>'
2904
-            );
2905
-            return '
2385
+	}
2386
+
2387
+
2388
+	/**
2389
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2390
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2391
+	 * to display the page
2392
+	 *
2393
+	 * @access protected
2394
+	 * @return void
2395
+	 * @throws EE_Error
2396
+	 */
2397
+	protected function _update_attendee_registration_form()
2398
+	{
2399
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2400
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2401
+			$REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2402
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2403
+			if ($success) {
2404
+				$what  = esc_html__('Registration Form', 'event_espresso');
2405
+				$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2406
+					: array('action' => 'default');
2407
+				$this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2408
+			}
2409
+		}
2410
+	}
2411
+
2412
+
2413
+	/**
2414
+	 * Gets the form for saving registrations custom questions (if done
2415
+	 * previously retrieves the cached form object, which may have validation errors in it)
2416
+	 *
2417
+	 * @param int $REG_ID
2418
+	 * @return EE_Registration_Custom_Questions_Form
2419
+	 * @throws EE_Error
2420
+	 * @throws InvalidArgumentException
2421
+	 * @throws InvalidDataTypeException
2422
+	 * @throws InvalidInterfaceException
2423
+	 */
2424
+	protected function _get_reg_custom_questions_form($REG_ID)
2425
+	{
2426
+		if ( ! $this->_reg_custom_questions_form) {
2427
+			require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2428
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2429
+				EEM_Registration::instance()->get_one_by_ID($REG_ID)
2430
+			);
2431
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2432
+		}
2433
+		return $this->_reg_custom_questions_form;
2434
+	}
2435
+
2436
+
2437
+	/**
2438
+	 * Saves
2439
+	 *
2440
+	 * @access private
2441
+	 * @param bool $REG_ID
2442
+	 * @return bool
2443
+	 * @throws EE_Error
2444
+	 * @throws InvalidArgumentException
2445
+	 * @throws InvalidDataTypeException
2446
+	 * @throws InvalidInterfaceException
2447
+	 */
2448
+	private function _save_reg_custom_questions_form($REG_ID = false)
2449
+	{
2450
+		if ( ! $REG_ID) {
2451
+			EE_Error::add_error(
2452
+				esc_html__(
2453
+					'An error occurred. No registration ID was received.', 'event_espresso'),
2454
+				__FILE__, __FUNCTION__, __LINE__
2455
+			);
2456
+		}
2457
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2458
+		$form->receive_form_submission($this->_req_data);
2459
+		$success = false;
2460
+		if ($form->is_valid()) {
2461
+			foreach ($form->subforms() as $question_group_id => $question_group_form) {
2462
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2463
+					$where_conditions    = array(
2464
+						'QST_ID' => $question_id,
2465
+						'REG_ID' => $REG_ID,
2466
+					);
2467
+					$possibly_new_values = array(
2468
+						'ANS_value' => $input->normalized_value(),
2469
+					);
2470
+					$answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2471
+					if ($answer instanceof EE_Answer) {
2472
+						$success = $answer->save($possibly_new_values);
2473
+					} else {
2474
+						//insert it then
2475
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2476
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2477
+						$success     = $answer->save();
2478
+					}
2479
+				}
2480
+			}
2481
+		} else {
2482
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2483
+		}
2484
+		return $success;
2485
+	}
2486
+
2487
+
2488
+	/**
2489
+	 *        generates HTML for the Registration main meta box
2490
+	 *
2491
+	 * @access public
2492
+	 * @return void
2493
+	 * @throws DomainException
2494
+	 * @throws EE_Error
2495
+	 * @throws InvalidArgumentException
2496
+	 * @throws InvalidDataTypeException
2497
+	 * @throws InvalidInterfaceException
2498
+	 */
2499
+	public function _reg_attendees_meta_box()
2500
+	{
2501
+		$REG = EEM_Registration::instance();
2502
+		//get all other registrations on this transaction, and cache
2503
+		//the attendees for them so we don't have to run another query using force_join
2504
+		$registrations                           = $REG->get_all(array(
2505
+			array(
2506
+				'TXN_ID' => $this->_registration->transaction_ID(),
2507
+				'REG_ID' => array('!=', $this->_registration->ID()),
2508
+			),
2509
+			'force_join' => array('Attendee'),
2510
+		));
2511
+		$this->_template_args['attendees']       = array();
2512
+		$this->_template_args['attendee_notice'] = '';
2513
+		if (empty($registrations)
2514
+			|| (is_array($registrations)
2515
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2516
+		) {
2517
+			EE_Error::add_error(
2518
+				esc_html__(
2519
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2520
+					'event_espresso'
2521
+				), __FILE__, __FUNCTION__, __LINE__
2522
+			);
2523
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2524
+		} else {
2525
+			$att_nmbr = 1;
2526
+			foreach ($registrations as $registration) {
2527
+				/* @var $registration EE_Registration */
2528
+				$attendee                                                    = $registration->attendee()
2529
+					? $registration->attendee()
2530
+					: EEM_Attendee::instance()
2531
+								  ->create_default_object();
2532
+				$this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2533
+				$this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2534
+				$this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2535
+				$this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2536
+				$this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2537
+				$this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2538
+					', ',
2539
+					$attendee->full_address_as_array()
2540
+				);
2541
+				$this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2542
+					array(
2543
+						'action' => 'edit_attendee',
2544
+						'post'   => $attendee->ID(),
2545
+					),
2546
+					REG_ADMIN_URL
2547
+				);
2548
+				$this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2549
+				$att_nmbr++;
2550
+			}
2551
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2552
+		}
2553
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2554
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2555
+	}
2556
+
2557
+
2558
+	/**
2559
+	 *        generates HTML for the Edit Registration side meta box
2560
+	 *
2561
+	 * @access public
2562
+	 * @return void
2563
+	 * @throws DomainException
2564
+	 * @throws EE_Error
2565
+	 * @throws InvalidArgumentException
2566
+	 * @throws InvalidDataTypeException
2567
+	 * @throws InvalidInterfaceException
2568
+	 */
2569
+	public function _reg_registrant_side_meta_box()
2570
+	{
2571
+		/*@var $attendee EE_Attendee */
2572
+		$att_check = $this->_registration->attendee();
2573
+		$attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2574
+		//now let's determine if this is not the primary registration.  If it isn't then we set the
2575
+		//primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2576
+		//primary registration object (that way we know if we need to show create button or not)
2577
+		if ( ! $this->_registration->is_primary_registrant()) {
2578
+			$primary_registration = $this->_registration->get_primary_registration();
2579
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2580
+				: null;
2581
+			if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2582
+				//in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2583
+				//custom attendee object so let's not worry about the primary reg.
2584
+				$primary_registration = null;
2585
+			}
2586
+		} else {
2587
+			$primary_registration = null;
2588
+		}
2589
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2590
+		$this->_template_args['fname']             = $attendee->fname();
2591
+		$this->_template_args['lname']             = $attendee->lname();
2592
+		$this->_template_args['email']             = $attendee->email();
2593
+		$this->_template_args['phone']             = $attendee->phone();
2594
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2595
+		//edit link
2596
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2597
+			'action' => 'edit_attendee',
2598
+			'post'   => $attendee->ID(),
2599
+		), REG_ADMIN_URL);
2600
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2601
+		//create link
2602
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2603
+			? EE_Admin_Page::add_query_args_and_nonce(array(
2604
+				'action'  => 'duplicate_attendee',
2605
+				'_REG_ID' => $this->_registration->ID(),
2606
+			), REG_ADMIN_URL) : '';
2607
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2608
+		$this->_template_args['att_check']    = $att_check;
2609
+		$template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2610
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2611
+	}
2612
+
2613
+
2614
+	/**
2615
+	 * trash or restore registrations
2616
+	 *
2617
+	 * @param  boolean $trash whether to archive or restore
2618
+	 * @return void
2619
+	 * @throws EE_Error
2620
+	 * @throws InvalidArgumentException
2621
+	 * @throws InvalidDataTypeException
2622
+	 * @throws InvalidInterfaceException
2623
+	 * @throws RuntimeException
2624
+	 * @access protected
2625
+	 */
2626
+	protected function _trash_or_restore_registrations($trash = true)
2627
+	{
2628
+		//if empty _REG_ID then get out because there's nothing to do
2629
+		if (empty($this->_req_data['_REG_ID'])) {
2630
+			EE_Error::add_error(
2631
+				sprintf(
2632
+					esc_html__(
2633
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2634
+						'event_espresso'
2635
+					),
2636
+					$trash ? 'trash' : 'restore'
2637
+				),
2638
+				__FILE__, __LINE__, __FUNCTION__
2639
+			);
2640
+			$this->_redirect_after_action(false, '', '', array(), true);
2641
+		}
2642
+		$success = 0;
2643
+		$overwrite_msgs = false;
2644
+		//Checkboxes
2645
+		if ( ! is_array($this->_req_data['_REG_ID'])) {
2646
+			$this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2647
+		}
2648
+		$reg_count = count($this->_req_data['_REG_ID']);
2649
+		// cycle thru checkboxes
2650
+		foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2651
+			/** @var EE_Registration $REG */
2652
+			$REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2653
+			$payments = $REG->registration_payments();
2654
+			if (! empty($payments)) {
2655
+				$name = $REG->attendee() instanceof EE_Attendee
2656
+					? $REG->attendee()->full_name()
2657
+					: esc_html__('Unknown Attendee', 'event_espresso');
2658
+				$overwrite_msgs = true;
2659
+				EE_Error::add_error(
2660
+					sprintf(
2661
+						esc_html__(
2662
+							'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2663
+							'event_espresso'
2664
+						),
2665
+						$name
2666
+					),
2667
+					__FILE__, __FUNCTION__, __LINE__
2668
+				);
2669
+				//can't trash this registration because it has payments.
2670
+				continue;
2671
+			}
2672
+			$updated = $trash ? $REG->delete() : $REG->restore();
2673
+			if ($updated) {
2674
+				$success++;
2675
+			}
2676
+		}
2677
+		$this->_redirect_after_action(
2678
+			$success === $reg_count, // were ALL registrations affected?
2679
+			$success > 1
2680
+				? esc_html__('Registrations', 'event_espresso')
2681
+				: esc_html__('Registration', 'event_espresso'),
2682
+			$trash
2683
+				? esc_html__('moved to the trash', 'event_espresso')
2684
+				: esc_html__('restored', 'event_espresso'),
2685
+			array('action' => 'default'),
2686
+			$overwrite_msgs
2687
+		);
2688
+	}
2689
+
2690
+
2691
+	/**
2692
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2693
+	 * registration but also.
2694
+	 * 1. Removing relations to EE_Attendee
2695
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2696
+	 * ALSO trashed.
2697
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2698
+	 * 4. Removing relationships between all tickets and the related registrations
2699
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2700
+	 * 6. Deleting permanently any related Checkins.
2701
+	 *
2702
+	 * @return void
2703
+	 * @throws EE_Error
2704
+	 * @throws InvalidArgumentException
2705
+	 * @throws InvalidDataTypeException
2706
+	 * @throws InvalidInterfaceException
2707
+	 */
2708
+	protected function _delete_registrations()
2709
+	{
2710
+		$REG_MDL = EEM_Registration::instance();
2711
+		$success = 1;
2712
+		//Checkboxes
2713
+		if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2714
+			// if array has more than one element than success message should be plural
2715
+			$success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2716
+			// cycle thru checkboxes
2717
+			while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2718
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2719
+				if ( ! $REG instanceof EE_Registration) {
2720
+					continue;
2721
+				}
2722
+				$deleted = $this->_delete_registration($REG);
2723
+				if ( ! $deleted) {
2724
+					$success = 0;
2725
+				}
2726
+			}
2727
+		} else {
2728
+			// grab single id and delete
2729
+			$REG_ID  = $this->_req_data['_REG_ID'];
2730
+			$REG     = $REG_MDL->get_one_by_ID($REG_ID);
2731
+			$deleted = $this->_delete_registration($REG);
2732
+			if ( ! $deleted) {
2733
+				$success = 0;
2734
+			}
2735
+		}
2736
+		$what        = $success > 1
2737
+			? esc_html__('Registrations', 'event_espresso')
2738
+			: esc_html__('Registration', 'event_espresso');
2739
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2740
+		$this->_redirect_after_action(
2741
+			$success,
2742
+			$what,
2743
+			$action_desc,
2744
+			array('action' => 'default'),
2745
+			true
2746
+		);
2747
+	}
2748
+
2749
+
2750
+	/**
2751
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2752
+	 * models get affected.
2753
+	 *
2754
+	 * @param  EE_Registration $REG registration to be deleted permenantly
2755
+	 * @return bool true = successful deletion, false = fail.
2756
+	 * @throws EE_Error
2757
+	 */
2758
+	protected function _delete_registration(EE_Registration $REG)
2759
+	{
2760
+		//first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2761
+		//registrations on the transaction that are NOT trashed.
2762
+		$TXN         = $REG->get_first_related('Transaction');
2763
+		$REGS        = $TXN->get_many_related('Registration');
2764
+		$all_trashed = true;
2765
+		foreach ($REGS as $registration) {
2766
+			if ( ! $registration->get('REG_deleted')) {
2767
+				$all_trashed = false;
2768
+			}
2769
+		}
2770
+		if ( ! $all_trashed) {
2771
+			EE_Error::add_error(
2772
+				esc_html__(
2773
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2774
+					'event_espresso'
2775
+				),
2776
+				__FILE__, __FUNCTION__, __LINE__
2777
+			);
2778
+			return false;
2779
+		}
2780
+		//k made it here so that means we can delete all the related transactions and their answers (but let's do them
2781
+		//separately from THIS one).
2782
+		foreach ($REGS as $registration) {
2783
+			//delete related answers
2784
+			$registration->delete_related_permanently('Answer');
2785
+			//remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2786
+			$attendee = $registration->get_first_related('Attendee');
2787
+			if ($attendee instanceof EE_Attendee) {
2788
+				$registration->_remove_relation_to($attendee, 'Attendee');
2789
+			}
2790
+			//now remove relationships to tickets on this registration.
2791
+			$registration->_remove_relations('Ticket');
2792
+			//now delete permanently the checkins related to this registration.
2793
+			$registration->delete_related_permanently('Checkin');
2794
+			if ($registration->ID() === $REG->ID()) {
2795
+				continue;
2796
+			} //we don't want to delete permanently the existing registration just yet.
2797
+			//remove relation to transaction for these registrations if NOT the existing registrations
2798
+			$registration->_remove_relations('Transaction');
2799
+			//delete permanently any related messages.
2800
+			$registration->delete_related_permanently('Message');
2801
+			//now delete this registration permanently
2802
+			$registration->delete_permanently();
2803
+		}
2804
+		//now all related registrations on the transaction are handled.  So let's just handle this registration itself
2805
+		// (the transaction and line items should be all that's left).
2806
+		// delete the line items related to the transaction for this registration.
2807
+		$TXN->delete_related_permanently('Line_Item');
2808
+		//we need to remove all the relationships on the transaction
2809
+		$TXN->delete_related_permanently('Payment');
2810
+		$TXN->delete_related_permanently('Extra_Meta');
2811
+		$TXN->delete_related_permanently('Message');
2812
+		//now we can delete this REG permanently (and the transaction of course)
2813
+		$REG->delete_related_permanently('Transaction');
2814
+		return $REG->delete_permanently();
2815
+	}
2816
+
2817
+
2818
+	/**
2819
+	 *    generates HTML for the Register New Attendee Admin page
2820
+	 *
2821
+	 * @access private
2822
+	 * @throws DomainException
2823
+	 * @throws EE_Error
2824
+	 */
2825
+	public function new_registration()
2826
+	{
2827
+		if ( ! $this->_set_reg_event()) {
2828
+			throw new EE_Error(
2829
+				esc_html__(
2830
+					'Unable to continue with registering because there is no Event ID in the request',
2831
+					'event_espresso'
2832
+				)
2833
+			);
2834
+		}
2835
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2836
+		// gotta start with a clean slate if we're not coming here via ajax
2837
+		if ( ! defined('DOING_AJAX')
2838
+			 && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2839
+		) {
2840
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2841
+		}
2842
+		$this->_template_args['event_name'] = '';
2843
+		// event name
2844
+		if ($this->_reg_event) {
2845
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2846
+			$edit_event_url                     = self::add_query_args_and_nonce(array(
2847
+				'action' => 'edit',
2848
+				'post'   => $this->_reg_event->ID(),
2849
+			), EVENTS_ADMIN_URL);
2850
+			$edit_event_lnk                     = '<a href="'
2851
+												  . $edit_event_url
2852
+												  . '" title="'
2853
+												  . esc_attr__('Edit ', 'event_espresso')
2854
+												  . $this->_reg_event->name()
2855
+												  . '">'
2856
+												  . esc_html__('Edit Event', 'event_espresso')
2857
+												  . '</a>';
2858
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2859
+												   . $edit_event_lnk
2860
+												   . '</span>';
2861
+		}
2862
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2863
+		if (defined('DOING_AJAX')) {
2864
+			$this->_return_json();
2865
+		}
2866
+		// grab header
2867
+		$template_path                              =
2868
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2869
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2870
+			$this->_template_args, true);
2871
+		//$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2872
+		// the details template wrapper
2873
+		$this->display_admin_page_with_sidebar();
2874
+	}
2875
+
2876
+
2877
+	/**
2878
+	 * This returns the content for a registration step
2879
+	 *
2880
+	 * @access protected
2881
+	 * @return string html
2882
+	 * @throws DomainException
2883
+	 * @throws EE_Error
2884
+	 * @throws InvalidArgumentException
2885
+	 * @throws InvalidDataTypeException
2886
+	 * @throws InvalidInterfaceException
2887
+	 */
2888
+	protected function _get_registration_step_content()
2889
+	{
2890
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2891
+			$warning_msg = sprintf(
2892
+				esc_html__(
2893
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2894
+					'event_espresso'
2895
+				),
2896
+				'<br />',
2897
+				'<h3 class="important-notice">',
2898
+				'</h3>',
2899
+				'<div class="float-right">',
2900
+				'<span id="redirect_timer" class="important-notice">30</span>',
2901
+				'</div>',
2902
+				'<b>',
2903
+				'</b>'
2904
+			);
2905
+			return '
2906 2906
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2907 2907
 	<script >
2908 2908
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2915,847 +2915,847 @@  discard block
 block discarded – undo
2915 2915
 	        }
2916 2916
 	    }, 800 );
2917 2917
 	</script >';
2918
-        }
2919
-        $template_args = array(
2920
-            'title'                    => '',
2921
-            'content'                  => '',
2922
-            'step_button_text'         => '',
2923
-            'show_notification_toggle' => false,
2924
-        );
2925
-        //to indicate we're processing a new registration
2926
-        $hidden_fields = array(
2927
-            'processing_registration' => array(
2928
-                'type'  => 'hidden',
2929
-                'value' => 0,
2930
-            ),
2931
-            'event_id'                => array(
2932
-                'type'  => 'hidden',
2933
-                'value' => $this->_reg_event->ID(),
2934
-            ),
2935
-        );
2936
-        //if the cart is empty then we know we're at step one so we'll display ticket selector
2937
-        $cart = EE_Registry::instance()->SSN->cart();
2938
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2939
-        switch ($step) {
2940
-            case 'ticket' :
2941
-                $hidden_fields['processing_registration']['value'] = 1;
2942
-                $template_args['title']                            = esc_html__(
2943
-                    'Step One: Select the Ticket for this registration',
2944
-                    'event_espresso'
2945
-                );
2946
-                $template_args['content']                          =
2947
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2948
-                $template_args['step_button_text']                 = esc_html__(
2949
-                    'Add Tickets and Continue to Registrant Details',
2950
-                    'event_espresso'
2951
-                );
2952
-                $template_args['show_notification_toggle']         = false;
2953
-                break;
2954
-            case 'questions' :
2955
-                $hidden_fields['processing_registration']['value'] = 2;
2956
-                $template_args['title']                            = esc_html__(
2957
-                    'Step Two: Add Registrant Details for this Registration',
2958
-                    'event_espresso'
2959
-                );
2960
-                //in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2961
-                // properly by the first process_reg_step run.
2962
-                $template_args['content']                  =
2963
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2964
-                $template_args['step_button_text']         = esc_html__(
2965
-                    'Save Registration and Continue to Details',
2966
-                    'event_espresso'
2967
-                );
2968
-                $template_args['show_notification_toggle'] = true;
2969
-                break;
2970
-        }
2971
-        //we come back to the process_registration_step route.
2972
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2973
-        return EEH_Template::display_template(
2974
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2975
-            $template_args,
2976
-            true
2977
-        );
2978
-    }
2979
-
2980
-
2981
-    /**
2982
-     *        set_reg_event
2983
-     *
2984
-     * @access private
2985
-     * @return bool
2986
-     * @throws EE_Error
2987
-     * @throws InvalidArgumentException
2988
-     * @throws InvalidDataTypeException
2989
-     * @throws InvalidInterfaceException
2990
-     */
2991
-    private function _set_reg_event()
2992
-    {
2993
-        if (is_object($this->_reg_event)) {
2994
-            return true;
2995
-        }
2996
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2997
-        if ( ! $EVT_ID) {
2998
-            return false;
2999
-        }
3000
-        $this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
3001
-        return true;
3002
-    }
3003
-
3004
-
3005
-    /**
3006
-     * process_reg_step
3007
-     *
3008
-     * @access        public
3009
-     * @return string
3010
-     * @throws DomainException
3011
-     * @throws EE_Error
3012
-     * @throws InvalidArgumentException
3013
-     * @throws InvalidDataTypeException
3014
-     * @throws InvalidInterfaceException
3015
-     * @throws ReflectionException
3016
-     * @throws RuntimeException
3017
-     */
3018
-    public function process_reg_step()
3019
-    {
3020
-        EE_System::do_not_cache();
3021
-        $this->_set_reg_event();
3022
-        EE_Registry::instance()->REQ->set_espresso_page(true);
3023
-        EE_Registry::instance()->REQ->set('uts', time());
3024
-        //what step are we on?
3025
-        $cart = EE_Registry::instance()->SSN->cart();
3026
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3027
-        //if doing ajax then we need to verify the nonce
3028
-        if (defined('DOING_AJAX')) {
3029
-            $nonce = isset($this->_req_data[$this->_req_nonce])
3030
-                ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
3031
-            $this->_verify_nonce($nonce, $this->_req_nonce);
3032
-        }
3033
-        switch ($step) {
3034
-            case 'ticket' :
3035
-                //process ticket selection
3036
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3037
-                if ($success) {
3038
-                    EE_Error::add_success(
3039
-                        esc_html__(
3040
-                            'Tickets Selected. Now complete the registration.',
3041
-                            'event_espresso'
3042
-                        )
3043
-                    );
3044
-                } else {
3045
-                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
3046
-                }
3047
-                if (defined('DOING_AJAX')) {
3048
-                    $this->new_registration(); //display next step
3049
-                } else {
3050
-                    $query_args = array(
3051
-                        'action'                  => 'new_registration',
3052
-                        'processing_registration' => 1,
3053
-                        'event_id'                => $this->_reg_event->ID(),
3054
-                        'uts'                     => time(),
3055
-                    );
3056
-                    $this->_redirect_after_action(
3057
-                        false,
3058
-                        '',
3059
-                        '',
3060
-                        $query_args,
3061
-                        true
3062
-                    );
3063
-                }
3064
-                break;
3065
-            case 'questions' :
3066
-                if (! isset(
3067
-                    $this->_req_data['txn_reg_status_change'],
3068
-                    $this->_req_data['txn_reg_status_change']['send_notifications'])
3069
-                ) {
3070
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3071
-                }
3072
-                //process registration
3073
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3074
-                if ($cart instanceof EE_Cart) {
3075
-                    $grand_total = $cart->get_cart_grand_total();
3076
-                    if ($grand_total instanceof EE_Line_Item) {
3077
-                        $grand_total->save_this_and_descendants_to_txn();
3078
-                    }
3079
-                }
3080
-                if ( ! $transaction instanceof EE_Transaction) {
3081
-                    $query_args = array(
3082
-                        'action'                  => 'new_registration',
3083
-                        'processing_registration' => 2,
3084
-                        'event_id'                => $this->_reg_event->ID(),
3085
-                        'uts'                     => time(),
3086
-                    );
3087
-                    if (defined('DOING_AJAX')) {
3088
-                        //display registration form again because there are errors (maybe validation?)
3089
-                        $this->new_registration();
3090
-                        return;
3091
-                    } else {
3092
-                        $this->_redirect_after_action(
3093
-                            false,
3094
-                            '',
3095
-                            '',
3096
-                            $query_args,
3097
-                            true
3098
-                        );
3099
-                        return;
3100
-                    }
3101
-                }
3102
-                // maybe update status, and make sure to save transaction if not done already
3103
-                if ( ! $transaction->update_status_based_on_total_paid()) {
3104
-                    $transaction->save();
3105
-                }
3106
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3107
-                $this->_req_data = array();
3108
-                $query_args      = array(
3109
-                    'action'        => 'redirect_to_txn',
3110
-                    'TXN_ID'        => $transaction->ID(),
3111
-                    'EVT_ID'        => $this->_reg_event->ID(),
3112
-                    'event_name'    => urlencode($this->_reg_event->name()),
3113
-                    'redirect_from' => 'new_registration',
3114
-                );
3115
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3116
-                break;
3117
-        }
3118
-        //what are you looking here for?  Should be nothing to do at this point.
3119
-    }
3120
-
3121
-
3122
-    /**
3123
-     * redirect_to_txn
3124
-     *
3125
-     * @access public
3126
-     * @return void
3127
-     * @throws EE_Error
3128
-     * @throws InvalidArgumentException
3129
-     * @throws InvalidDataTypeException
3130
-     * @throws InvalidInterfaceException
3131
-     */
3132
-    public function redirect_to_txn()
3133
-    {
3134
-        EE_System::do_not_cache();
3135
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3136
-        $query_args = array(
3137
-            'action' => 'view_transaction',
3138
-            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3139
-            'page'   => 'espresso_transactions',
3140
-        );
3141
-        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3142
-            $query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3143
-            $query_args['event_name']    = urlencode($this->_req_data['event_name']);
3144
-            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
3145
-        }
3146
-        EE_Error::add_success(
3147
-            esc_html__(
3148
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3149
-                'event_espresso'
3150
-            )
3151
-        );
3152
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3153
-    }
3154
-
3155
-
3156
-    /**
3157
-     *        generates HTML for the Attendee Contact List
3158
-     *
3159
-     * @access protected
3160
-     * @return void
3161
-     */
3162
-    protected function _attendee_contact_list_table()
3163
-    {
3164
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3165
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3166
-        $this->display_admin_list_table_page_with_no_sidebar();
3167
-    }
3168
-
3169
-
3170
-    /**
3171
-     *        get_attendees
3172
-     *
3173
-     * @param      $per_page
3174
-     * @param bool $count whether to return count or data.
3175
-     * @param bool $trash
3176
-     * @return array
3177
-     * @throws EE_Error
3178
-     * @throws InvalidArgumentException
3179
-     * @throws InvalidDataTypeException
3180
-     * @throws InvalidInterfaceException
3181
-     * @access public
3182
-     */
3183
-    public function get_attendees($per_page, $count = false, $trash = false)
3184
-    {
3185
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3186
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3187
-        $ATT_MDL                    = EEM_Attendee::instance();
3188
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3189
-        switch ($this->_req_data['orderby']) {
3190
-            case 'ATT_ID':
3191
-                $orderby = 'ATT_ID';
3192
-                break;
3193
-            case 'ATT_fname':
3194
-                $orderby = 'ATT_fname';
3195
-                break;
3196
-            case 'ATT_email':
3197
-                $orderby = 'ATT_email';
3198
-                break;
3199
-            case 'ATT_city':
3200
-                $orderby = 'ATT_city';
3201
-                break;
3202
-            case 'STA_ID':
3203
-                $orderby = 'STA_ID';
3204
-                break;
3205
-            case 'CNT_ID':
3206
-                $orderby = 'CNT_ID';
3207
-                break;
3208
-            default:
3209
-                $orderby = 'ATT_lname';
3210
-        }
3211
-        $sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3212
-            ? $this->_req_data['order']
3213
-            : 'ASC';
3214
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3215
-            ? $this->_req_data['paged']
3216
-            : 1;
3217
-        $per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3218
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3219
-            ? $this->_req_data['perpage']
3220
-            : $per_page;
3221
-        $_where       = array();
3222
-        if ( ! empty($this->_req_data['s'])) {
3223
-            $sstr         = '%' . $this->_req_data['s'] . '%';
3224
-            $_where['OR'] = array(
3225
-                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3226
-                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3227
-                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3228
-                'ATT_fname'                         => array('LIKE', $sstr),
3229
-                'ATT_lname'                         => array('LIKE', $sstr),
3230
-                'ATT_short_bio'                     => array('LIKE', $sstr),
3231
-                'ATT_email'                         => array('LIKE', $sstr),
3232
-                'ATT_address'                       => array('LIKE', $sstr),
3233
-                'ATT_address2'                      => array('LIKE', $sstr),
3234
-                'ATT_city'                          => array('LIKE', $sstr),
3235
-                'Country.CNT_name'                  => array('LIKE', $sstr),
3236
-                'State.STA_name'                    => array('LIKE', $sstr),
3237
-                'ATT_phone'                         => array('LIKE', $sstr),
3238
-                'Registration.REG_final_price'      => array('LIKE', $sstr),
3239
-                'Registration.REG_code'             => array('LIKE', $sstr),
3240
-                'Registration.REG_count'            => array('LIKE', $sstr),
3241
-                'Registration.REG_group_size'       => array('LIKE', $sstr),
3242
-            );
3243
-        }
3244
-        $offset = ($current_page - 1) * $per_page;
3245
-        $limit  = $count ? null : array($offset, $per_page);
3246
-        if ($trash) {
3247
-            $_where['status'] = array('!=', 'publish');
3248
-            $all_attendees    = $count
3249
-                ? $ATT_MDL->count(array(
3250
-                    $_where,
3251
-                    'order_by' => array($orderby => $sort),
3252
-                    'limit'    => $limit,
3253
-                ), 'ATT_ID', true)
3254
-                : $ATT_MDL->get_all(array(
3255
-                    $_where,
3256
-                    'order_by' => array($orderby => $sort),
3257
-                    'limit'    => $limit,
3258
-                ));
3259
-        } else {
3260
-            $_where['status'] = array('IN', array('publish'));
3261
-            $all_attendees    = $count
3262
-                ? $ATT_MDL->count(array(
3263
-                    $_where,
3264
-                    'order_by' => array($orderby => $sort),
3265
-                    'limit'    => $limit,
3266
-                ), 'ATT_ID', true)
3267
-                : $ATT_MDL->get_all(array(
3268
-                    $_where,
3269
-                    'order_by' => array($orderby => $sort),
3270
-                    'limit'    => $limit,
3271
-                ));
3272
-        }
3273
-        return $all_attendees;
3274
-    }
3275
-
3276
-
3277
-    /**
3278
-     * This is just taking care of resending the registration confirmation
3279
-     *
3280
-     * @access protected
3281
-     * @return void
3282
-     */
3283
-    protected function _resend_registration()
3284
-    {
3285
-        $this->_process_resend_registration();
3286
-        $query_args = isset($this->_req_data['redirect_to'])
3287
-            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3288
-            : array('action' => 'default');
3289
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3290
-    }
3291
-
3292
-    /**
3293
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3294
-     * to use when selecting registrations
3295
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3296
-     *                                                     the query parameters from the request
3297
-     * @return void ends the request with a redirect or download
3298
-     */
3299
-    public function _registrations_report_base( $method_name_for_getting_query_params )
3300
-    {
3301
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3302
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3303
-                array(
3304
-                    'page'        => 'espresso_batch',
3305
-                    'batch'       => 'file',
3306
-                    'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3307
-                    'filters'     => urlencode(
3308
-                        serialize(
3309
-                            call_user_func(
3310
-                                array( $this, $method_name_for_getting_query_params ),
3311
-                                EEH_Array::is_set(
3312
-                                    $this->_req_data,
3313
-                                    'filters',
3314
-                                    array()
3315
-                                )
3316
-                            )
3317
-                        )
3318
-                ),
3319
-                'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3320
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3321
-                'return_url'  => urlencode($this->_req_data['return_url']),
3322
-            )));
3323
-        } else {
3324
-            $new_request_args = array(
3325
-                'export' => 'report',
3326
-                'action' => 'registrations_report_for_event',
3327
-                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3328
-            );
3329
-            $this->_req_data = array_merge($this->_req_data, $new_request_args);
3330
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3331
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3332
-                $EE_Export = EE_Export::instance($this->_req_data);
3333
-                $EE_Export->export();
3334
-            }
3335
-        }
3336
-    }
3337
-
3338
-
3339
-
3340
-    /**
3341
-     * Creates a registration report using only query parameters in the request
3342
-     * @return void
3343
-     */
3344
-    public function _registrations_report()
3345
-    {
3346
-        $this->_registrations_report_base('_get_registration_query_parameters');
3347
-    }
3348
-
3349
-
3350
-    public function _contact_list_export()
3351
-    {
3352
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3353
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3354
-            $EE_Export = EE_Export::instance($this->_req_data);
3355
-            $EE_Export->export_attendees();
3356
-        }
3357
-    }
3358
-
3359
-
3360
-    public function _contact_list_report()
3361
-    {
3362
-        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3363
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3364
-                'page'        => 'espresso_batch',
3365
-                'batch'       => 'file',
3366
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3367
-                'return_url'  => urlencode($this->_req_data['return_url']),
3368
-            )));
3369
-        } else {
3370
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3371
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3372
-                $EE_Export = EE_Export::instance($this->_req_data);
3373
-                $EE_Export->report_attendees();
3374
-            }
3375
-        }
3376
-    }
3377
-
3378
-
3379
-
3380
-
3381
-
3382
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3383
-    /**
3384
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3385
-     *
3386
-     * @return void
3387
-     * @throws EE_Error
3388
-     * @throws InvalidArgumentException
3389
-     * @throws InvalidDataTypeException
3390
-     * @throws InvalidInterfaceException
3391
-     */
3392
-    protected function _duplicate_attendee()
3393
-    {
3394
-        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3395
-        //verify we have necessary info
3396
-        if (empty($this->_req_data['_REG_ID'])) {
3397
-            EE_Error::add_error(
3398
-                esc_html__(
3399
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3400
-                    'event_espresso'
3401
-                ), __FILE__, __LINE__, __FUNCTION__
3402
-            );
3403
-            $query_args = array('action' => $action);
3404
-            $this->_redirect_after_action('', '', '', $query_args, true);
3405
-        }
3406
-        //okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3407
-        $registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3408
-        $attendee     = $registration->attendee();
3409
-        //remove relation of existing attendee on registration
3410
-        $registration->_remove_relation_to($attendee, 'Attendee');
3411
-        //new attendee
3412
-        $new_attendee = clone $attendee;
3413
-        $new_attendee->set('ATT_ID', 0);
3414
-        $new_attendee->save();
3415
-        //add new attendee to reg
3416
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3417
-        EE_Error::add_success(
3418
-            esc_html__(
3419
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3420
-                'event_espresso'
3421
-            )
3422
-        );
3423
-        //redirect to edit page for attendee
3424
-        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3425
-        $this->_redirect_after_action('', '', '', $query_args, true);
3426
-    }
3427
-
3428
-
3429
-    /**
3430
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3431
-     * @param int      $post_id
3432
-     * @param WP_POST $post
3433
-     * @throws DomainException
3434
-     * @throws EE_Error
3435
-     * @throws InvalidArgumentException
3436
-     * @throws InvalidDataTypeException
3437
-     * @throws InvalidInterfaceException
3438
-     * @throws LogicException
3439
-     * @throws InvalidFormSubmissionException
3440
-     */
3441
-    protected function _insert_update_cpt_item($post_id, $post)
3442
-    {
3443
-        $success  = true;
3444
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3445
-            ? EEM_Attendee::instance()->get_one_by_ID($post_id)
3446
-            : null;
3447
-        //for attendee updates
3448
-        if ($attendee instanceof EE_Attendee) {
3449
-            //note we should only be UPDATING attendees at this point.
3450
-            $updated_fields = array(
3451
-                'ATT_fname'     => $this->_req_data['ATT_fname'],
3452
-                'ATT_lname'     => $this->_req_data['ATT_lname'],
3453
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3454
-                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3455
-                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3456
-                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3457
-                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3458
-                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3459
-                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3460
-            );
3461
-            foreach ($updated_fields as $field => $value) {
3462
-                $attendee->set($field, $value);
3463
-            }
3464
-
3465
-            //process contact details metabox form handler (which will also save the attendee)
3466
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3467
-            $success = $contact_details_form->process($this->_req_data);
3468
-
3469
-            $attendee_update_callbacks = apply_filters(
3470
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3471
-                array()
3472
-            );
3473
-            foreach ($attendee_update_callbacks as $a_callback) {
3474
-                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3475
-                    throw new EE_Error(
3476
-                        sprintf(
3477
-                            esc_html__(
3478
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3479
-                                'event_espresso'
3480
-                            ),
3481
-                            $a_callback
3482
-                        )
3483
-                    );
3484
-                }
3485
-            }
3486
-        }
3487
-
3488
-        if ($success === false) {
3489
-            EE_Error::add_error(
3490
-                esc_html__(
3491
-                    'Something went wrong with updating the meta table data for the registration.',
3492
-                    'event_espresso'
3493
-                ),
3494
-                __FILE__, __FUNCTION__, __LINE__
3495
-            );
3496
-        }
3497
-    }
3498
-
3499
-
3500
-    public function trash_cpt_item($post_id)
3501
-    {
3502
-    }
3503
-
3504
-
3505
-    public function delete_cpt_item($post_id)
3506
-    {
3507
-    }
3508
-
3509
-
3510
-    public function restore_cpt_item($post_id)
3511
-    {
3512
-    }
3513
-
3514
-
3515
-    protected function _restore_cpt_item($post_id, $revision_id)
3516
-    {
3517
-    }
3518
-
3519
-
3520
-    public function attendee_editor_metaboxes()
3521
-    {
3522
-        $this->verify_cpt_object();
3523
-        remove_meta_box(
3524
-            'postexcerpt',
3525
-            esc_html__('Excerpt', 'event_espresso'),
3526
-            'post_excerpt_meta_box',
3527
-            $this->_cpt_routes[$this->_req_action],
3528
-            'normal',
3529
-            'core'
3530
-        );
3531
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3532
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3533
-            add_meta_box(
3534
-                'postexcerpt',
3535
-                esc_html__('Short Biography', 'event_espresso'),
3536
-                'post_excerpt_meta_box',
3537
-                $this->_cpt_routes[$this->_req_action],
3538
-                'normal'
3539
-            );
3540
-        }
3541
-        if (post_type_supports('espresso_attendees', 'comments')) {
3542
-            add_meta_box(
3543
-                'commentsdiv',
3544
-                esc_html__('Notes on the Contact', 'event_espresso'),
3545
-                'post_comment_meta_box',
3546
-                $this->_cpt_routes[$this->_req_action],
3547
-                'normal',
3548
-                'core'
3549
-            );
3550
-        }
3551
-        add_meta_box(
3552
-            'attendee_contact_info',
3553
-            esc_html__('Contact Info', 'event_espresso'),
3554
-            array($this, 'attendee_contact_info'),
3555
-            $this->_cpt_routes[$this->_req_action],
3556
-            'side',
3557
-            'core'
3558
-        );
3559
-        add_meta_box(
3560
-            'attendee_details_address',
3561
-            esc_html__('Address Details', 'event_espresso'),
3562
-            array($this, 'attendee_address_details'),
3563
-            $this->_cpt_routes[$this->_req_action],
3564
-            'normal',
3565
-            'core'
3566
-        );
3567
-        add_meta_box(
3568
-            'attendee_registrations',
3569
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3570
-            array($this, 'attendee_registrations_meta_box'),
3571
-            $this->_cpt_routes[$this->_req_action],
3572
-            'normal',
3573
-            'high'
3574
-        );
3575
-    }
3576
-
3577
-
3578
-    /**
3579
-     * Metabox for attendee contact info
3580
-     *
3581
-     * @param  WP_Post $post wp post object
3582
-     * @return string attendee contact info ( and form )
3583
-     * @throws EE_Error
3584
-     * @throws InvalidArgumentException
3585
-     * @throws InvalidDataTypeException
3586
-     * @throws InvalidInterfaceException
3587
-     * @throws LogicException
3588
-     * @throws DomainException
3589
-     */
3590
-    public function attendee_contact_info($post)
3591
-    {
3592
-        //get attendee object ( should already have it )
3593
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3594
-        $form->enqueueStylesAndScripts();
3595
-        echo $form->display();
3596
-    }
3597
-
3598
-
3599
-    /**
3600
-     * Return form handler for the contact details metabox
3601
-     *
3602
-     * @param EE_Attendee $attendee
3603
-     * @return AttendeeContactDetailsMetaboxFormHandler
3604
-     * @throws DomainException
3605
-     * @throws InvalidArgumentException
3606
-     * @throws InvalidDataTypeException
3607
-     * @throws InvalidInterfaceException
3608
-     */
3609
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3610
-    {
3611
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3612
-    }
3613
-
3614
-
3615
-    /**
3616
-     * Metabox for attendee details
3617
-     *
3618
-     * @param  WP_Post $post wp post object
3619
-     * @throws DomainException
3620
-     */
3621
-    public function attendee_address_details($post)
3622
-    {
3623
-        //get attendee object (should already have it)
3624
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3625
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3626
-            new EE_Question_Form_Input(
3627
-                EE_Question::new_instance(
3628
-                    array(
3629
-                        'QST_ID'           => 0,
3630
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3631
-                        'QST_system'       => 'admin-state',
3632
-                    )
3633
-                ),
3634
-                EE_Answer::new_instance(
3635
-                    array(
3636
-                        'ANS_ID'    => 0,
3637
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3638
-                    )
3639
-                ),
3640
-                array(
3641
-                    'input_id'       => 'STA_ID',
3642
-                    'input_name'     => 'STA_ID',
3643
-                    'input_prefix'   => '',
3644
-                    'append_qstn_id' => false,
3645
-                )
3646
-            )
3647
-        );
3648
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3649
-            new EE_Question_Form_Input(
3650
-                EE_Question::new_instance(
3651
-                    array(
3652
-                        'QST_ID'           => 0,
3653
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3654
-                        'QST_system'       => 'admin-country',
3655
-                    )
3656
-                ),
3657
-                EE_Answer::new_instance(
3658
-                    array(
3659
-                        'ANS_ID'    => 0,
3660
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3661
-                    )
3662
-                ),
3663
-                array(
3664
-                    'input_id'       => 'CNT_ISO',
3665
-                    'input_name'     => 'CNT_ISO',
3666
-                    'input_prefix'   => '',
3667
-                    'append_qstn_id' => false,
3668
-                )
3669
-            )
3670
-        );
3671
-        $template                             =
3672
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3673
-        EEH_Template::display_template($template, $this->_template_args);
3674
-    }
3675
-
3676
-
3677
-    /**
3678
-     *        _attendee_details
3679
-     *
3680
-     * @access protected
3681
-     * @param $post
3682
-     * @return void
3683
-     * @throws DomainException
3684
-     * @throws EE_Error
3685
-     */
3686
-    public function attendee_registrations_meta_box($post)
3687
-    {
3688
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3689
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3690
-        $template                              =
3691
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3692
-        EEH_Template::display_template($template, $this->_template_args);
3693
-    }
3694
-
3695
-
3696
-    /**
3697
-     * add in the form fields for the attendee edit
3698
-     *
3699
-     * @param  WP_Post $post wp post object
3700
-     * @return string html for new form.
3701
-     * @throws DomainException
3702
-     */
3703
-    public function after_title_form_fields($post)
3704
-    {
3705
-        if ($post->post_type == 'espresso_attendees') {
3706
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3707
-            $template_args['attendee'] = $this->_cpt_model_obj;
3708
-            EEH_Template::display_template($template, $template_args);
3709
-        }
3710
-    }
3711
-
3712
-
3713
-    /**
3714
-     *        _trash_or_restore_attendee
3715
-     *
3716
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3717
-     * @return void
3718
-     * @throws EE_Error
3719
-     * @throws InvalidArgumentException
3720
-     * @throws InvalidDataTypeException
3721
-     * @throws InvalidInterfaceException
3722
-     * @access protected
3723
-     */
3724
-    protected function _trash_or_restore_attendees($trash = true)
3725
-    {
3726
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3727
-        $ATT_MDL = EEM_Attendee::instance();
3728
-        $success = 1;
3729
-        //Checkboxes
3730
-        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3731
-            // if array has more than one element than success message should be plural
3732
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3733
-            // cycle thru checkboxes
3734
-            while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3735
-                $updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3736
-                    : $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3737
-                if ( ! $updated) {
3738
-                    $success = 0;
3739
-                }
3740
-            }
3741
-        } else {
3742
-            // grab single id and delete
3743
-            $ATT_ID = absint($this->_req_data['ATT_ID']);
3744
-            //get attendee
3745
-            $att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3746
-            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3747
-            $updated = $att->save();
3748
-            if ( ! $updated) {
3749
-                $success = 0;
3750
-            }
3751
-        }
3752
-        $what        = $success > 1
3753
-            ? esc_html__('Contacts', 'event_espresso')
3754
-            : esc_html__('Contact', 'event_espresso');
3755
-        $action_desc = $trash
3756
-            ? esc_html__('moved to the trash', 'event_espresso')
3757
-            : esc_html__('restored', 'event_espresso');
3758
-        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3759
-    }
2918
+		}
2919
+		$template_args = array(
2920
+			'title'                    => '',
2921
+			'content'                  => '',
2922
+			'step_button_text'         => '',
2923
+			'show_notification_toggle' => false,
2924
+		);
2925
+		//to indicate we're processing a new registration
2926
+		$hidden_fields = array(
2927
+			'processing_registration' => array(
2928
+				'type'  => 'hidden',
2929
+				'value' => 0,
2930
+			),
2931
+			'event_id'                => array(
2932
+				'type'  => 'hidden',
2933
+				'value' => $this->_reg_event->ID(),
2934
+			),
2935
+		);
2936
+		//if the cart is empty then we know we're at step one so we'll display ticket selector
2937
+		$cart = EE_Registry::instance()->SSN->cart();
2938
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2939
+		switch ($step) {
2940
+			case 'ticket' :
2941
+				$hidden_fields['processing_registration']['value'] = 1;
2942
+				$template_args['title']                            = esc_html__(
2943
+					'Step One: Select the Ticket for this registration',
2944
+					'event_espresso'
2945
+				);
2946
+				$template_args['content']                          =
2947
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2948
+				$template_args['step_button_text']                 = esc_html__(
2949
+					'Add Tickets and Continue to Registrant Details',
2950
+					'event_espresso'
2951
+				);
2952
+				$template_args['show_notification_toggle']         = false;
2953
+				break;
2954
+			case 'questions' :
2955
+				$hidden_fields['processing_registration']['value'] = 2;
2956
+				$template_args['title']                            = esc_html__(
2957
+					'Step Two: Add Registrant Details for this Registration',
2958
+					'event_espresso'
2959
+				);
2960
+				//in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2961
+				// properly by the first process_reg_step run.
2962
+				$template_args['content']                  =
2963
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2964
+				$template_args['step_button_text']         = esc_html__(
2965
+					'Save Registration and Continue to Details',
2966
+					'event_espresso'
2967
+				);
2968
+				$template_args['show_notification_toggle'] = true;
2969
+				break;
2970
+		}
2971
+		//we come back to the process_registration_step route.
2972
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2973
+		return EEH_Template::display_template(
2974
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2975
+			$template_args,
2976
+			true
2977
+		);
2978
+	}
2979
+
2980
+
2981
+	/**
2982
+	 *        set_reg_event
2983
+	 *
2984
+	 * @access private
2985
+	 * @return bool
2986
+	 * @throws EE_Error
2987
+	 * @throws InvalidArgumentException
2988
+	 * @throws InvalidDataTypeException
2989
+	 * @throws InvalidInterfaceException
2990
+	 */
2991
+	private function _set_reg_event()
2992
+	{
2993
+		if (is_object($this->_reg_event)) {
2994
+			return true;
2995
+		}
2996
+		$EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2997
+		if ( ! $EVT_ID) {
2998
+			return false;
2999
+		}
3000
+		$this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
3001
+		return true;
3002
+	}
3003
+
3004
+
3005
+	/**
3006
+	 * process_reg_step
3007
+	 *
3008
+	 * @access        public
3009
+	 * @return string
3010
+	 * @throws DomainException
3011
+	 * @throws EE_Error
3012
+	 * @throws InvalidArgumentException
3013
+	 * @throws InvalidDataTypeException
3014
+	 * @throws InvalidInterfaceException
3015
+	 * @throws ReflectionException
3016
+	 * @throws RuntimeException
3017
+	 */
3018
+	public function process_reg_step()
3019
+	{
3020
+		EE_System::do_not_cache();
3021
+		$this->_set_reg_event();
3022
+		EE_Registry::instance()->REQ->set_espresso_page(true);
3023
+		EE_Registry::instance()->REQ->set('uts', time());
3024
+		//what step are we on?
3025
+		$cart = EE_Registry::instance()->SSN->cart();
3026
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3027
+		//if doing ajax then we need to verify the nonce
3028
+		if (defined('DOING_AJAX')) {
3029
+			$nonce = isset($this->_req_data[$this->_req_nonce])
3030
+				? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
3031
+			$this->_verify_nonce($nonce, $this->_req_nonce);
3032
+		}
3033
+		switch ($step) {
3034
+			case 'ticket' :
3035
+				//process ticket selection
3036
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3037
+				if ($success) {
3038
+					EE_Error::add_success(
3039
+						esc_html__(
3040
+							'Tickets Selected. Now complete the registration.',
3041
+							'event_espresso'
3042
+						)
3043
+					);
3044
+				} else {
3045
+					$query_args['step_error'] = $this->_req_data['step_error'] = true;
3046
+				}
3047
+				if (defined('DOING_AJAX')) {
3048
+					$this->new_registration(); //display next step
3049
+				} else {
3050
+					$query_args = array(
3051
+						'action'                  => 'new_registration',
3052
+						'processing_registration' => 1,
3053
+						'event_id'                => $this->_reg_event->ID(),
3054
+						'uts'                     => time(),
3055
+					);
3056
+					$this->_redirect_after_action(
3057
+						false,
3058
+						'',
3059
+						'',
3060
+						$query_args,
3061
+						true
3062
+					);
3063
+				}
3064
+				break;
3065
+			case 'questions' :
3066
+				if (! isset(
3067
+					$this->_req_data['txn_reg_status_change'],
3068
+					$this->_req_data['txn_reg_status_change']['send_notifications'])
3069
+				) {
3070
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3071
+				}
3072
+				//process registration
3073
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3074
+				if ($cart instanceof EE_Cart) {
3075
+					$grand_total = $cart->get_cart_grand_total();
3076
+					if ($grand_total instanceof EE_Line_Item) {
3077
+						$grand_total->save_this_and_descendants_to_txn();
3078
+					}
3079
+				}
3080
+				if ( ! $transaction instanceof EE_Transaction) {
3081
+					$query_args = array(
3082
+						'action'                  => 'new_registration',
3083
+						'processing_registration' => 2,
3084
+						'event_id'                => $this->_reg_event->ID(),
3085
+						'uts'                     => time(),
3086
+					);
3087
+					if (defined('DOING_AJAX')) {
3088
+						//display registration form again because there are errors (maybe validation?)
3089
+						$this->new_registration();
3090
+						return;
3091
+					} else {
3092
+						$this->_redirect_after_action(
3093
+							false,
3094
+							'',
3095
+							'',
3096
+							$query_args,
3097
+							true
3098
+						);
3099
+						return;
3100
+					}
3101
+				}
3102
+				// maybe update status, and make sure to save transaction if not done already
3103
+				if ( ! $transaction->update_status_based_on_total_paid()) {
3104
+					$transaction->save();
3105
+				}
3106
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3107
+				$this->_req_data = array();
3108
+				$query_args      = array(
3109
+					'action'        => 'redirect_to_txn',
3110
+					'TXN_ID'        => $transaction->ID(),
3111
+					'EVT_ID'        => $this->_reg_event->ID(),
3112
+					'event_name'    => urlencode($this->_reg_event->name()),
3113
+					'redirect_from' => 'new_registration',
3114
+				);
3115
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3116
+				break;
3117
+		}
3118
+		//what are you looking here for?  Should be nothing to do at this point.
3119
+	}
3120
+
3121
+
3122
+	/**
3123
+	 * redirect_to_txn
3124
+	 *
3125
+	 * @access public
3126
+	 * @return void
3127
+	 * @throws EE_Error
3128
+	 * @throws InvalidArgumentException
3129
+	 * @throws InvalidDataTypeException
3130
+	 * @throws InvalidInterfaceException
3131
+	 */
3132
+	public function redirect_to_txn()
3133
+	{
3134
+		EE_System::do_not_cache();
3135
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3136
+		$query_args = array(
3137
+			'action' => 'view_transaction',
3138
+			'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3139
+			'page'   => 'espresso_transactions',
3140
+		);
3141
+		if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3142
+			$query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3143
+			$query_args['event_name']    = urlencode($this->_req_data['event_name']);
3144
+			$query_args['redirect_from'] = $this->_req_data['redirect_from'];
3145
+		}
3146
+		EE_Error::add_success(
3147
+			esc_html__(
3148
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3149
+				'event_espresso'
3150
+			)
3151
+		);
3152
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3153
+	}
3154
+
3155
+
3156
+	/**
3157
+	 *        generates HTML for the Attendee Contact List
3158
+	 *
3159
+	 * @access protected
3160
+	 * @return void
3161
+	 */
3162
+	protected function _attendee_contact_list_table()
3163
+	{
3164
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3165
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3166
+		$this->display_admin_list_table_page_with_no_sidebar();
3167
+	}
3168
+
3169
+
3170
+	/**
3171
+	 *        get_attendees
3172
+	 *
3173
+	 * @param      $per_page
3174
+	 * @param bool $count whether to return count or data.
3175
+	 * @param bool $trash
3176
+	 * @return array
3177
+	 * @throws EE_Error
3178
+	 * @throws InvalidArgumentException
3179
+	 * @throws InvalidDataTypeException
3180
+	 * @throws InvalidInterfaceException
3181
+	 * @access public
3182
+	 */
3183
+	public function get_attendees($per_page, $count = false, $trash = false)
3184
+	{
3185
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3186
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3187
+		$ATT_MDL                    = EEM_Attendee::instance();
3188
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3189
+		switch ($this->_req_data['orderby']) {
3190
+			case 'ATT_ID':
3191
+				$orderby = 'ATT_ID';
3192
+				break;
3193
+			case 'ATT_fname':
3194
+				$orderby = 'ATT_fname';
3195
+				break;
3196
+			case 'ATT_email':
3197
+				$orderby = 'ATT_email';
3198
+				break;
3199
+			case 'ATT_city':
3200
+				$orderby = 'ATT_city';
3201
+				break;
3202
+			case 'STA_ID':
3203
+				$orderby = 'STA_ID';
3204
+				break;
3205
+			case 'CNT_ID':
3206
+				$orderby = 'CNT_ID';
3207
+				break;
3208
+			default:
3209
+				$orderby = 'ATT_lname';
3210
+		}
3211
+		$sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3212
+			? $this->_req_data['order']
3213
+			: 'ASC';
3214
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3215
+			? $this->_req_data['paged']
3216
+			: 1;
3217
+		$per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3218
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3219
+			? $this->_req_data['perpage']
3220
+			: $per_page;
3221
+		$_where       = array();
3222
+		if ( ! empty($this->_req_data['s'])) {
3223
+			$sstr         = '%' . $this->_req_data['s'] . '%';
3224
+			$_where['OR'] = array(
3225
+				'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3226
+				'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3227
+				'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3228
+				'ATT_fname'                         => array('LIKE', $sstr),
3229
+				'ATT_lname'                         => array('LIKE', $sstr),
3230
+				'ATT_short_bio'                     => array('LIKE', $sstr),
3231
+				'ATT_email'                         => array('LIKE', $sstr),
3232
+				'ATT_address'                       => array('LIKE', $sstr),
3233
+				'ATT_address2'                      => array('LIKE', $sstr),
3234
+				'ATT_city'                          => array('LIKE', $sstr),
3235
+				'Country.CNT_name'                  => array('LIKE', $sstr),
3236
+				'State.STA_name'                    => array('LIKE', $sstr),
3237
+				'ATT_phone'                         => array('LIKE', $sstr),
3238
+				'Registration.REG_final_price'      => array('LIKE', $sstr),
3239
+				'Registration.REG_code'             => array('LIKE', $sstr),
3240
+				'Registration.REG_count'            => array('LIKE', $sstr),
3241
+				'Registration.REG_group_size'       => array('LIKE', $sstr),
3242
+			);
3243
+		}
3244
+		$offset = ($current_page - 1) * $per_page;
3245
+		$limit  = $count ? null : array($offset, $per_page);
3246
+		if ($trash) {
3247
+			$_where['status'] = array('!=', 'publish');
3248
+			$all_attendees    = $count
3249
+				? $ATT_MDL->count(array(
3250
+					$_where,
3251
+					'order_by' => array($orderby => $sort),
3252
+					'limit'    => $limit,
3253
+				), 'ATT_ID', true)
3254
+				: $ATT_MDL->get_all(array(
3255
+					$_where,
3256
+					'order_by' => array($orderby => $sort),
3257
+					'limit'    => $limit,
3258
+				));
3259
+		} else {
3260
+			$_where['status'] = array('IN', array('publish'));
3261
+			$all_attendees    = $count
3262
+				? $ATT_MDL->count(array(
3263
+					$_where,
3264
+					'order_by' => array($orderby => $sort),
3265
+					'limit'    => $limit,
3266
+				), 'ATT_ID', true)
3267
+				: $ATT_MDL->get_all(array(
3268
+					$_where,
3269
+					'order_by' => array($orderby => $sort),
3270
+					'limit'    => $limit,
3271
+				));
3272
+		}
3273
+		return $all_attendees;
3274
+	}
3275
+
3276
+
3277
+	/**
3278
+	 * This is just taking care of resending the registration confirmation
3279
+	 *
3280
+	 * @access protected
3281
+	 * @return void
3282
+	 */
3283
+	protected function _resend_registration()
3284
+	{
3285
+		$this->_process_resend_registration();
3286
+		$query_args = isset($this->_req_data['redirect_to'])
3287
+			? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3288
+			: array('action' => 'default');
3289
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3290
+	}
3291
+
3292
+	/**
3293
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3294
+	 * to use when selecting registrations
3295
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3296
+	 *                                                     the query parameters from the request
3297
+	 * @return void ends the request with a redirect or download
3298
+	 */
3299
+	public function _registrations_report_base( $method_name_for_getting_query_params )
3300
+	{
3301
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3302
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3303
+				array(
3304
+					'page'        => 'espresso_batch',
3305
+					'batch'       => 'file',
3306
+					'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3307
+					'filters'     => urlencode(
3308
+						serialize(
3309
+							call_user_func(
3310
+								array( $this, $method_name_for_getting_query_params ),
3311
+								EEH_Array::is_set(
3312
+									$this->_req_data,
3313
+									'filters',
3314
+									array()
3315
+								)
3316
+							)
3317
+						)
3318
+				),
3319
+				'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3320
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3321
+				'return_url'  => urlencode($this->_req_data['return_url']),
3322
+			)));
3323
+		} else {
3324
+			$new_request_args = array(
3325
+				'export' => 'report',
3326
+				'action' => 'registrations_report_for_event',
3327
+				'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3328
+			);
3329
+			$this->_req_data = array_merge($this->_req_data, $new_request_args);
3330
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3331
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3332
+				$EE_Export = EE_Export::instance($this->_req_data);
3333
+				$EE_Export->export();
3334
+			}
3335
+		}
3336
+	}
3337
+
3338
+
3339
+
3340
+	/**
3341
+	 * Creates a registration report using only query parameters in the request
3342
+	 * @return void
3343
+	 */
3344
+	public function _registrations_report()
3345
+	{
3346
+		$this->_registrations_report_base('_get_registration_query_parameters');
3347
+	}
3348
+
3349
+
3350
+	public function _contact_list_export()
3351
+	{
3352
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3353
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3354
+			$EE_Export = EE_Export::instance($this->_req_data);
3355
+			$EE_Export->export_attendees();
3356
+		}
3357
+	}
3358
+
3359
+
3360
+	public function _contact_list_report()
3361
+	{
3362
+		if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3363
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3364
+				'page'        => 'espresso_batch',
3365
+				'batch'       => 'file',
3366
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3367
+				'return_url'  => urlencode($this->_req_data['return_url']),
3368
+			)));
3369
+		} else {
3370
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3371
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3372
+				$EE_Export = EE_Export::instance($this->_req_data);
3373
+				$EE_Export->report_attendees();
3374
+			}
3375
+		}
3376
+	}
3377
+
3378
+
3379
+
3380
+
3381
+
3382
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3383
+	/**
3384
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3385
+	 *
3386
+	 * @return void
3387
+	 * @throws EE_Error
3388
+	 * @throws InvalidArgumentException
3389
+	 * @throws InvalidDataTypeException
3390
+	 * @throws InvalidInterfaceException
3391
+	 */
3392
+	protected function _duplicate_attendee()
3393
+	{
3394
+		$action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3395
+		//verify we have necessary info
3396
+		if (empty($this->_req_data['_REG_ID'])) {
3397
+			EE_Error::add_error(
3398
+				esc_html__(
3399
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3400
+					'event_espresso'
3401
+				), __FILE__, __LINE__, __FUNCTION__
3402
+			);
3403
+			$query_args = array('action' => $action);
3404
+			$this->_redirect_after_action('', '', '', $query_args, true);
3405
+		}
3406
+		//okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3407
+		$registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3408
+		$attendee     = $registration->attendee();
3409
+		//remove relation of existing attendee on registration
3410
+		$registration->_remove_relation_to($attendee, 'Attendee');
3411
+		//new attendee
3412
+		$new_attendee = clone $attendee;
3413
+		$new_attendee->set('ATT_ID', 0);
3414
+		$new_attendee->save();
3415
+		//add new attendee to reg
3416
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3417
+		EE_Error::add_success(
3418
+			esc_html__(
3419
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3420
+				'event_espresso'
3421
+			)
3422
+		);
3423
+		//redirect to edit page for attendee
3424
+		$query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3425
+		$this->_redirect_after_action('', '', '', $query_args, true);
3426
+	}
3427
+
3428
+
3429
+	/**
3430
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3431
+	 * @param int      $post_id
3432
+	 * @param WP_POST $post
3433
+	 * @throws DomainException
3434
+	 * @throws EE_Error
3435
+	 * @throws InvalidArgumentException
3436
+	 * @throws InvalidDataTypeException
3437
+	 * @throws InvalidInterfaceException
3438
+	 * @throws LogicException
3439
+	 * @throws InvalidFormSubmissionException
3440
+	 */
3441
+	protected function _insert_update_cpt_item($post_id, $post)
3442
+	{
3443
+		$success  = true;
3444
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3445
+			? EEM_Attendee::instance()->get_one_by_ID($post_id)
3446
+			: null;
3447
+		//for attendee updates
3448
+		if ($attendee instanceof EE_Attendee) {
3449
+			//note we should only be UPDATING attendees at this point.
3450
+			$updated_fields = array(
3451
+				'ATT_fname'     => $this->_req_data['ATT_fname'],
3452
+				'ATT_lname'     => $this->_req_data['ATT_lname'],
3453
+				'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3454
+				'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3455
+				'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3456
+				'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3457
+				'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3458
+				'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3459
+				'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3460
+			);
3461
+			foreach ($updated_fields as $field => $value) {
3462
+				$attendee->set($field, $value);
3463
+			}
3464
+
3465
+			//process contact details metabox form handler (which will also save the attendee)
3466
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3467
+			$success = $contact_details_form->process($this->_req_data);
3468
+
3469
+			$attendee_update_callbacks = apply_filters(
3470
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3471
+				array()
3472
+			);
3473
+			foreach ($attendee_update_callbacks as $a_callback) {
3474
+				if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3475
+					throw new EE_Error(
3476
+						sprintf(
3477
+							esc_html__(
3478
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3479
+								'event_espresso'
3480
+							),
3481
+							$a_callback
3482
+						)
3483
+					);
3484
+				}
3485
+			}
3486
+		}
3487
+
3488
+		if ($success === false) {
3489
+			EE_Error::add_error(
3490
+				esc_html__(
3491
+					'Something went wrong with updating the meta table data for the registration.',
3492
+					'event_espresso'
3493
+				),
3494
+				__FILE__, __FUNCTION__, __LINE__
3495
+			);
3496
+		}
3497
+	}
3498
+
3499
+
3500
+	public function trash_cpt_item($post_id)
3501
+	{
3502
+	}
3503
+
3504
+
3505
+	public function delete_cpt_item($post_id)
3506
+	{
3507
+	}
3508
+
3509
+
3510
+	public function restore_cpt_item($post_id)
3511
+	{
3512
+	}
3513
+
3514
+
3515
+	protected function _restore_cpt_item($post_id, $revision_id)
3516
+	{
3517
+	}
3518
+
3519
+
3520
+	public function attendee_editor_metaboxes()
3521
+	{
3522
+		$this->verify_cpt_object();
3523
+		remove_meta_box(
3524
+			'postexcerpt',
3525
+			esc_html__('Excerpt', 'event_espresso'),
3526
+			'post_excerpt_meta_box',
3527
+			$this->_cpt_routes[$this->_req_action],
3528
+			'normal',
3529
+			'core'
3530
+		);
3531
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3532
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3533
+			add_meta_box(
3534
+				'postexcerpt',
3535
+				esc_html__('Short Biography', 'event_espresso'),
3536
+				'post_excerpt_meta_box',
3537
+				$this->_cpt_routes[$this->_req_action],
3538
+				'normal'
3539
+			);
3540
+		}
3541
+		if (post_type_supports('espresso_attendees', 'comments')) {
3542
+			add_meta_box(
3543
+				'commentsdiv',
3544
+				esc_html__('Notes on the Contact', 'event_espresso'),
3545
+				'post_comment_meta_box',
3546
+				$this->_cpt_routes[$this->_req_action],
3547
+				'normal',
3548
+				'core'
3549
+			);
3550
+		}
3551
+		add_meta_box(
3552
+			'attendee_contact_info',
3553
+			esc_html__('Contact Info', 'event_espresso'),
3554
+			array($this, 'attendee_contact_info'),
3555
+			$this->_cpt_routes[$this->_req_action],
3556
+			'side',
3557
+			'core'
3558
+		);
3559
+		add_meta_box(
3560
+			'attendee_details_address',
3561
+			esc_html__('Address Details', 'event_espresso'),
3562
+			array($this, 'attendee_address_details'),
3563
+			$this->_cpt_routes[$this->_req_action],
3564
+			'normal',
3565
+			'core'
3566
+		);
3567
+		add_meta_box(
3568
+			'attendee_registrations',
3569
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3570
+			array($this, 'attendee_registrations_meta_box'),
3571
+			$this->_cpt_routes[$this->_req_action],
3572
+			'normal',
3573
+			'high'
3574
+		);
3575
+	}
3576
+
3577
+
3578
+	/**
3579
+	 * Metabox for attendee contact info
3580
+	 *
3581
+	 * @param  WP_Post $post wp post object
3582
+	 * @return string attendee contact info ( and form )
3583
+	 * @throws EE_Error
3584
+	 * @throws InvalidArgumentException
3585
+	 * @throws InvalidDataTypeException
3586
+	 * @throws InvalidInterfaceException
3587
+	 * @throws LogicException
3588
+	 * @throws DomainException
3589
+	 */
3590
+	public function attendee_contact_info($post)
3591
+	{
3592
+		//get attendee object ( should already have it )
3593
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3594
+		$form->enqueueStylesAndScripts();
3595
+		echo $form->display();
3596
+	}
3597
+
3598
+
3599
+	/**
3600
+	 * Return form handler for the contact details metabox
3601
+	 *
3602
+	 * @param EE_Attendee $attendee
3603
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3604
+	 * @throws DomainException
3605
+	 * @throws InvalidArgumentException
3606
+	 * @throws InvalidDataTypeException
3607
+	 * @throws InvalidInterfaceException
3608
+	 */
3609
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3610
+	{
3611
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3612
+	}
3613
+
3614
+
3615
+	/**
3616
+	 * Metabox for attendee details
3617
+	 *
3618
+	 * @param  WP_Post $post wp post object
3619
+	 * @throws DomainException
3620
+	 */
3621
+	public function attendee_address_details($post)
3622
+	{
3623
+		//get attendee object (should already have it)
3624
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3625
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3626
+			new EE_Question_Form_Input(
3627
+				EE_Question::new_instance(
3628
+					array(
3629
+						'QST_ID'           => 0,
3630
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3631
+						'QST_system'       => 'admin-state',
3632
+					)
3633
+				),
3634
+				EE_Answer::new_instance(
3635
+					array(
3636
+						'ANS_ID'    => 0,
3637
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3638
+					)
3639
+				),
3640
+				array(
3641
+					'input_id'       => 'STA_ID',
3642
+					'input_name'     => 'STA_ID',
3643
+					'input_prefix'   => '',
3644
+					'append_qstn_id' => false,
3645
+				)
3646
+			)
3647
+		);
3648
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3649
+			new EE_Question_Form_Input(
3650
+				EE_Question::new_instance(
3651
+					array(
3652
+						'QST_ID'           => 0,
3653
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3654
+						'QST_system'       => 'admin-country',
3655
+					)
3656
+				),
3657
+				EE_Answer::new_instance(
3658
+					array(
3659
+						'ANS_ID'    => 0,
3660
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3661
+					)
3662
+				),
3663
+				array(
3664
+					'input_id'       => 'CNT_ISO',
3665
+					'input_name'     => 'CNT_ISO',
3666
+					'input_prefix'   => '',
3667
+					'append_qstn_id' => false,
3668
+				)
3669
+			)
3670
+		);
3671
+		$template                             =
3672
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3673
+		EEH_Template::display_template($template, $this->_template_args);
3674
+	}
3675
+
3676
+
3677
+	/**
3678
+	 *        _attendee_details
3679
+	 *
3680
+	 * @access protected
3681
+	 * @param $post
3682
+	 * @return void
3683
+	 * @throws DomainException
3684
+	 * @throws EE_Error
3685
+	 */
3686
+	public function attendee_registrations_meta_box($post)
3687
+	{
3688
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3689
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3690
+		$template                              =
3691
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3692
+		EEH_Template::display_template($template, $this->_template_args);
3693
+	}
3694
+
3695
+
3696
+	/**
3697
+	 * add in the form fields for the attendee edit
3698
+	 *
3699
+	 * @param  WP_Post $post wp post object
3700
+	 * @return string html for new form.
3701
+	 * @throws DomainException
3702
+	 */
3703
+	public function after_title_form_fields($post)
3704
+	{
3705
+		if ($post->post_type == 'espresso_attendees') {
3706
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3707
+			$template_args['attendee'] = $this->_cpt_model_obj;
3708
+			EEH_Template::display_template($template, $template_args);
3709
+		}
3710
+	}
3711
+
3712
+
3713
+	/**
3714
+	 *        _trash_or_restore_attendee
3715
+	 *
3716
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3717
+	 * @return void
3718
+	 * @throws EE_Error
3719
+	 * @throws InvalidArgumentException
3720
+	 * @throws InvalidDataTypeException
3721
+	 * @throws InvalidInterfaceException
3722
+	 * @access protected
3723
+	 */
3724
+	protected function _trash_or_restore_attendees($trash = true)
3725
+	{
3726
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3727
+		$ATT_MDL = EEM_Attendee::instance();
3728
+		$success = 1;
3729
+		//Checkboxes
3730
+		if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3731
+			// if array has more than one element than success message should be plural
3732
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3733
+			// cycle thru checkboxes
3734
+			while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3735
+				$updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3736
+					: $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3737
+				if ( ! $updated) {
3738
+					$success = 0;
3739
+				}
3740
+			}
3741
+		} else {
3742
+			// grab single id and delete
3743
+			$ATT_ID = absint($this->_req_data['ATT_ID']);
3744
+			//get attendee
3745
+			$att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3746
+			$updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3747
+			$updated = $att->save();
3748
+			if ( ! $updated) {
3749
+				$success = 0;
3750
+			}
3751
+		}
3752
+		$what        = $success > 1
3753
+			? esc_html__('Contacts', 'event_espresso')
3754
+			: esc_html__('Contact', 'event_espresso');
3755
+		$action_desc = $trash
3756
+			? esc_html__('moved to the trash', 'event_espresso')
3757
+			: esc_html__('restored', 'event_espresso');
3758
+		$this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3759
+	}
3760 3760
 
3761 3761
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 2 patches
Indentation   +744 added lines, -744 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 
@@ -26,749 +26,749 @@  discard block
 block discarded – undo
26 26
 class EE_Admin_Page_Loader
27 27
 {
28 28
 
29
-    /**
30
-     * _installed_pages
31
-     * objects for page_init objects detected and loaded
32
-     *
33
-     * @access private
34
-     * @var \EE_Admin_Page_Init[]
35
-     */
36
-    private $_installed_pages = array();
37
-
38
-
39
-
40
-    /**
41
-     * this is used to hold the registry of menu slugs for all the installed admin pages
42
-     *
43
-     * @var array
44
-     */
45
-    private $_menu_slugs = array();
46
-
47
-
48
-    /**
49
-     * _caffeinated_extends
50
-     * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
51
-     * pieces needed to do so).  This property is defined in the _set_caffeinated method.
52
-     *
53
-     * @var array
54
-     */
55
-    private $_caffeinated_extends = array();
56
-
57
-
58
-
59
-    /**
60
-     * _current_caf_extend_slug
61
-     * This property is used for holding the page slug that is required for referencing the correct
62
-     * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
63
-     *
64
-     * @var array
65
-     */
66
-    private $_current_caf_extend_slug;
67
-
68
-
69
-
70
-    /**
71
-     * _caf_autoloader
72
-     * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
73
-     * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
74
-     * classes.
75
-     *
76
-     * @var array
77
-     */
78
-    //	private $_caf_autoloader = array();
79
-    /**
80
-     * _prepped_menu_maps
81
-     * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
82
-     *
83
-     * @since  4.4.0
84
-     * @var EE_Admin_Page_Menu_Map[]
85
-     */
86
-    private $_prepped_menu_maps = array();
87
-
88
-
89
-
90
-    /**
91
-     * _admin_menu_groups
92
-     * array that holds the group headings and details for
93
-     *
94
-     * @access private
95
-     * @var array
96
-     */
97
-    private $_admin_menu_groups = array();
98
-
99
-
100
-
101
-    /**
102
-     * This property will hold the hook file for setting up the filter that does all the connections between admin
103
-     * pages.
104
-     *
105
-     * @var string
106
-     */
107
-    public $hook_file;
108
-
109
-
110
-
111
-    /**
112
-     * constructor
113
-     *
114
-     * @access public
115
-     * @return \EE_Admin_Page_Loader
116
-     */
117
-    public function __construct()
118
-    {
119
-        //load menu_map classes
120
-        EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
121
-        //define the default "groups" for the admin_pages
122
-        $this->_set_menu_groups();
123
-        //let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
124
-        //		spl_autoload_register( array( $this, 'init_autoloaders') );
125
-        //let's do a scan and see what installed pages we have
126
-        $this->_get_installed_pages();
127
-        //set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
128
-        add_action('admin_menu', array($this, 'set_menus'));
129
-        add_action('network_admin_menu', array($this, 'set_network_menus'));
130
-    }
131
-
132
-
133
-
134
-    /**
135
-     * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
136
-     * files in the caffeinated folder.
137
-     *
138
-     * @access private
139
-     * @return void
140
-     */
141
-    private function _define_caffeinated_constants()
142
-    {
143
-        if (! defined('EE_CORE_CAF_ADMIN')) {
144
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
145
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
146
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
147
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
148
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
149
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
150
-        }
151
-    }
152
-
153
-
154
-
155
-    /**
156
-     * _set_menu_groups
157
-     * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
158
-     *
159
-     * @access private
160
-     * @return void
161
-     */
162
-    private function _set_menu_groups()
163
-    {
164
-
165
-        //set array of EE_Admin_Page_Menu_Group objects
166
-        $groups = array(
167
-            'main'       => new EE_Admin_Page_Menu_Group(
168
-                array(
169
-                    'menu_label'   => __('Main', 'event_espresso'),
170
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
171
-                    'menu_slug'    => 'main',
172
-                    'capability'   => 'ee_read_ee',
173
-                    'menu_order'   => 0,
174
-                    'parent_slug'  => 'espresso_events',
175
-                )
176
-            ),
177
-            'management' => new EE_Admin_Page_Menu_Group(
178
-                array(
179
-                    'menu_label'   => __('Management', 'event_espresso'),
180
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
181
-                    'menu_slug'    => 'management',
182
-                    'capability'   => 'ee_read_ee',
183
-                    'menu_order'   => 10,
184
-                    'parent_slug'  => 'espresso_events',
185
-                )
186
-            ),
187
-            'settings'   => new EE_Admin_Page_Menu_Group(
188
-                array(
189
-                    'menu_label'   => __('Settings', 'event_espresso'),
190
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
191
-                    'menu_slug'    => 'settings',
192
-                    'capability'   => 'ee_read_ee',
193
-                    'menu_order'   => 30,
194
-                    'parent_slug'  => 'espresso_events',
195
-                )
196
-            ),
197
-            'templates'  => new EE_Admin_Page_Menu_Group(
198
-                array(
199
-                    'menu_label'   => __('Templates', 'event_espresso'),
200
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
201
-                    'menu_slug'    => 'templates',
202
-                    'capability'   => 'ee_read_ee',
203
-                    'menu_order'   => 40,
204
-                    'parent_slug'  => 'espresso_events',
205
-                )
206
-            ),
207
-            'extras'     => new EE_Admin_Page_Menu_Group(
208
-                array(
209
-                    'menu_label'              => __('Extras', 'event_espresso'),
210
-                    'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
211
-                    'menu_slug'               => 'extras',
212
-                    'capability'              => 'ee_read_ee',
213
-                    'menu_order'              => 50,
214
-                    'parent_slug'             => 'espresso_events',
215
-                    'maintenance_mode_parent' => 'espresso_maintenance_settings',
216
-                )
217
-            ),
218
-            'tools'      => new EE_Admin_Page_Menu_Group(
219
-                array(
220
-                    'menu_label'   => __("Tools", "event_espresso"),
221
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
222
-                    'menu_slug'    => 'tools',
223
-                    'capability'   => 'ee_read_ee',
224
-                    'menu_order'   => 60,
225
-                    'parent_slug'  => 'espresso_events',
226
-                )
227
-            ),
228
-            'addons'     => new EE_Admin_Page_Menu_Group(
229
-                array(
230
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
231
-                    'menu_label'   => __('Add-ons', 'event_espresso'),
232
-                    'menu_slug'    => 'addons',
233
-                    'capability'   => 'ee_read_ee',
234
-                    'menu_order'   => 20,
235
-                    'parent_slug'  => 'espresso_events',
236
-                )
237
-            ),
238
-        );
239
-        $this->_admin_menu_groups = apply_filters(
240
-            'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
241
-            $groups
242
-        );
243
-    }
244
-
245
-
246
-
247
-    /**
248
-     * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
249
-     * slug.  The other utility with this function is it validates that all the groups are instances of
250
-     * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
251
-     *
252
-     * @since  4.4.0
253
-     * @throws \EE_Error
254
-     * @return EE_Admin_Page_Menu_Group[]
255
-     */
256
-    private function _rearrange_menu_groups()
257
-    {
258
-        $groups = array();
259
-        //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
260
-        usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
261
-        foreach ($this->_admin_menu_groups as $group) {
262
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
263
-                throw new EE_Error(
264
-                    sprintf(
265
-                        __(
266
-                            'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
267
-                            'event_espresso'
268
-                        ),
269
-                        print_r($group, true)
270
-                    )
271
-                );
272
-            }
273
-            $groups[$group->menu_slug] = $group;
274
-        }
275
-        return $groups;
276
-    }
277
-
278
-
279
-
280
-    /**
281
-     * _get_installed_pages
282
-     * This just gets the list of installed EE_Admin_pages.
283
-     *
284
-     * @access private
285
-     * @throws EE_Error
286
-     * @return void
287
-     */
288
-    private function _get_installed_pages()
289
-    {
290
-        $installed_refs = array();
291
-        $exclude        = array('assets', 'templates');
292
-        // grab everything in the  admin core directory
293
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
294
-        if ($admin_screens) {
295
-            foreach ($admin_screens as $admin_screen) {
296
-                // files and anything in the exclude array need not apply
297
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
298
-                    // these folders represent the different EE admin pages
299
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
300
-                }
301
-            }
302
-        }
303
-        if (empty($installed_refs)) {
304
-            $error_msg[] = __(
305
-                'There are no EE_Admin pages detected, it looks like EE did not install properly',
306
-                'event_espresso'
307
-            );
308
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
309
-                    __(
310
-                        'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
311
-                        'event_espresso'
312
-                    ),
313
-                    EE_ADMIN_PAGES
314
-                );
315
-            throw new EE_Error(implode('||', $error_msg));
316
-        }
317
-        //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
318
-        $installed_refs = $this->_set_caffeinated($installed_refs);
319
-        //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
320
-        $installed_refs             = apply_filters(
321
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
322
-            $installed_refs
323
-        );
324
-        $this->_caffeinated_extends = apply_filters(
325
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
326
-            $this->_caffeinated_extends
327
-        );
328
-        //loop through admin pages and setup the $_installed_pages array.
329
-        $hooks_ref = array();
330
-        foreach ($installed_refs as $page => $path) {
331
-            // set autoloaders for our admin page classes based on included path information
332
-            EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
333
-            // build list of installed pages
334
-            $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
335
-            // verify returned object
336
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
337
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
338
-                    continue;
339
-                }
340
-                //skip if in full maintenance mode and maintenance_mode_parent is set
341
-                $maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
342
-                if (empty($maintenance_mode_parent)
343
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
344
-                ) {
345
-                    unset($installed_refs[$page]);
346
-                    continue;
347
-                }
348
-                $menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
349
-                $this->_menu_slugs[$menu_slug] = $page;
350
-                //flag for register hooks on extended pages b/c extended pages use the default INIT.
351
-                $extend = false;
352
-                //now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
353
-                if (isset($this->_caffeinated_extends[$page])) {
354
-                    $this->_current_caf_extend_slug = $page;
355
-                    $admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
356
-                    $caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
357
-                    $caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
358
-                    add_filter(
359
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
360
-                        function($path_to_file) use ($caf_path) {
361
-                            return $caf_path;
362
-                        }
363
-                    );
364
-                    add_filter(
365
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
366
-                        function ($admin_page) use ($caf_admin_page)
367
-                        {
368
-                            return $caf_admin_page;
369
-                        }
370
-                    );
371
-                    $extend = true;
372
-                }
373
-                //let's do the registered hooks
374
-                $extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
375
-                $hooks_ref      = array_merge($hooks_ref, $extended_hooks);
376
-            }
377
-        }
378
-        //the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
379
-        //first make sure we've got unique values
380
-        $hooks_ref = array_unique($hooks_ref);
381
-        //now let's loop and require!
382
-        foreach ($hooks_ref as $path) {
383
-            require_once($path);
384
-        }
385
-        //make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
386
-        global $ee_menu_slugs;
387
-        $ee_menu_slugs = $this->_menu_slugs;
388
-        //we need to loop again to run any early code
389
-        foreach ($installed_refs as $page => $path) {
390
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
391
-                $this->_installed_pages[$page]->do_initial_loads();
392
-            }
393
-        }
394
-        do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
395
-    }
396
-
397
-
398
-
399
-    /**
400
-     * get_admin_page_object
401
-     *
402
-     * @param string $page_slug
403
-     * @return EE_Admin_Page
404
-     */
405
-    public function get_admin_page_object($page_slug = '')
406
-    {
407
-        if (isset($this->_installed_pages[$page_slug])) {
408
-            return $this->_installed_pages[$page_slug]->loaded_page_object();
409
-        }
410
-        return null;
411
-    }
412
-
413
-
414
-
415
-    /**
416
-     * _get_classname_for_admin_page
417
-     * generates an "Admin Page" class based on the directory  name
418
-     *
419
-     * @param $dir_name
420
-     * @return string
421
-     */
422
-    private function _get_classname_for_admin_page($dir_name = '')
423
-    {
424
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
425
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
426
-    }
427
-
428
-
429
-
430
-    /**
431
-     * _get_classname_for_admin_init_page
432
-     * generates an "Admin Page Init" class based on the directory  name
433
-     *
434
-     * @param $dir_name
435
-     * @return string
436
-     */
437
-    private function _get_classname_for_admin_init_page($dir_name = '')
438
-    {
439
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
440
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
441
-    }
442
-
443
-
444
-
445
-    /**
446
-     * _load_admin_page
447
-     * Loads and instantiates page_init object for a single EE_admin page.
448
-     *
449
-     * @param  string $page page_reference
450
-     * @param string  $path
451
-     * @throws EE_Error
452
-     * @return object|bool  return page object if valid, bool false if not.
453
-     */
454
-    private function _load_admin_page($page = '', $path = '')
455
-    {
456
-        $class_name = $this->_get_classname_for_admin_init_page($page);
457
-        EE_Registry::instance()->load_file($path, $class_name, 'core');
458
-        if (! class_exists($class_name)) {
459
-            $inner_error_msg = '<br />' . sprintf(
460
-                    esc_html__(
461
-                        'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
462
-                        'event_espresso'
463
-                    ),
464
-                    '<strong>' . $class_name . '</strong>'
465
-                );
466
-            $error_msg[]     = sprintf(
467
-                __('Something went wrong with loading the %s admin page.', 'event_espresso'),
468
-                $page
469
-            );
470
-            $error_msg[]     = $error_msg[0]
471
-                               . "\r\n"
472
-                               . sprintf(
473
-                                   esc_html__(
474
-                                       'There is no Init class in place for the %s admin page.',
475
-                                       'event_espresso'
476
-                                   ),
477
-                                   $page
478
-                               )
479
-                               . $inner_error_msg;
480
-            throw new EE_Error(implode('||', $error_msg));
481
-        }
482
-        $a = new ReflectionClass($class_name);
483
-        return $a->newInstance();
484
-    }
485
-
486
-
487
-
488
-    /**
489
-     * set_menus
490
-     * This method sets up the menus for EE Admin Pages
491
-     *
492
-     * @access private
493
-     * @return void
494
-     */
495
-    public function set_menus()
496
-    {
497
-        //prep the menu pages (sort, group.)
498
-        $this->_prep_pages();
499
-        foreach ($this->_prepped_menu_maps as $menu_map) {
500
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
501
-                $menu_map->add_menu_page(false);
502
-            }
503
-        }
504
-    }
505
-
506
-
507
-    /**
508
-     * set_network_menus
509
-     * This method sets up the menus for network EE Admin Pages.
510
-     * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
511
-     * are only added to the menu map if they are intended for the admin menu
512
-     *
513
-     * @return void
514
-     */
515
-    public function set_network_menus()
516
-    {
517
-        $this->_prep_pages();
518
-        foreach ($this->_prepped_menu_maps as $menu_map) {
519
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
520
-                $menu_map->add_menu_page(true);
521
-            }
522
-        }
523
-    }
524
-
525
-
526
-
527
-    /**
528
-     * _prep_pages
529
-     * sets the _prepped_menu_maps property
530
-     *
531
-     * @access private
532
-     * @throws EE_Error
533
-     * @return void
534
-     */
535
-    private function _prep_pages()
536
-    {
537
-        $pages_array = array();
538
-        //rearrange _admin_menu_groups to be indexed by group slug.
539
-        $menu_groups = $this->_rearrange_menu_groups();
540
-        foreach ($this->_installed_pages as $page) {
541
-            if ($page instanceof EE_Admin_page_Init) {
542
-                $page_map = $page->get_menu_map();
543
-                //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
544
-                if (is_array($page_map) || empty($page_map)) {
545
-                    EE_Error::add_persistent_admin_notice(
546
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
547
-                        sprintf(
548
-                            __(
549
-                                'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
550
-                                'event_espresso'
551
-                            ),
552
-                            $page->label
553
-                        )
554
-                    );
555
-                    continue;
556
-                }
557
-                //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
558
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
559
-                    throw new EE_Error(
560
-                        sprintf(
561
-                            __(
562
-                                'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
563
-                                'event_espresso'
564
-                            ),
565
-                            $page->label,
566
-                            $page_map
567
-                        )
568
-                    );
569
-                }
570
-                //use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
571
-                if (empty($page_map->maintenance_mode_parent)
572
-                    && EE_Maintenance_Mode::instance()->level()
573
-                       == EE_Maintenance_Mode::level_2_complete_maintenance) {
574
-                    continue;
575
-                }
576
-                //assign to group (remember $page_map has the admin page stored in it).
577
-                $pages_array[$page_map->menu_group][] = $page_map;
578
-            }
579
-        }
580
-        if (empty($pages_array)) {
581
-            throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
582
-        }
583
-        //let's sort the groups, make sure it's a valid group, add header (if to show).
584
-        foreach ($pages_array as $group => $menu_maps) {
585
-            //valid_group?
586
-            if (! array_key_exists($group, $menu_groups)) {
587
-                continue;
588
-            }
589
-            //sort pages.
590
-            usort($menu_maps, array($this, '_sort_menu_maps'));
591
-            //prepend header
592
-            array_unshift($menu_maps, $menu_groups[$group]);
593
-            //reset $pages_array with prepped data
594
-            $pages_array[$group] = $menu_maps;
595
-        }
596
-        //now let's setup the _prepped_menu_maps property
597
-        foreach ($menu_groups as $group => $group_objs) {
598
-            if (isset($pages_array[$group])) {
599
-                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
600
-            }
601
-        }/**/
602
-    }
603
-
604
-
605
-
606
-    /**
607
-     * This method is the "workhorse" for detecting and setting up caffeinated functionality.
608
-     * In this method there are three checks being done:
609
-     * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
610
-     * array) etc.  (new page sets are found in caffeinated/new/{page})
611
-     * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
612
-     * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
613
-     * Extend_Events_Admin_Page extends Events_Admin_Page.
614
-     * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
615
-     * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
616
-     * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
617
-     * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
618
-     * admin_pages)
619
-     *
620
-     * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
621
-     *                              loaded.
622
-     * @return array
623
-     */
624
-    private function _set_caffeinated($installed_refs)
625
-    {
626
-
627
-        //first let's check if there IS a caffeinated folder. If there is not then lets get out.
628
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
629
-            return $installed_refs;
630
-        }
631
-        $this->_define_caffeinated_constants();
632
-        $exclude = array('tickets');
633
-        //okay let's setup an "New" pages first (we'll return installed refs later)
634
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
635
-        if ($new_admin_screens) {
636
-            foreach ($new_admin_screens as $admin_screen) {
637
-                // files and anything in the exclude array need not apply
638
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
639
-                    // these folders represent the different NEW EE admin pages
640
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
641
-                    // set autoloaders for our admin page classes based on included path information
642
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
643
-                    //					$this->_caf_autoloader[] = array(
644
-                    //						'dir' => 'new',
645
-                    //						'folder' => basename( $admin_screen )
646
-                    //					);
647
-                }
648
-            }
649
-        }
650
-        //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
651
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
652
-        if ($extends) {
653
-            foreach ($extends as $extend) {
654
-                if (is_dir($extend)) {
655
-                    $extend_ref = basename($extend);
656
-                    //now let's make sure there is a file that matches the expected format
657
-                    $filename                                              = str_replace(
658
-                        ' ',
659
-                        '_',
660
-                        ucwords(
661
-                            str_replace(
662
-                                '_',
663
-                                ' ',
664
-                                $extend_ref
665
-                            )
666
-                        )
667
-                    );
668
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
669
-                    $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
670
-                        array('\\', '/'),
671
-                        DS,
672
-                        EE_CORE_CAF_ADMIN
673
-                        . 'extend'
674
-                        . DS
675
-                        . $extend_ref
676
-                        . DS
677
-                        . $filename
678
-                        . '.core.php'
679
-                    );
680
-                    $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
681
-                    // set autoloaders for our admin page classes based on included path information
682
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
683
-                    //					$this->_caf_autoloader[] = array(
684
-                    //						'dir' => 'extend',
685
-                    //						'folder' => $extend_ref
686
-                    //					);
687
-                }
688
-            }
689
-        }
690
-        //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
691
-        $ee_admin_hooks = array();
692
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
693
-        if ($hooks) {
694
-            foreach ($hooks as $hook) {
695
-                if (is_readable($hook)) {
696
-                    require_once $hook;
697
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
698
-                    $classname = str_replace('.class.php', '', $classname);
699
-                    if (class_exists($classname)) {
700
-                        $a                = new ReflectionClass($classname);
701
-                        $ee_admin_hooks[] = $a->newInstance();
702
-                    }
703
-                }
704
-            }
705
-        }/**/
706
-        $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
707
-        return $installed_refs;
708
-    }
709
-
710
-
711
-
712
-
713
-
714
-    /**
715
-     * Initial autoloader registration
716
-     * This just sets up the autoloader for the root admin files
717
-     *
718
-     * @param  string $className incoming classname to check for autoload
719
-     * @return void
720
-     */
721
-    //	public function init_autoloaders( $className ) {
722
-    //		$dir_ref = array(
723
-    //			EE_ADMIN => array('core', 'class')
724
-    //		);
725
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
726
-    //	}
727
-    /**
728
-     * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
729
-     * caffeinated folders.
730
-     *
731
-     * @access public
732
-     * @param  string $className in coming classname being called
733
-     * @return void
734
-     */
735
-    //	public function caffeinated_autoloaders( $className ) {
736
-    //		//let's setup an array of paths to check (for each subsystem)
737
-    //		$dir_ref = array();
738
-    //		foreach ( $this->_caf_autoloader as $pathinfo) {
739
-    //			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
740
-    //		}
741
-    //
742
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
743
-    //	}
744
-    /**
745
-     * Utility method for sorting the _menu_maps (callback for usort php function)
746
-     *
747
-     * @since  4.4.0
748
-     * @param  EE_Admin_Page_Menu_Map $a menu_map object
749
-     * @param  EE_Admin_Page_Menu_Map $b being compared to
750
-     * @return int    sort order
751
-     */
752
-    private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
753
-    {
754
-        if ($a->menu_order == $b->menu_order) {
755
-            return 0;
756
-        }
757
-        return ($a->menu_order < $b->menu_order) ? -1 : 1;
758
-    }
759
-
760
-
761
-
762
-    /**
763
-     * _default_header_link
764
-     * This is just a dummy method to use with header submenu items
765
-     *
766
-     * @return bool false
767
-     */
768
-    public function _default_header_link()
769
-    {
770
-        return false;
771
-    }
29
+	/**
30
+	 * _installed_pages
31
+	 * objects for page_init objects detected and loaded
32
+	 *
33
+	 * @access private
34
+	 * @var \EE_Admin_Page_Init[]
35
+	 */
36
+	private $_installed_pages = array();
37
+
38
+
39
+
40
+	/**
41
+	 * this is used to hold the registry of menu slugs for all the installed admin pages
42
+	 *
43
+	 * @var array
44
+	 */
45
+	private $_menu_slugs = array();
46
+
47
+
48
+	/**
49
+	 * _caffeinated_extends
50
+	 * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
51
+	 * pieces needed to do so).  This property is defined in the _set_caffeinated method.
52
+	 *
53
+	 * @var array
54
+	 */
55
+	private $_caffeinated_extends = array();
56
+
57
+
58
+
59
+	/**
60
+	 * _current_caf_extend_slug
61
+	 * This property is used for holding the page slug that is required for referencing the correct
62
+	 * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
63
+	 *
64
+	 * @var array
65
+	 */
66
+	private $_current_caf_extend_slug;
67
+
68
+
69
+
70
+	/**
71
+	 * _caf_autoloader
72
+	 * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
73
+	 * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
74
+	 * classes.
75
+	 *
76
+	 * @var array
77
+	 */
78
+	//	private $_caf_autoloader = array();
79
+	/**
80
+	 * _prepped_menu_maps
81
+	 * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
82
+	 *
83
+	 * @since  4.4.0
84
+	 * @var EE_Admin_Page_Menu_Map[]
85
+	 */
86
+	private $_prepped_menu_maps = array();
87
+
88
+
89
+
90
+	/**
91
+	 * _admin_menu_groups
92
+	 * array that holds the group headings and details for
93
+	 *
94
+	 * @access private
95
+	 * @var array
96
+	 */
97
+	private $_admin_menu_groups = array();
98
+
99
+
100
+
101
+	/**
102
+	 * This property will hold the hook file for setting up the filter that does all the connections between admin
103
+	 * pages.
104
+	 *
105
+	 * @var string
106
+	 */
107
+	public $hook_file;
108
+
109
+
110
+
111
+	/**
112
+	 * constructor
113
+	 *
114
+	 * @access public
115
+	 * @return \EE_Admin_Page_Loader
116
+	 */
117
+	public function __construct()
118
+	{
119
+		//load menu_map classes
120
+		EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
121
+		//define the default "groups" for the admin_pages
122
+		$this->_set_menu_groups();
123
+		//let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
124
+		//		spl_autoload_register( array( $this, 'init_autoloaders') );
125
+		//let's do a scan and see what installed pages we have
126
+		$this->_get_installed_pages();
127
+		//set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
128
+		add_action('admin_menu', array($this, 'set_menus'));
129
+		add_action('network_admin_menu', array($this, 'set_network_menus'));
130
+	}
131
+
132
+
133
+
134
+	/**
135
+	 * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
136
+	 * files in the caffeinated folder.
137
+	 *
138
+	 * @access private
139
+	 * @return void
140
+	 */
141
+	private function _define_caffeinated_constants()
142
+	{
143
+		if (! defined('EE_CORE_CAF_ADMIN')) {
144
+			define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
145
+			define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
146
+			define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
147
+			define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
148
+			define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
149
+			define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
150
+		}
151
+	}
152
+
153
+
154
+
155
+	/**
156
+	 * _set_menu_groups
157
+	 * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
158
+	 *
159
+	 * @access private
160
+	 * @return void
161
+	 */
162
+	private function _set_menu_groups()
163
+	{
164
+
165
+		//set array of EE_Admin_Page_Menu_Group objects
166
+		$groups = array(
167
+			'main'       => new EE_Admin_Page_Menu_Group(
168
+				array(
169
+					'menu_label'   => __('Main', 'event_espresso'),
170
+					'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
171
+					'menu_slug'    => 'main',
172
+					'capability'   => 'ee_read_ee',
173
+					'menu_order'   => 0,
174
+					'parent_slug'  => 'espresso_events',
175
+				)
176
+			),
177
+			'management' => new EE_Admin_Page_Menu_Group(
178
+				array(
179
+					'menu_label'   => __('Management', 'event_espresso'),
180
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
181
+					'menu_slug'    => 'management',
182
+					'capability'   => 'ee_read_ee',
183
+					'menu_order'   => 10,
184
+					'parent_slug'  => 'espresso_events',
185
+				)
186
+			),
187
+			'settings'   => new EE_Admin_Page_Menu_Group(
188
+				array(
189
+					'menu_label'   => __('Settings', 'event_espresso'),
190
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
191
+					'menu_slug'    => 'settings',
192
+					'capability'   => 'ee_read_ee',
193
+					'menu_order'   => 30,
194
+					'parent_slug'  => 'espresso_events',
195
+				)
196
+			),
197
+			'templates'  => new EE_Admin_Page_Menu_Group(
198
+				array(
199
+					'menu_label'   => __('Templates', 'event_espresso'),
200
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
201
+					'menu_slug'    => 'templates',
202
+					'capability'   => 'ee_read_ee',
203
+					'menu_order'   => 40,
204
+					'parent_slug'  => 'espresso_events',
205
+				)
206
+			),
207
+			'extras'     => new EE_Admin_Page_Menu_Group(
208
+				array(
209
+					'menu_label'              => __('Extras', 'event_espresso'),
210
+					'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
211
+					'menu_slug'               => 'extras',
212
+					'capability'              => 'ee_read_ee',
213
+					'menu_order'              => 50,
214
+					'parent_slug'             => 'espresso_events',
215
+					'maintenance_mode_parent' => 'espresso_maintenance_settings',
216
+				)
217
+			),
218
+			'tools'      => new EE_Admin_Page_Menu_Group(
219
+				array(
220
+					'menu_label'   => __("Tools", "event_espresso"),
221
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
222
+					'menu_slug'    => 'tools',
223
+					'capability'   => 'ee_read_ee',
224
+					'menu_order'   => 60,
225
+					'parent_slug'  => 'espresso_events',
226
+				)
227
+			),
228
+			'addons'     => new EE_Admin_Page_Menu_Group(
229
+				array(
230
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
231
+					'menu_label'   => __('Add-ons', 'event_espresso'),
232
+					'menu_slug'    => 'addons',
233
+					'capability'   => 'ee_read_ee',
234
+					'menu_order'   => 20,
235
+					'parent_slug'  => 'espresso_events',
236
+				)
237
+			),
238
+		);
239
+		$this->_admin_menu_groups = apply_filters(
240
+			'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
241
+			$groups
242
+		);
243
+	}
244
+
245
+
246
+
247
+	/**
248
+	 * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
249
+	 * slug.  The other utility with this function is it validates that all the groups are instances of
250
+	 * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
251
+	 *
252
+	 * @since  4.4.0
253
+	 * @throws \EE_Error
254
+	 * @return EE_Admin_Page_Menu_Group[]
255
+	 */
256
+	private function _rearrange_menu_groups()
257
+	{
258
+		$groups = array();
259
+		//first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
260
+		usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
261
+		foreach ($this->_admin_menu_groups as $group) {
262
+			if (! $group instanceof EE_Admin_Page_Menu_Group) {
263
+				throw new EE_Error(
264
+					sprintf(
265
+						__(
266
+							'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
267
+							'event_espresso'
268
+						),
269
+						print_r($group, true)
270
+					)
271
+				);
272
+			}
273
+			$groups[$group->menu_slug] = $group;
274
+		}
275
+		return $groups;
276
+	}
277
+
278
+
279
+
280
+	/**
281
+	 * _get_installed_pages
282
+	 * This just gets the list of installed EE_Admin_pages.
283
+	 *
284
+	 * @access private
285
+	 * @throws EE_Error
286
+	 * @return void
287
+	 */
288
+	private function _get_installed_pages()
289
+	{
290
+		$installed_refs = array();
291
+		$exclude        = array('assets', 'templates');
292
+		// grab everything in the  admin core directory
293
+		$admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
294
+		if ($admin_screens) {
295
+			foreach ($admin_screens as $admin_screen) {
296
+				// files and anything in the exclude array need not apply
297
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
298
+					// these folders represent the different EE admin pages
299
+					$installed_refs[basename($admin_screen)] = $admin_screen;
300
+				}
301
+			}
302
+		}
303
+		if (empty($installed_refs)) {
304
+			$error_msg[] = __(
305
+				'There are no EE_Admin pages detected, it looks like EE did not install properly',
306
+				'event_espresso'
307
+			);
308
+			$error_msg[] = $error_msg[0] . "\r\n" . sprintf(
309
+					__(
310
+						'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
311
+						'event_espresso'
312
+					),
313
+					EE_ADMIN_PAGES
314
+				);
315
+			throw new EE_Error(implode('||', $error_msg));
316
+		}
317
+		//this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
318
+		$installed_refs = $this->_set_caffeinated($installed_refs);
319
+		//allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
320
+		$installed_refs             = apply_filters(
321
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
322
+			$installed_refs
323
+		);
324
+		$this->_caffeinated_extends = apply_filters(
325
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
326
+			$this->_caffeinated_extends
327
+		);
328
+		//loop through admin pages and setup the $_installed_pages array.
329
+		$hooks_ref = array();
330
+		foreach ($installed_refs as $page => $path) {
331
+			// set autoloaders for our admin page classes based on included path information
332
+			EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
333
+			// build list of installed pages
334
+			$this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
335
+			// verify returned object
336
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
337
+				if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
338
+					continue;
339
+				}
340
+				//skip if in full maintenance mode and maintenance_mode_parent is set
341
+				$maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
342
+				if (empty($maintenance_mode_parent)
343
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
344
+				) {
345
+					unset($installed_refs[$page]);
346
+					continue;
347
+				}
348
+				$menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
349
+				$this->_menu_slugs[$menu_slug] = $page;
350
+				//flag for register hooks on extended pages b/c extended pages use the default INIT.
351
+				$extend = false;
352
+				//now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
353
+				if (isset($this->_caffeinated_extends[$page])) {
354
+					$this->_current_caf_extend_slug = $page;
355
+					$admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
356
+					$caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
357
+					$caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
358
+					add_filter(
359
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
360
+						function($path_to_file) use ($caf_path) {
361
+							return $caf_path;
362
+						}
363
+					);
364
+					add_filter(
365
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
366
+						function ($admin_page) use ($caf_admin_page)
367
+						{
368
+							return $caf_admin_page;
369
+						}
370
+					);
371
+					$extend = true;
372
+				}
373
+				//let's do the registered hooks
374
+				$extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
375
+				$hooks_ref      = array_merge($hooks_ref, $extended_hooks);
376
+			}
377
+		}
378
+		//the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
379
+		//first make sure we've got unique values
380
+		$hooks_ref = array_unique($hooks_ref);
381
+		//now let's loop and require!
382
+		foreach ($hooks_ref as $path) {
383
+			require_once($path);
384
+		}
385
+		//make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
386
+		global $ee_menu_slugs;
387
+		$ee_menu_slugs = $this->_menu_slugs;
388
+		//we need to loop again to run any early code
389
+		foreach ($installed_refs as $page => $path) {
390
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
391
+				$this->_installed_pages[$page]->do_initial_loads();
392
+			}
393
+		}
394
+		do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
395
+	}
396
+
397
+
398
+
399
+	/**
400
+	 * get_admin_page_object
401
+	 *
402
+	 * @param string $page_slug
403
+	 * @return EE_Admin_Page
404
+	 */
405
+	public function get_admin_page_object($page_slug = '')
406
+	{
407
+		if (isset($this->_installed_pages[$page_slug])) {
408
+			return $this->_installed_pages[$page_slug]->loaded_page_object();
409
+		}
410
+		return null;
411
+	}
412
+
413
+
414
+
415
+	/**
416
+	 * _get_classname_for_admin_page
417
+	 * generates an "Admin Page" class based on the directory  name
418
+	 *
419
+	 * @param $dir_name
420
+	 * @return string
421
+	 */
422
+	private function _get_classname_for_admin_page($dir_name = '')
423
+	{
424
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
425
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
426
+	}
427
+
428
+
429
+
430
+	/**
431
+	 * _get_classname_for_admin_init_page
432
+	 * generates an "Admin Page Init" class based on the directory  name
433
+	 *
434
+	 * @param $dir_name
435
+	 * @return string
436
+	 */
437
+	private function _get_classname_for_admin_init_page($dir_name = '')
438
+	{
439
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
440
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
441
+	}
442
+
443
+
444
+
445
+	/**
446
+	 * _load_admin_page
447
+	 * Loads and instantiates page_init object for a single EE_admin page.
448
+	 *
449
+	 * @param  string $page page_reference
450
+	 * @param string  $path
451
+	 * @throws EE_Error
452
+	 * @return object|bool  return page object if valid, bool false if not.
453
+	 */
454
+	private function _load_admin_page($page = '', $path = '')
455
+	{
456
+		$class_name = $this->_get_classname_for_admin_init_page($page);
457
+		EE_Registry::instance()->load_file($path, $class_name, 'core');
458
+		if (! class_exists($class_name)) {
459
+			$inner_error_msg = '<br />' . sprintf(
460
+					esc_html__(
461
+						'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
462
+						'event_espresso'
463
+					),
464
+					'<strong>' . $class_name . '</strong>'
465
+				);
466
+			$error_msg[]     = sprintf(
467
+				__('Something went wrong with loading the %s admin page.', 'event_espresso'),
468
+				$page
469
+			);
470
+			$error_msg[]     = $error_msg[0]
471
+							   . "\r\n"
472
+							   . sprintf(
473
+								   esc_html__(
474
+									   'There is no Init class in place for the %s admin page.',
475
+									   'event_espresso'
476
+								   ),
477
+								   $page
478
+							   )
479
+							   . $inner_error_msg;
480
+			throw new EE_Error(implode('||', $error_msg));
481
+		}
482
+		$a = new ReflectionClass($class_name);
483
+		return $a->newInstance();
484
+	}
485
+
486
+
487
+
488
+	/**
489
+	 * set_menus
490
+	 * This method sets up the menus for EE Admin Pages
491
+	 *
492
+	 * @access private
493
+	 * @return void
494
+	 */
495
+	public function set_menus()
496
+	{
497
+		//prep the menu pages (sort, group.)
498
+		$this->_prep_pages();
499
+		foreach ($this->_prepped_menu_maps as $menu_map) {
500
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
501
+				$menu_map->add_menu_page(false);
502
+			}
503
+		}
504
+	}
505
+
506
+
507
+	/**
508
+	 * set_network_menus
509
+	 * This method sets up the menus for network EE Admin Pages.
510
+	 * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
511
+	 * are only added to the menu map if they are intended for the admin menu
512
+	 *
513
+	 * @return void
514
+	 */
515
+	public function set_network_menus()
516
+	{
517
+		$this->_prep_pages();
518
+		foreach ($this->_prepped_menu_maps as $menu_map) {
519
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
520
+				$menu_map->add_menu_page(true);
521
+			}
522
+		}
523
+	}
524
+
525
+
526
+
527
+	/**
528
+	 * _prep_pages
529
+	 * sets the _prepped_menu_maps property
530
+	 *
531
+	 * @access private
532
+	 * @throws EE_Error
533
+	 * @return void
534
+	 */
535
+	private function _prep_pages()
536
+	{
537
+		$pages_array = array();
538
+		//rearrange _admin_menu_groups to be indexed by group slug.
539
+		$menu_groups = $this->_rearrange_menu_groups();
540
+		foreach ($this->_installed_pages as $page) {
541
+			if ($page instanceof EE_Admin_page_Init) {
542
+				$page_map = $page->get_menu_map();
543
+				//if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
544
+				if (is_array($page_map) || empty($page_map)) {
545
+					EE_Error::add_persistent_admin_notice(
546
+						'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
547
+						sprintf(
548
+							__(
549
+								'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
550
+								'event_espresso'
551
+							),
552
+							$page->label
553
+						)
554
+					);
555
+					continue;
556
+				}
557
+				//if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
558
+				if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
559
+					throw new EE_Error(
560
+						sprintf(
561
+							__(
562
+								'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
563
+								'event_espresso'
564
+							),
565
+							$page->label,
566
+							$page_map
567
+						)
568
+					);
569
+				}
570
+				//use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
571
+				if (empty($page_map->maintenance_mode_parent)
572
+					&& EE_Maintenance_Mode::instance()->level()
573
+					   == EE_Maintenance_Mode::level_2_complete_maintenance) {
574
+					continue;
575
+				}
576
+				//assign to group (remember $page_map has the admin page stored in it).
577
+				$pages_array[$page_map->menu_group][] = $page_map;
578
+			}
579
+		}
580
+		if (empty($pages_array)) {
581
+			throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
582
+		}
583
+		//let's sort the groups, make sure it's a valid group, add header (if to show).
584
+		foreach ($pages_array as $group => $menu_maps) {
585
+			//valid_group?
586
+			if (! array_key_exists($group, $menu_groups)) {
587
+				continue;
588
+			}
589
+			//sort pages.
590
+			usort($menu_maps, array($this, '_sort_menu_maps'));
591
+			//prepend header
592
+			array_unshift($menu_maps, $menu_groups[$group]);
593
+			//reset $pages_array with prepped data
594
+			$pages_array[$group] = $menu_maps;
595
+		}
596
+		//now let's setup the _prepped_menu_maps property
597
+		foreach ($menu_groups as $group => $group_objs) {
598
+			if (isset($pages_array[$group])) {
599
+				$this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
600
+			}
601
+		}/**/
602
+	}
603
+
604
+
605
+
606
+	/**
607
+	 * This method is the "workhorse" for detecting and setting up caffeinated functionality.
608
+	 * In this method there are three checks being done:
609
+	 * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
610
+	 * array) etc.  (new page sets are found in caffeinated/new/{page})
611
+	 * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
612
+	 * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
613
+	 * Extend_Events_Admin_Page extends Events_Admin_Page.
614
+	 * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
615
+	 * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
616
+	 * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
617
+	 * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
618
+	 * admin_pages)
619
+	 *
620
+	 * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
621
+	 *                              loaded.
622
+	 * @return array
623
+	 */
624
+	private function _set_caffeinated($installed_refs)
625
+	{
626
+
627
+		//first let's check if there IS a caffeinated folder. If there is not then lets get out.
628
+		if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
629
+			return $installed_refs;
630
+		}
631
+		$this->_define_caffeinated_constants();
632
+		$exclude = array('tickets');
633
+		//okay let's setup an "New" pages first (we'll return installed refs later)
634
+		$new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
635
+		if ($new_admin_screens) {
636
+			foreach ($new_admin_screens as $admin_screen) {
637
+				// files and anything in the exclude array need not apply
638
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
639
+					// these folders represent the different NEW EE admin pages
640
+					$installed_refs[basename($admin_screen)] = $admin_screen;
641
+					// set autoloaders for our admin page classes based on included path information
642
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
643
+					//					$this->_caf_autoloader[] = array(
644
+					//						'dir' => 'new',
645
+					//						'folder' => basename( $admin_screen )
646
+					//					);
647
+				}
648
+			}
649
+		}
650
+		//let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
651
+		$extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
652
+		if ($extends) {
653
+			foreach ($extends as $extend) {
654
+				if (is_dir($extend)) {
655
+					$extend_ref = basename($extend);
656
+					//now let's make sure there is a file that matches the expected format
657
+					$filename                                              = str_replace(
658
+						' ',
659
+						'_',
660
+						ucwords(
661
+							str_replace(
662
+								'_',
663
+								' ',
664
+								$extend_ref
665
+							)
666
+						)
667
+					);
668
+					$filename                                              = 'Extend_' . $filename . '_Admin_Page';
669
+					$this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
670
+						array('\\', '/'),
671
+						DS,
672
+						EE_CORE_CAF_ADMIN
673
+						. 'extend'
674
+						. DS
675
+						. $extend_ref
676
+						. DS
677
+						. $filename
678
+						. '.core.php'
679
+					);
680
+					$this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
681
+					// set autoloaders for our admin page classes based on included path information
682
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
683
+					//					$this->_caf_autoloader[] = array(
684
+					//						'dir' => 'extend',
685
+					//						'folder' => $extend_ref
686
+					//					);
687
+				}
688
+			}
689
+		}
690
+		//let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
691
+		$ee_admin_hooks = array();
692
+		$hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
693
+		if ($hooks) {
694
+			foreach ($hooks as $hook) {
695
+				if (is_readable($hook)) {
696
+					require_once $hook;
697
+					$classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
698
+					$classname = str_replace('.class.php', '', $classname);
699
+					if (class_exists($classname)) {
700
+						$a                = new ReflectionClass($classname);
701
+						$ee_admin_hooks[] = $a->newInstance();
702
+					}
703
+				}
704
+			}
705
+		}/**/
706
+		$ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
707
+		return $installed_refs;
708
+	}
709
+
710
+
711
+
712
+
713
+
714
+	/**
715
+	 * Initial autoloader registration
716
+	 * This just sets up the autoloader for the root admin files
717
+	 *
718
+	 * @param  string $className incoming classname to check for autoload
719
+	 * @return void
720
+	 */
721
+	//	public function init_autoloaders( $className ) {
722
+	//		$dir_ref = array(
723
+	//			EE_ADMIN => array('core', 'class')
724
+	//		);
725
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
726
+	//	}
727
+	/**
728
+	 * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
729
+	 * caffeinated folders.
730
+	 *
731
+	 * @access public
732
+	 * @param  string $className in coming classname being called
733
+	 * @return void
734
+	 */
735
+	//	public function caffeinated_autoloaders( $className ) {
736
+	//		//let's setup an array of paths to check (for each subsystem)
737
+	//		$dir_ref = array();
738
+	//		foreach ( $this->_caf_autoloader as $pathinfo) {
739
+	//			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
740
+	//		}
741
+	//
742
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
743
+	//	}
744
+	/**
745
+	 * Utility method for sorting the _menu_maps (callback for usort php function)
746
+	 *
747
+	 * @since  4.4.0
748
+	 * @param  EE_Admin_Page_Menu_Map $a menu_map object
749
+	 * @param  EE_Admin_Page_Menu_Map $b being compared to
750
+	 * @return int    sort order
751
+	 */
752
+	private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
753
+	{
754
+		if ($a->menu_order == $b->menu_order) {
755
+			return 0;
756
+		}
757
+		return ($a->menu_order < $b->menu_order) ? -1 : 1;
758
+	}
759
+
760
+
761
+
762
+	/**
763
+	 * _default_header_link
764
+	 * This is just a dummy method to use with header submenu items
765
+	 *
766
+	 * @return bool false
767
+	 */
768
+	public function _default_header_link()
769
+	{
770
+		return false;
771
+	}
772 772
 
773 773
 
774 774
 }
Please login to merge, or discard this patch.
Spacing   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (! defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -140,13 +140,13 @@  discard block
 block discarded – undo
140 140
      */
141 141
     private function _define_caffeinated_constants()
142 142
     {
143
-        if (! defined('EE_CORE_CAF_ADMIN')) {
144
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
145
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
146
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
147
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
148
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
149
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
143
+        if ( ! defined('EE_CORE_CAF_ADMIN')) {
144
+            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/');
145
+            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/');
146
+            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/');
147
+            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/');
148
+            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/');
149
+            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/');
150 150
         }
151 151
     }
152 152
 
@@ -259,7 +259,7 @@  discard block
 block discarded – undo
259 259
         //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
260 260
         usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
261 261
         foreach ($this->_admin_menu_groups as $group) {
262
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
262
+            if ( ! $group instanceof EE_Admin_Page_Menu_Group) {
263 263
                 throw new EE_Error(
264 264
                     sprintf(
265 265
                         __(
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
         $installed_refs = array();
291 291
         $exclude        = array('assets', 'templates');
292 292
         // grab everything in the  admin core directory
293
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
293
+        $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR);
294 294
         if ($admin_screens) {
295 295
             foreach ($admin_screens as $admin_screen) {
296 296
                 // files and anything in the exclude array need not apply
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
                 'There are no EE_Admin pages detected, it looks like EE did not install properly',
306 306
                 'event_espresso'
307 307
             );
308
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
308
+            $error_msg[] = $error_msg[0]."\r\n".sprintf(
309 309
                     __(
310 310
                         'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
311 311
                         'event_espresso'
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
         //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
318 318
         $installed_refs = $this->_set_caffeinated($installed_refs);
319 319
         //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
320
-        $installed_refs             = apply_filters(
320
+        $installed_refs = apply_filters(
321 321
             'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
322 322
             $installed_refs
323 323
         );
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
             $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
335 335
             // verify returned object
336 336
             if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
337
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
337
+                if ( ! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
338 338
                     continue;
339 339
                 }
340 340
                 //skip if in full maintenance mode and maintenance_mode_parent is set
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
                     );
364 364
                     add_filter(
365 365
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
366
-                        function ($admin_page) use ($caf_admin_page)
366
+                        function($admin_page) use ($caf_admin_page)
367 367
                         {
368 368
                             return $caf_admin_page;
369 369
                         }
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
     private function _get_classname_for_admin_page($dir_name = '')
423 423
     {
424 424
         $class_name = str_replace('_', ' ', strtolower($dir_name));
425
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
425
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
426 426
     }
427 427
 
428 428
 
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
     private function _get_classname_for_admin_init_page($dir_name = '')
438 438
     {
439 439
         $class_name = str_replace('_', ' ', strtolower($dir_name));
440
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
440
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init';
441 441
     }
442 442
 
443 443
 
@@ -455,19 +455,19 @@  discard block
 block discarded – undo
455 455
     {
456 456
         $class_name = $this->_get_classname_for_admin_init_page($page);
457 457
         EE_Registry::instance()->load_file($path, $class_name, 'core');
458
-        if (! class_exists($class_name)) {
459
-            $inner_error_msg = '<br />' . sprintf(
458
+        if ( ! class_exists($class_name)) {
459
+            $inner_error_msg = '<br />'.sprintf(
460 460
                     esc_html__(
461 461
                         'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
462 462
                         'event_espresso'
463 463
                     ),
464
-                    '<strong>' . $class_name . '</strong>'
464
+                    '<strong>'.$class_name.'</strong>'
465 465
                 );
466
-            $error_msg[]     = sprintf(
466
+            $error_msg[] = sprintf(
467 467
                 __('Something went wrong with loading the %s admin page.', 'event_espresso'),
468 468
                 $page
469 469
             );
470
-            $error_msg[]     = $error_msg[0]
470
+            $error_msg[] = $error_msg[0]
471 471
                                . "\r\n"
472 472
                                . sprintf(
473 473
                                    esc_html__(
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
                 //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
544 544
                 if (is_array($page_map) || empty($page_map)) {
545 545
                     EE_Error::add_persistent_admin_notice(
546
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
546
+                        'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION,
547 547
                         sprintf(
548 548
                             __(
549 549
                                 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
                     continue;
556 556
                 }
557 557
                 //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
558
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
558
+                if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) {
559 559
                     throw new EE_Error(
560 560
                         sprintf(
561 561
                             __(
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
         //let's sort the groups, make sure it's a valid group, add header (if to show).
584 584
         foreach ($pages_array as $group => $menu_maps) {
585 585
             //valid_group?
586
-            if (! array_key_exists($group, $menu_groups)) {
586
+            if ( ! array_key_exists($group, $menu_groups)) {
587 587
                 continue;
588 588
             }
589 589
             //sort pages.
@@ -625,13 +625,13 @@  discard block
 block discarded – undo
625 625
     {
626 626
 
627 627
         //first let's check if there IS a caffeinated folder. If there is not then lets get out.
628
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
628
+        if ( ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated'.DS.'admin') || (defined('EE_DECAF') && EE_DECAF)) {
629 629
             return $installed_refs;
630 630
         }
631 631
         $this->_define_caffeinated_constants();
632 632
         $exclude = array('tickets');
633 633
         //okay let's setup an "New" pages first (we'll return installed refs later)
634
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
634
+        $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR);
635 635
         if ($new_admin_screens) {
636 636
             foreach ($new_admin_screens as $admin_screen) {
637 637
                 // files and anything in the exclude array need not apply
@@ -648,13 +648,13 @@  discard block
 block discarded – undo
648 648
             }
649 649
         }
650 650
         //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
651
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
651
+        $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR);
652 652
         if ($extends) {
653 653
             foreach ($extends as $extend) {
654 654
                 if (is_dir($extend)) {
655 655
                     $extend_ref = basename($extend);
656 656
                     //now let's make sure there is a file that matches the expected format
657
-                    $filename                                              = str_replace(
657
+                    $filename = str_replace(
658 658
                         ' ',
659 659
                         '_',
660 660
                         ucwords(
@@ -665,7 +665,7 @@  discard block
 block discarded – undo
665 665
                             )
666 666
                         )
667 667
                     );
668
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
668
+                    $filename                                              = 'Extend_'.$filename.'_Admin_Page';
669 669
                     $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
670 670
                         array('\\', '/'),
671 671
                         DS,
@@ -689,12 +689,12 @@  discard block
 block discarded – undo
689 689
         }
690 690
         //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
691 691
         $ee_admin_hooks = array();
692
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
692
+        $hooks          = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php');
693 693
         if ($hooks) {
694 694
             foreach ($hooks as $hook) {
695 695
                 if (is_readable($hook)) {
696 696
                     require_once $hook;
697
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
697
+                    $classname = str_replace(EE_CORE_CAF_ADMIN.'hooks/', '', $hook);
698 698
                     $classname = str_replace('.class.php', '', $classname);
699 699
                     if (class_exists($classname)) {
700 700
                         $a                = new ReflectionClass($classname);
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -38,217 +38,217 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         *
70
-         * @return void
71
-         */
72
-        function espresso_minimum_php_version_error()
73
-        {
74
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 *
70
+		 * @return void
71
+		 */
72
+		function espresso_minimum_php_version_error()
73
+		{
74
+			?>
75 75
             <div class="error">
76 76
                 <p>
77 77
                     <?php
78
-                    printf(
79
-                        esc_html__(
80
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
-                            'event_espresso'
82
-                        ),
83
-                        EE_MIN_PHP_VER_REQUIRED,
84
-                        PHP_VERSION,
85
-                        '<br/>',
86
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
-                    );
88
-                    ?>
78
+					printf(
79
+						esc_html__(
80
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
+							'event_espresso'
82
+						),
83
+						EE_MIN_PHP_VER_REQUIRED,
84
+						PHP_VERSION,
85
+						'<br/>',
86
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
+					);
88
+					?>
89 89
                 </p>
90 90
             </div>
91 91
             <?php
92
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
93
-        }
92
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
93
+		}
94 94
 
95
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
-    } else {
97
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
-        /**
99
-         * espresso_version
100
-         * Returns the plugin version
101
-         *
102
-         * @return string
103
-         */
104
-        function espresso_version()
105
-        {
106
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.49.rc.002');
107
-        }
95
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
+	} else {
97
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
+		/**
99
+		 * espresso_version
100
+		 * Returns the plugin version
101
+		 *
102
+		 * @return string
103
+		 */
104
+		function espresso_version()
105
+		{
106
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.49.rc.002');
107
+		}
108 108
 
109
-        /**
110
-         * espresso_plugin_activation
111
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
-         */
113
-        function espresso_plugin_activation()
114
-        {
115
-            update_option('ee_espresso_activation', true);
116
-        }
109
+		/**
110
+		 * espresso_plugin_activation
111
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
+		 */
113
+		function espresso_plugin_activation()
114
+		{
115
+			update_option('ee_espresso_activation', true);
116
+		}
117 117
 
118
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
-        /**
120
-         *    espresso_load_error_handling
121
-         *    this function loads EE's class for handling exceptions and errors
122
-         */
123
-        function espresso_load_error_handling()
124
-        {
125
-            static $error_handling_loaded = false;
126
-            if ($error_handling_loaded) {
127
-                return;
128
-            }
129
-            // load debugging tools
130
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
-                require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
-                \EEH_Debug_Tools::instance();
133
-            }
134
-            // load error handling
135
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
-                require_once EE_CORE . 'EE_Error.core.php';
137
-            } else {
138
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
-            }
140
-            $error_handling_loaded = true;
141
-        }
118
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
+		/**
120
+		 *    espresso_load_error_handling
121
+		 *    this function loads EE's class for handling exceptions and errors
122
+		 */
123
+		function espresso_load_error_handling()
124
+		{
125
+			static $error_handling_loaded = false;
126
+			if ($error_handling_loaded) {
127
+				return;
128
+			}
129
+			// load debugging tools
130
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
+				require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
+				\EEH_Debug_Tools::instance();
133
+			}
134
+			// load error handling
135
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
+				require_once EE_CORE . 'EE_Error.core.php';
137
+			} else {
138
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
+			}
140
+			$error_handling_loaded = true;
141
+		}
142 142
 
143
-        /**
144
-         *    espresso_load_required
145
-         *    given a class name and path, this function will load that file or throw an exception
146
-         *
147
-         * @param    string $classname
148
-         * @param    string $full_path_to_file
149
-         * @throws    EE_Error
150
-         */
151
-        function espresso_load_required($classname, $full_path_to_file)
152
-        {
153
-            if (is_readable($full_path_to_file)) {
154
-                require_once $full_path_to_file;
155
-            } else {
156
-                throw new \EE_Error (
157
-                    sprintf(
158
-                        esc_html__(
159
-                            'The %s class file could not be located or is not readable due to file permissions.',
160
-                            'event_espresso'
161
-                        ),
162
-                        $classname
163
-                    )
164
-                );
165
-            }
166
-        }
143
+		/**
144
+		 *    espresso_load_required
145
+		 *    given a class name and path, this function will load that file or throw an exception
146
+		 *
147
+		 * @param    string $classname
148
+		 * @param    string $full_path_to_file
149
+		 * @throws    EE_Error
150
+		 */
151
+		function espresso_load_required($classname, $full_path_to_file)
152
+		{
153
+			if (is_readable($full_path_to_file)) {
154
+				require_once $full_path_to_file;
155
+			} else {
156
+				throw new \EE_Error (
157
+					sprintf(
158
+						esc_html__(
159
+							'The %s class file could not be located or is not readable due to file permissions.',
160
+							'event_espresso'
161
+						),
162
+						$classname
163
+					)
164
+				);
165
+			}
166
+		}
167 167
 
168
-        /**
169
-         * @since 4.9.27
170
-         * @throws \EE_Error
171
-         * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
-         * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
-         * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
-         * @throws \EventEspresso\core\exceptions\InvalidClassException
175
-         * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
-         * @throws \OutOfBoundsException
179
-         */
180
-        function bootstrap_espresso()
181
-        {
182
-            require_once __DIR__ . '/core/espresso_definitions.php';
183
-            try {
184
-                espresso_load_error_handling();
185
-                espresso_load_required(
186
-                    'EEH_Base',
187
-                    EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
-                );
189
-                espresso_load_required(
190
-                    'EEH_File',
191
-                    EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
-                );
193
-                espresso_load_required(
194
-                    'EEH_File',
195
-                    EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
-                );
197
-                espresso_load_required(
198
-                    'EEH_Array',
199
-                    EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
-                );
201
-                // instantiate and configure PSR4 autoloader
202
-                espresso_load_required(
203
-                    'Psr4Autoloader',
204
-                    EE_CORE . 'Psr4Autoloader.php'
205
-                );
206
-                espresso_load_required(
207
-                    'EE_Psr4AutoloaderInit',
208
-                    EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
-                );
210
-                $AutoloaderInit = new EE_Psr4AutoloaderInit();
211
-                $AutoloaderInit->initializeAutoloader();
212
-                espresso_load_required(
213
-                    'EE_Request',
214
-                    EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
-                );
216
-                espresso_load_required(
217
-                    'EE_Response',
218
-                    EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
-                );
220
-                espresso_load_required(
221
-                    'EE_Bootstrap',
222
-                    EE_CORE . 'EE_Bootstrap.core.php'
223
-                );
224
-                // bootstrap EE and the request stack
225
-                new EE_Bootstrap(
226
-                    new EE_Request($_GET, $_POST, $_COOKIE),
227
-                    new EE_Response()
228
-                );
229
-            } catch (Exception $e) {
230
-                require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
-                new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
-            }
233
-        }
234
-        bootstrap_espresso();
235
-    }
168
+		/**
169
+		 * @since 4.9.27
170
+		 * @throws \EE_Error
171
+		 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
+		 * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
+		 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
+		 * @throws \EventEspresso\core\exceptions\InvalidClassException
175
+		 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
+		 * @throws \OutOfBoundsException
179
+		 */
180
+		function bootstrap_espresso()
181
+		{
182
+			require_once __DIR__ . '/core/espresso_definitions.php';
183
+			try {
184
+				espresso_load_error_handling();
185
+				espresso_load_required(
186
+					'EEH_Base',
187
+					EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
+				);
189
+				espresso_load_required(
190
+					'EEH_File',
191
+					EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
+				);
193
+				espresso_load_required(
194
+					'EEH_File',
195
+					EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
+				);
197
+				espresso_load_required(
198
+					'EEH_Array',
199
+					EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
+				);
201
+				// instantiate and configure PSR4 autoloader
202
+				espresso_load_required(
203
+					'Psr4Autoloader',
204
+					EE_CORE . 'Psr4Autoloader.php'
205
+				);
206
+				espresso_load_required(
207
+					'EE_Psr4AutoloaderInit',
208
+					EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
+				);
210
+				$AutoloaderInit = new EE_Psr4AutoloaderInit();
211
+				$AutoloaderInit->initializeAutoloader();
212
+				espresso_load_required(
213
+					'EE_Request',
214
+					EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
+				);
216
+				espresso_load_required(
217
+					'EE_Response',
218
+					EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
+				);
220
+				espresso_load_required(
221
+					'EE_Bootstrap',
222
+					EE_CORE . 'EE_Bootstrap.core.php'
223
+				);
224
+				// bootstrap EE and the request stack
225
+				new EE_Bootstrap(
226
+					new EE_Request($_GET, $_POST, $_COOKIE),
227
+					new EE_Response()
228
+				);
229
+			} catch (Exception $e) {
230
+				require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
+				new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
+			}
233
+		}
234
+		bootstrap_espresso();
235
+	}
236 236
 }
237 237
 if (! function_exists('espresso_deactivate_plugin')) {
238
-    /**
239
-     *    deactivate_plugin
240
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
-     *
242
-     * @access public
243
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
-     * @return    void
245
-     */
246
-    function espresso_deactivate_plugin($plugin_basename = '')
247
-    {
248
-        if (! function_exists('deactivate_plugins')) {
249
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
-        }
251
-        unset($_GET['activate'], $_REQUEST['activate']);
252
-        deactivate_plugins($plugin_basename);
253
-    }
238
+	/**
239
+	 *    deactivate_plugin
240
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
+	 *
242
+	 * @access public
243
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
+	 * @return    void
245
+	 */
246
+	function espresso_deactivate_plugin($plugin_basename = '')
247
+	{
248
+		if (! function_exists('deactivate_plugins')) {
249
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
+		}
251
+		unset($_GET['activate'], $_REQUEST['activate']);
252
+		deactivate_plugins($plugin_basename);
253
+	}
254 254
 }
Please login to merge, or discard this patch.