Completed
Branch EDTR/apollo-react-client (410ac8)
by
unknown
10:21 queued 39s
created
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1388 added lines, -1388 removed lines patch added patch discarded remove patch
@@ -17,1392 +17,1392 @@
 block discarded – undo
17 17
 class Extend_Events_Admin_Page extends Events_Admin_Page
18 18
 {
19 19
 
20
-    /**
21
-     * @var AdvancedEditorAdminFormSection
22
-     */
23
-    protected $advanced_editor_admin_form;
24
-
25
-    /**
26
-     * @var AdvancedEditorEntityData
27
-     */
28
-    protected $advanced_editor_data;
29
-
30
-
31
-    /**
32
-     * Extend_Events_Admin_Page constructor.
33
-     *
34
-     * @param bool $routing
35
-     * @throws EE_Error
36
-     * @throws InvalidArgumentException
37
-     * @throws InvalidDataTypeException
38
-     * @throws InvalidInterfaceException
39
-     * @throws ReflectionException
40
-     */
41
-    public function __construct($routing = true)
42
-    {
43
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
44
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
45
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
46
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
47
-        }
48
-        parent::__construct($routing);
49
-    }
50
-
51
-
52
-    /**
53
-     * Sets routes.
54
-     *
55
-     * @throws EE_Error
56
-     * @throws InvalidArgumentException
57
-     * @throws InvalidDataTypeException
58
-     * @throws InvalidInterfaceException
59
-     * @since $VID:$
60
-     */
61
-    protected function _extend_page_config()
62
-    {
63
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
64
-        // is there a evt_id in the request?
65
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
66
-            ? $this->_req_data['EVT_ID']
67
-            : 0;
68
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
69
-        // tkt_id?
70
-        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
71
-            ? $this->_req_data['TKT_ID']
72
-            : 0;
73
-        $new_page_routes = array(
74
-            'duplicate_event'          => array(
75
-                'func'       => '_duplicate_event',
76
-                'capability' => 'ee_edit_event',
77
-                'obj_id'     => $evt_id,
78
-                'noheader'   => true,
79
-            ),
80
-            'ticket_list_table'        => array(
81
-                'func'       => '_tickets_overview_list_table',
82
-                'capability' => 'ee_read_default_tickets',
83
-            ),
84
-            'trash_ticket'             => array(
85
-                'func'       => '_trash_or_restore_ticket',
86
-                'capability' => 'ee_delete_default_ticket',
87
-                'obj_id'     => $tkt_id,
88
-                'noheader'   => true,
89
-                'args'       => array('trash' => true),
90
-            ),
91
-            'trash_tickets'            => array(
92
-                'func'       => '_trash_or_restore_ticket',
93
-                'capability' => 'ee_delete_default_tickets',
94
-                'noheader'   => true,
95
-                'args'       => array('trash' => true),
96
-            ),
97
-            'restore_ticket'           => array(
98
-                'func'       => '_trash_or_restore_ticket',
99
-                'capability' => 'ee_delete_default_ticket',
100
-                'obj_id'     => $tkt_id,
101
-                'noheader'   => true,
102
-            ),
103
-            'restore_tickets'          => array(
104
-                'func'       => '_trash_or_restore_ticket',
105
-                'capability' => 'ee_delete_default_tickets',
106
-                'noheader'   => true,
107
-            ),
108
-            'delete_ticket'            => array(
109
-                'func'       => '_delete_ticket',
110
-                'capability' => 'ee_delete_default_ticket',
111
-                'obj_id'     => $tkt_id,
112
-                'noheader'   => true,
113
-            ),
114
-            'delete_tickets'           => array(
115
-                'func'       => '_delete_ticket',
116
-                'capability' => 'ee_delete_default_tickets',
117
-                'noheader'   => true,
118
-            ),
119
-            'import_page'              => array(
120
-                'func'       => '_import_page',
121
-                'capability' => 'import',
122
-            ),
123
-            'import'                   => array(
124
-                'func'       => '_import_events',
125
-                'capability' => 'import',
126
-                'noheader'   => true,
127
-            ),
128
-            'import_events'            => array(
129
-                'func'       => '_import_events',
130
-                'capability' => 'import',
131
-                'noheader'   => true,
132
-            ),
133
-            'export_events'            => array(
134
-                'func'       => '_events_export',
135
-                'capability' => 'export',
136
-                'noheader'   => true,
137
-            ),
138
-            'export_categories'        => array(
139
-                'func'       => '_categories_export',
140
-                'capability' => 'export',
141
-                'noheader'   => true,
142
-            ),
143
-            'sample_export_file'       => array(
144
-                'func'       => '_sample_export_file',
145
-                'capability' => 'export',
146
-                'noheader'   => true,
147
-            ),
148
-            'update_template_settings' => array(
149
-                'func'       => '_update_template_settings',
150
-                'capability' => 'manage_options',
151
-                'noheader'   => true,
152
-            ),
153
-        );
154
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
155
-        // partial route/config override
156
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
157
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
158
-        $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
159
-        $this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
160
-        $this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
161
-        $this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
162
-        // add tickets tab but only if there are more than one default ticket!
163
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
164
-            array(array('TKT_is_default' => 1)),
165
-            'TKT_ID',
166
-            true
167
-        );
168
-        if ($tkt_count > 1) {
169
-            $new_page_config = array(
170
-                'ticket_list_table' => array(
171
-                    'nav'           => array(
172
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
173
-                        'order' => 60,
174
-                    ),
175
-                    'list_table'    => 'Tickets_List_Table',
176
-                    'require_nonce' => false,
177
-                ),
178
-            );
179
-        }
180
-        // template settings
181
-        $new_page_config['template_settings'] = array(
182
-            'nav'           => array(
183
-                'label' => esc_html__('Templates', 'event_espresso'),
184
-                'order' => 30,
185
-            ),
186
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
187
-            'help_tabs'     => array(
188
-                'general_settings_templates_help_tab' => array(
189
-                    'title'    => esc_html__('Templates', 'event_espresso'),
190
-                    'filename' => 'general_settings_templates',
191
-                ),
192
-            ),
193
-            'help_tour'     => array('Templates_Help_Tour'),
194
-            'require_nonce' => false,
195
-        );
196
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
197
-        // add filters and actions
198
-        // modifying _views
199
-        add_filter(
200
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
201
-            array($this, 'add_additional_datetime_button'),
202
-            10,
203
-            2
204
-        );
205
-        add_filter(
206
-            'FHEE_event_datetime_metabox_clone_button_template',
207
-            array($this, 'add_datetime_clone_button'),
208
-            10,
209
-            2
210
-        );
211
-        add_filter(
212
-            'FHEE_event_datetime_metabox_timezones_template',
213
-            array($this, 'datetime_timezones_template'),
214
-            10,
215
-            2
216
-        );
217
-        // filters for event list table
218
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
219
-        add_filter(
220
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
221
-            array($this, 'extra_list_table_actions'),
222
-            10,
223
-            2
224
-        );
225
-        // legend item
226
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
227
-        add_action('admin_init', array($this, 'admin_init'));
228
-        // setup Advanced Editor ???
229
-        if (isset($this->_req_data['action'])
230
-            && (
231
-                $this->_req_data['action'] === 'default_event_settings'
232
-                || $this->_req_data['action'] === 'update_default_event_settings'
233
-            )
234
-        ) {
235
-            $this->advanced_editor_admin_form = $this->loader->getShared(
236
-                'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection'
237
-            );
238
-        }
239
-        $admin_config = $this->loader->getShared('EE_Admin_Config');
240
-        if (isset($this->_req_data['action'])
241
-            && ($this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
242
-            && $admin_config instanceof EE_Admin_Config && $admin_config->useAdvancedEditor()
243
-        ) {
244
-            $this->advanced_editor_data = $this->loader->getShared(
245
-                'EventEspresso\core\domain\services\admin\events\editor\AdvancedEditorEntityData',
246
-                [$this->_cpt_model_obj]
247
-            );
248
-        }
249
-    }
250
-
251
-
252
-    /**
253
-     * admin_init
254
-     */
255
-    public function admin_init()
256
-    {
257
-        EE_Registry::$i18n_js_strings = array_merge(
258
-            EE_Registry::$i18n_js_strings,
259
-            array(
260
-                'image_confirm'          => esc_html__(
261
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
262
-                    'event_espresso'
263
-                ),
264
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
265
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
266
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
267
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
268
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
269
-            )
270
-        );
271
-    }
272
-
273
-
274
-    /**
275
-     * Add per page screen options to the default ticket list table view.
276
-     *
277
-     * @throws InvalidArgumentException
278
-     * @throws InvalidDataTypeException
279
-     * @throws InvalidInterfaceException
280
-     */
281
-    protected function _add_screen_options_ticket_list_table()
282
-    {
283
-        $this->_per_page_screen_option();
284
-    }
285
-
286
-
287
-    /**
288
-     * @param string $return
289
-     * @param int    $id
290
-     * @param string $new_title
291
-     * @param string $new_slug
292
-     * @return string
293
-     */
294
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
295
-    {
296
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
297
-        // make sure this is only when editing
298
-        if (! empty($id)) {
299
-            $href = EE_Admin_Page::add_query_args_and_nonce(
300
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
301
-                $this->_admin_base_url
302
-            );
303
-            $title = esc_attr__('Duplicate Event', 'event_espresso');
304
-            $return .= '<a href="'
305
-                       . $href
306
-                       . '" title="'
307
-                       . $title
308
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
309
-                       . $title
310
-                       . '</a>';
311
-        }
312
-        return $return;
313
-    }
314
-
315
-
316
-    /**
317
-     * Set the list table views for the default ticket list table view.
318
-     */
319
-    public function _set_list_table_views_ticket_list_table()
320
-    {
321
-        $this->_views = array(
322
-            'all'     => array(
323
-                'slug'        => 'all',
324
-                'label'       => esc_html__('All', 'event_espresso'),
325
-                'count'       => 0,
326
-                'bulk_action' => array(
327
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
328
-                ),
329
-            ),
330
-            'trashed' => array(
331
-                'slug'        => 'trashed',
332
-                'label'       => esc_html__('Trash', 'event_espresso'),
333
-                'count'       => 0,
334
-                'bulk_action' => array(
335
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
336
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
337
-                ),
338
-            ),
339
-        );
340
-    }
341
-
342
-
343
-    /**
344
-     * Enqueue scripts and styles for the event editor.
345
-     */
346
-    public function load_scripts_styles_edit()
347
-    {
348
-        wp_register_script(
349
-            'ee-event-editor-heartbeat',
350
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
351
-            array('ee_admin_js', 'heartbeat'),
352
-            EVENT_ESPRESSO_VERSION,
353
-            true
354
-        );
355
-        wp_enqueue_script('ee-accounting');
356
-        // styles
357
-        wp_enqueue_style('espresso-ui-theme');
358
-        wp_enqueue_script('event_editor_js');
359
-        wp_enqueue_script('ee-event-editor-heartbeat');
360
-    }
361
-
362
-
363
-    /**
364
-     * Returns template for the additional datetime.
365
-     *
366
-     * @param $template
367
-     * @param $template_args
368
-     * @return mixed
369
-     * @throws DomainException
370
-     */
371
-    public function add_additional_datetime_button($template, $template_args)
372
-    {
373
-        return EEH_Template::display_template(
374
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
375
-            $template_args,
376
-            true
377
-        );
378
-    }
379
-
380
-
381
-    /**
382
-     * Returns the template for cloning a datetime.
383
-     *
384
-     * @param $template
385
-     * @param $template_args
386
-     * @return mixed
387
-     * @throws DomainException
388
-     */
389
-    public function add_datetime_clone_button($template, $template_args)
390
-    {
391
-        return EEH_Template::display_template(
392
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
393
-            $template_args,
394
-            true
395
-        );
396
-    }
397
-
398
-
399
-    /**
400
-     * Returns the template for datetime timezones.
401
-     *
402
-     * @param $template
403
-     * @param $template_args
404
-     * @return mixed
405
-     * @throws DomainException
406
-     */
407
-    public function datetime_timezones_template($template, $template_args)
408
-    {
409
-        return EEH_Template::display_template(
410
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
411
-            $template_args,
412
-            true
413
-        );
414
-    }
415
-
416
-
417
-    /**
418
-     * Sets the views for the default list table view.
419
-     */
420
-    protected function _set_list_table_views_default()
421
-    {
422
-        parent::_set_list_table_views_default();
423
-        $new_views = array(
424
-            'today' => array(
425
-                'slug'        => 'today',
426
-                'label'       => esc_html__('Today', 'event_espresso'),
427
-                'count'       => $this->total_events_today(),
428
-                'bulk_action' => array(
429
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
430
-                ),
431
-            ),
432
-            'month' => array(
433
-                'slug'        => 'month',
434
-                'label'       => esc_html__('This Month', 'event_espresso'),
435
-                'count'       => $this->total_events_this_month(),
436
-                'bulk_action' => array(
437
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
438
-                ),
439
-            ),
440
-        );
441
-        $this->_views = array_merge($this->_views, $new_views);
442
-    }
443
-
444
-
445
-    /**
446
-     * Returns the extra action links for the default list table view.
447
-     *
448
-     * @param array    $action_links
449
-     * @param EE_Event $event
450
-     * @return array
451
-     * @throws EE_Error
452
-     * @throws InvalidArgumentException
453
-     * @throws InvalidDataTypeException
454
-     * @throws InvalidInterfaceException
455
-     * @throws ReflectionException
456
-     */
457
-    public function extra_list_table_actions(array $action_links, EE_Event $event)
458
-    {
459
-        if (EE_Registry::instance()->CAP->current_user_can(
460
-            'ee_read_registrations',
461
-            'espresso_registrations_reports',
462
-            $event->ID()
463
-        )
464
-        ) {
465
-            $reports_query_args = array(
466
-                'action' => 'reports',
467
-                'EVT_ID' => $event->ID(),
468
-            );
469
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
470
-            $action_links[] = '<a href="'
471
-                              . $reports_link
472
-                              . '" title="'
473
-                              . esc_attr__('View Report', 'event_espresso')
474
-                              . '"><div class="dashicons dashicons-chart-bar"></div></a>'
475
-                              . "\n\t";
476
-        }
477
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
478
-            EE_Registry::instance()->load_helper('MSG_Template');
479
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
480
-                'see_notifications_for',
481
-                null,
482
-                array('EVT_ID' => $event->ID())
483
-            );
484
-        }
485
-        return $action_links;
486
-    }
487
-
488
-
489
-    /**
490
-     * @param $items
491
-     * @return mixed
492
-     */
493
-    public function additional_legend_items($items)
494
-    {
495
-        if (EE_Registry::instance()->CAP->current_user_can(
496
-            'ee_read_registrations',
497
-            'espresso_registrations_reports'
498
-        )
499
-        ) {
500
-            $items['reports'] = array(
501
-                'class' => 'dashicons dashicons-chart-bar',
502
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
503
-            );
504
-        }
505
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
506
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
507
-            // $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
508
-            // (can only use numeric offsets when treating strings as arrays)
509
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
510
-                $items['view_related_messages'] = array(
511
-                    'class' => $related_for_icon['css_class'],
512
-                    'desc'  => $related_for_icon['label'],
513
-                );
514
-            }
515
-        }
516
-        return $items;
517
-    }
518
-
519
-
520
-    /**
521
-     * This is the callback method for the duplicate event route
522
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
523
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
524
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
525
-     * After duplication the redirect is to the new event edit page.
526
-     *
527
-     * @return void
528
-     * @throws EE_Error If EE_Event is not available with given ID
529
-     * @throws InvalidArgumentException
530
-     * @throws InvalidDataTypeException
531
-     * @throws InvalidInterfaceException
532
-     * @throws ReflectionException
533
-     * @access protected
534
-     */
535
-    protected function _duplicate_event()
536
-    {
537
-        // first make sure the ID for the event is in the request.
538
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
539
-        if (! isset($this->_req_data['EVT_ID'])) {
540
-            EE_Error::add_error(
541
-                esc_html__(
542
-                    'In order to duplicate an event an Event ID is required.  None was given.',
543
-                    'event_espresso'
544
-                ),
545
-                __FILE__,
546
-                __FUNCTION__,
547
-                __LINE__
548
-            );
549
-            $this->_redirect_after_action(false, '', '', array(), true);
550
-            return;
551
-        }
552
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
553
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
554
-        if (! $orig_event instanceof EE_Event) {
555
-            throw new EE_Error(
556
-                sprintf(
557
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
558
-                    $this->_req_data['EVT_ID']
559
-                )
560
-            );
561
-        }
562
-        // k now let's clone the $orig_event before getting relations
563
-        $new_event = clone $orig_event;
564
-        // original datetimes
565
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
566
-        // other original relations
567
-        $orig_ven = $orig_event->get_many_related('Venue');
568
-        // reset the ID and modify other details to make it clear this is a dupe
569
-        $new_event->set('EVT_ID', 0);
570
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
571
-        $new_event->set('EVT_name', $new_name);
572
-        $new_event->set(
573
-            'EVT_slug',
574
-            wp_unique_post_slug(
575
-                sanitize_title($orig_event->name()),
576
-                0,
577
-                'publish',
578
-                'espresso_events',
579
-                0
580
-            )
581
-        );
582
-        $new_event->set('status', 'draft');
583
-        // duplicate discussion settings
584
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
585
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
586
-        // save the new event
587
-        $new_event->save();
588
-        // venues
589
-        foreach ($orig_ven as $ven) {
590
-            $new_event->_add_relation_to($ven, 'Venue');
591
-        }
592
-        $new_event->save();
593
-        // now we need to get the question group relations and handle that
594
-        // first primary question groups
595
-        $orig_primary_qgs = $orig_event->get_many_related(
596
-            'Question_Group',
597
-            [['Event_Question_Group.EQG_primary' => true]]
598
-        );
599
-        if (! empty($orig_primary_qgs)) {
600
-            foreach ($orig_primary_qgs as $id => $obj) {
601
-                if ($obj instanceof EE_Question_Group) {
602
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
603
-                }
604
-            }
605
-        }
606
-        // next additional attendee question groups
607
-        $orig_additional_qgs = $orig_event->get_many_related(
608
-            'Question_Group',
609
-            [['Event_Question_Group.EQG_additional' => true]]
610
-        );
611
-        if (! empty($orig_additional_qgs)) {
612
-            foreach ($orig_additional_qgs as $id => $obj) {
613
-                if ($obj instanceof EE_Question_Group) {
614
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
615
-                }
616
-            }
617
-        }
618
-
619
-        $new_event->save();
620
-
621
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
622
-        $cloned_tickets = array();
623
-        foreach ($orig_datetimes as $orig_dtt) {
624
-            if (! $orig_dtt instanceof EE_Datetime) {
625
-                continue;
626
-            }
627
-            $new_dtt = clone $orig_dtt;
628
-            $orig_tkts = $orig_dtt->tickets();
629
-            // save new dtt then add to event
630
-            $new_dtt->set('DTT_ID', 0);
631
-            $new_dtt->set('DTT_sold', 0);
632
-            $new_dtt->set_reserved(0);
633
-            $new_dtt->save();
634
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
635
-            $new_event->save();
636
-            // now let's get the ticket relations setup.
637
-            foreach ((array) $orig_tkts as $orig_tkt) {
638
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
639
-                if (! $orig_tkt instanceof EE_Ticket) {
640
-                    continue;
641
-                }
642
-                // is this ticket archived?  If it is then let's skip
643
-                if ($orig_tkt->get('TKT_deleted')) {
644
-                    continue;
645
-                }
646
-                // does this original ticket already exist in the clone_tickets cache?
647
-                //  If so we'll just use the new ticket from it.
648
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
649
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
650
-                } else {
651
-                    $new_tkt = clone $orig_tkt;
652
-                    // get relations on the $orig_tkt that we need to setup.
653
-                    $orig_prices = $orig_tkt->prices();
654
-                    $new_tkt->set('TKT_ID', 0);
655
-                    $new_tkt->set('TKT_sold', 0);
656
-                    $new_tkt->set('TKT_reserved', 0);
657
-                    $new_tkt->save(); // make sure new ticket has ID.
658
-                    // price relations on new ticket need to be setup.
659
-                    foreach ($orig_prices as $orig_price) {
660
-                        $new_price = clone $orig_price;
661
-                        $new_price->set('PRC_ID', 0);
662
-                        $new_price->save();
663
-                        $new_tkt->_add_relation_to($new_price, 'Price');
664
-                        $new_tkt->save();
665
-                    }
666
-
667
-                    do_action(
668
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
669
-                        $orig_tkt,
670
-                        $new_tkt,
671
-                        $orig_prices,
672
-                        $orig_event,
673
-                        $orig_dtt,
674
-                        $new_dtt
675
-                    );
676
-                }
677
-                // k now we can add the new ticket as a relation to the new datetime
678
-                // and make sure its added to our cached $cloned_tickets array
679
-                // for use with later datetimes that have the same ticket.
680
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
681
-                $new_dtt->save();
682
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
683
-            }
684
-        }
685
-        // clone taxonomy information
686
-        $taxonomies_to_clone_with = apply_filters(
687
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
688
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
689
-        );
690
-        // get terms for original event (notice)
691
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
692
-        // loop through terms and add them to new event.
693
-        foreach ($orig_terms as $term) {
694
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
695
-        }
696
-
697
-        // duplicate other core WP_Post items for this event.
698
-        // post thumbnail (feature image).
699
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
700
-        if ($feature_image_id) {
701
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
702
-        }
703
-
704
-        // duplicate page_template setting
705
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
706
-        if ($page_template) {
707
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
708
-        }
709
-
710
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
711
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
712
-        if ($new_event->ID()) {
713
-            $redirect_args = array(
714
-                'post'   => $new_event->ID(),
715
-                'action' => 'edit',
716
-            );
717
-            EE_Error::add_success(
718
-                esc_html__(
719
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
720
-                    'event_espresso'
721
-                )
722
-            );
723
-        } else {
724
-            $redirect_args = array(
725
-                'action' => 'default',
726
-            );
727
-            EE_Error::add_error(
728
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
729
-                __FILE__,
730
-                __FUNCTION__,
731
-                __LINE__
732
-            );
733
-        }
734
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
735
-    }
736
-
737
-
738
-    /**
739
-     * Generates output for the import page.
740
-     *
741
-     * @throws DomainException
742
-     * @throws EE_Error
743
-     * @throws InvalidArgumentException
744
-     * @throws InvalidDataTypeException
745
-     * @throws InvalidInterfaceException
746
-     */
747
-    protected function _import_page()
748
-    {
749
-        $title = esc_html__('Import', 'event_espresso');
750
-        $intro = esc_html__(
751
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
752
-            'event_espresso'
753
-        );
754
-        $form_url = EVENTS_ADMIN_URL;
755
-        $action = 'import_events';
756
-        $type = 'csv';
757
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
758
-            $title,
759
-            $intro,
760
-            $form_url,
761
-            $action,
762
-            $type
763
-        );
764
-        $this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
765
-            array('action' => 'sample_export_file'),
766
-            $this->_admin_base_url
767
-        );
768
-        $content = EEH_Template::display_template(
769
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
770
-            $this->_template_args,
771
-            true
772
-        );
773
-        $this->_template_args['admin_page_content'] = $content;
774
-        $this->display_admin_page_with_sidebar();
775
-    }
776
-
777
-
778
-    /**
779
-     * _import_events
780
-     * This handles displaying the screen and running imports for importing events.
781
-     *
782
-     * @return void
783
-     * @throws EE_Error
784
-     * @throws InvalidArgumentException
785
-     * @throws InvalidDataTypeException
786
-     * @throws InvalidInterfaceException
787
-     */
788
-    protected function _import_events()
789
-    {
790
-        require_once(EE_CLASSES . 'EE_Import.class.php');
791
-        $success = EE_Import::instance()->import();
792
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
793
-    }
794
-
795
-
796
-    /**
797
-     * _events_export
798
-     * Will export all (or just the given event) to a Excel compatible file.
799
-     *
800
-     * @access protected
801
-     * @return void
802
-     */
803
-    protected function _events_export()
804
-    {
805
-        if (isset($this->_req_data['EVT_ID'])) {
806
-            $event_ids = $this->_req_data['EVT_ID'];
807
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
808
-            $event_ids = $this->_req_data['EVT_IDs'];
809
-        } else {
810
-            $event_ids = null;
811
-        }
812
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
813
-        $new_request_args = array(
814
-            'export' => 'report',
815
-            'action' => 'all_event_data',
816
-            'EVT_ID' => $event_ids,
817
-        );
818
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
819
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
820
-            require_once(EE_CLASSES . 'EE_Export.class.php');
821
-            $EE_Export = EE_Export::instance($this->_req_data);
822
-            $EE_Export->export();
823
-        }
824
-    }
825
-
826
-
827
-    /**
828
-     * handle category exports()
829
-     *
830
-     * @return void
831
-     */
832
-    protected function _categories_export()
833
-    {
834
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
835
-        $new_request_args = array(
836
-            'export'       => 'report',
837
-            'action'       => 'categories',
838
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
839
-        );
840
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
841
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
842
-            require_once(EE_CLASSES . 'EE_Export.class.php');
843
-            $EE_Export = EE_Export::instance($this->_req_data);
844
-            $EE_Export->export();
845
-        }
846
-    }
847
-
848
-
849
-    /**
850
-     * Creates a sample CSV file for importing
851
-     */
852
-    protected function _sample_export_file()
853
-    {
854
-        // require_once(EE_CLASSES . 'EE_Export.class.php');
855
-        EE_Export::instance()->export_sample();
856
-    }
857
-
858
-
859
-    /*************        Template Settings        *************/
860
-    /**
861
-     * Generates template settings page output
862
-     *
863
-     * @throws DomainException
864
-     * @throws EE_Error
865
-     * @throws InvalidArgumentException
866
-     * @throws InvalidDataTypeException
867
-     * @throws InvalidInterfaceException
868
-     */
869
-    protected function _template_settings()
870
-    {
871
-        $this->_template_args['values'] = $this->_yes_no_values;
872
-        /**
873
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
874
-         * from General_Settings_Admin_Page to here.
875
-         */
876
-        $this->_template_args = apply_filters(
877
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
878
-            $this->_template_args
879
-        );
880
-        $this->_set_add_edit_form_tags('update_template_settings');
881
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
882
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
883
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
884
-            $this->_template_args,
885
-            true
886
-        );
887
-        $this->display_admin_page_with_sidebar();
888
-    }
889
-
890
-
891
-    /**
892
-     * Handler for updating template settings.
893
-     *
894
-     * @throws EE_Error
895
-     * @throws InvalidArgumentException
896
-     * @throws InvalidDataTypeException
897
-     * @throws InvalidInterfaceException
898
-     */
899
-    protected function _update_template_settings()
900
-    {
901
-        /**
902
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
903
-         * from General_Settings_Admin_Page to here.
904
-         */
905
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
906
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
907
-            EE_Registry::instance()->CFG->template_settings,
908
-            $this->_req_data
909
-        );
910
-        // update custom post type slugs and detect if we need to flush rewrite rules
911
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
912
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
913
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
914
-            : EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
915
-        $what = 'Template Settings';
916
-        $success = $this->_update_espresso_configuration(
917
-            $what,
918
-            EE_Registry::instance()->CFG->template_settings,
919
-            __FILE__,
920
-            __FUNCTION__,
921
-            __LINE__
922
-        );
923
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
924
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
925
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
926
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
927
-            );
928
-            $rewrite_rules->flush();
929
-        }
930
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
931
-    }
932
-
933
-
934
-    /**
935
-     * _premium_event_editor_meta_boxes
936
-     * add all metaboxes related to the event_editor
937
-     *
938
-     * @access protected
939
-     * @return void
940
-     * @throws EE_Error
941
-     * @throws InvalidArgumentException
942
-     * @throws InvalidDataTypeException
943
-     * @throws InvalidInterfaceException
944
-     * @throws ReflectionException
945
-     */
946
-    protected function _premium_event_editor_meta_boxes()
947
-    {
948
-        $this->verify_cpt_object();
949
-        add_meta_box(
950
-            'espresso_event_editor_event_options',
951
-            esc_html__('Event Registration Options', 'event_espresso'),
952
-            array($this, 'registration_options_meta_box'),
953
-            $this->page_slug,
954
-            'side',
955
-            'core'
956
-        );
957
-    }
958
-
959
-
960
-    /**
961
-     * override caf metabox
962
-     *
963
-     * @return void
964
-     * @throws DomainException
965
-     * @throws EE_Error
966
-     */
967
-    public function registration_options_meta_box()
968
-    {
969
-        $yes_no_values = array(
970
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
971
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
972
-        );
973
-        $default_reg_status_values = EEM_Registration::reg_status_array(
974
-            array(
975
-                EEM_Registration::status_id_cancelled,
976
-                EEM_Registration::status_id_declined,
977
-                EEM_Registration::status_id_incomplete,
978
-                EEM_Registration::status_id_wait_list,
979
-            ),
980
-            true
981
-        );
982
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
983
-        $template_args['_event'] = $this->_cpt_model_obj;
984
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
985
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
986
-            'default_reg_status',
987
-            $default_reg_status_values,
988
-            $this->_cpt_model_obj->default_registration_status()
989
-        );
990
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
991
-            'display_desc',
992
-            $yes_no_values,
993
-            $this->_cpt_model_obj->display_description()
994
-        );
995
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
996
-            'display_ticket_selector',
997
-            $yes_no_values,
998
-            $this->_cpt_model_obj->display_ticket_selector(),
999
-            '',
1000
-            '',
1001
-            false
1002
-        );
1003
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
1004
-            'EVT_default_registration_status',
1005
-            $default_reg_status_values,
1006
-            $this->_cpt_model_obj->default_registration_status()
1007
-        );
1008
-        $template_args['additional_registration_options'] = apply_filters(
1009
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1010
-            '',
1011
-            $template_args,
1012
-            $yes_no_values,
1013
-            $default_reg_status_values
1014
-        );
1015
-        EEH_Template::display_template(
1016
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1017
-            $template_args
1018
-        );
1019
-    }
1020
-
1021
-
1022
-
1023
-    /**
1024
-     * wp_list_table_mods for caf
1025
-     * ============================
1026
-     */
1027
-    /**
1028
-     * hook into list table filters and provide filters for caffeinated list table
1029
-     *
1030
-     * @param array $old_filters    any existing filters present
1031
-     * @param array $list_table_obj the list table object
1032
-     * @return array                  new filters
1033
-     * @throws EE_Error
1034
-     * @throws InvalidArgumentException
1035
-     * @throws InvalidDataTypeException
1036
-     * @throws InvalidInterfaceException
1037
-     * @throws ReflectionException
1038
-     */
1039
-    public function list_table_filters($old_filters, $list_table_obj)
1040
-    {
1041
-        $filters = array();
1042
-        // first month/year filters
1043
-        $filters[] = $this->espresso_event_months_dropdown();
1044
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1045
-        // active status dropdown
1046
-        if ($status !== 'draft') {
1047
-            $filters[] = $this->active_status_dropdown(
1048
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
1049
-            );
1050
-            $filters[] = $this->venuesDropdown(
1051
-                isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1052
-            );
1053
-        }
1054
-        // category filter
1055
-        $filters[] = $this->category_dropdown();
1056
-        return array_merge($old_filters, $filters);
1057
-    }
1058
-
1059
-
1060
-    /**
1061
-     * espresso_event_months_dropdown
1062
-     *
1063
-     * @access public
1064
-     * @return string                dropdown listing month/year selections for events.
1065
-     */
1066
-    public function espresso_event_months_dropdown()
1067
-    {
1068
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
1069
-        // Note we need to include any other filters that are set!
1070
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1071
-        // categories?
1072
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1073
-            ? $this->_req_data['EVT_CAT']
1074
-            : null;
1075
-        // active status?
1076
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1077
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1078
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1079
-    }
1080
-
1081
-
1082
-    /**
1083
-     * returns a list of "active" statuses on the event
1084
-     *
1085
-     * @param  string $current_value whatever the current active status is
1086
-     * @return string
1087
-     */
1088
-    public function active_status_dropdown($current_value = '')
1089
-    {
1090
-        $select_name = 'active_status';
1091
-        $values = array(
1092
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1093
-            'active'   => esc_html__('Active', 'event_espresso'),
1094
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1095
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1096
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1097
-        );
1098
-
1099
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1100
-    }
1101
-
1102
-
1103
-    /**
1104
-     * returns a list of "venues"
1105
-     *
1106
-     * @param string $current_value whatever the current active status is
1107
-     * @return string
1108
-     * @throws EE_Error
1109
-     * @throws InvalidArgumentException
1110
-     * @throws InvalidDataTypeException
1111
-     * @throws InvalidInterfaceException
1112
-     * @throws ReflectionException
1113
-     */
1114
-    protected function venuesDropdown($current_value = '')
1115
-    {
1116
-        $select_name = 'venue';
1117
-        $values = array(
1118
-            '' => esc_html__('All Venues', 'event_espresso'),
1119
-        );
1120
-        // populate the list of venues.
1121
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1122
-        $venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1123
-
1124
-        foreach ($venues as $venue) {
1125
-            $values[ $venue->ID() ] = $venue->name();
1126
-        }
1127
-
1128
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1129
-    }
1130
-
1131
-
1132
-    /**
1133
-     * output a dropdown of the categories for the category filter on the event admin list table
1134
-     *
1135
-     * @access  public
1136
-     * @return string html
1137
-     */
1138
-    public function category_dropdown()
1139
-    {
1140
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1141
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1142
-    }
1143
-
1144
-
1145
-    /**
1146
-     * get total number of events today
1147
-     *
1148
-     * @access public
1149
-     * @return int
1150
-     * @throws EE_Error
1151
-     * @throws InvalidArgumentException
1152
-     * @throws InvalidDataTypeException
1153
-     * @throws InvalidInterfaceException
1154
-     */
1155
-    public function total_events_today()
1156
-    {
1157
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1158
-            'DTT_EVT_start',
1159
-            date('Y-m-d') . ' 00:00:00',
1160
-            'Y-m-d H:i:s',
1161
-            'UTC'
1162
-        );
1163
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1164
-            'DTT_EVT_start',
1165
-            date('Y-m-d') . ' 23:59:59',
1166
-            'Y-m-d H:i:s',
1167
-            'UTC'
1168
-        );
1169
-        $where = array(
1170
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1171
-        );
1172
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1173
-        return $count;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * get total number of events this month
1179
-     *
1180
-     * @access public
1181
-     * @return int
1182
-     * @throws EE_Error
1183
-     * @throws InvalidArgumentException
1184
-     * @throws InvalidDataTypeException
1185
-     * @throws InvalidInterfaceException
1186
-     */
1187
-    public function total_events_this_month()
1188
-    {
1189
-        // Dates
1190
-        $this_year_r = date('Y');
1191
-        $this_month_r = date('m');
1192
-        $days_this_month = date('t');
1193
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1194
-            'DTT_EVT_start',
1195
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1196
-            'Y-m-d H:i:s',
1197
-            'UTC'
1198
-        );
1199
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1200
-            'DTT_EVT_start',
1201
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1202
-            'Y-m-d H:i:s',
1203
-            'UTC'
1204
-        );
1205
-        $where = array(
1206
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1207
-        );
1208
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1209
-        return $count;
1210
-    }
1211
-
1212
-
1213
-    /** DEFAULT TICKETS STUFF **/
1214
-
1215
-    /**
1216
-     * Output default tickets list table view.
1217
-     *
1218
-     * @throws DomainException
1219
-     * @throws EE_Error
1220
-     * @throws InvalidArgumentException
1221
-     * @throws InvalidDataTypeException
1222
-     * @throws InvalidInterfaceException
1223
-     */
1224
-    public function _tickets_overview_list_table()
1225
-    {
1226
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1227
-        $this->display_admin_list_table_page_with_no_sidebar();
1228
-    }
1229
-
1230
-
1231
-    /**
1232
-     * @param int  $per_page
1233
-     * @param bool $count
1234
-     * @param bool $trashed
1235
-     * @return EE_Soft_Delete_Base_Class[]|int
1236
-     * @throws EE_Error
1237
-     * @throws InvalidArgumentException
1238
-     * @throws InvalidDataTypeException
1239
-     * @throws InvalidInterfaceException
1240
-     */
1241
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1242
-    {
1243
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1244
-        $order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1245
-        switch ($orderby) {
1246
-            case 'TKT_name':
1247
-                $orderby = array('TKT_name' => $order);
1248
-                break;
1249
-            case 'TKT_price':
1250
-                $orderby = array('TKT_price' => $order);
1251
-                break;
1252
-            case 'TKT_uses':
1253
-                $orderby = array('TKT_uses' => $order);
1254
-                break;
1255
-            case 'TKT_min':
1256
-                $orderby = array('TKT_min' => $order);
1257
-                break;
1258
-            case 'TKT_max':
1259
-                $orderby = array('TKT_max' => $order);
1260
-                break;
1261
-            case 'TKT_qty':
1262
-                $orderby = array('TKT_qty' => $order);
1263
-                break;
1264
-        }
1265
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1266
-            ? $this->_req_data['paged']
1267
-            : 1;
1268
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1269
-            ? $this->_req_data['perpage']
1270
-            : $per_page;
1271
-        $_where = array(
1272
-            'TKT_is_default' => 1,
1273
-            'TKT_deleted'    => $trashed,
1274
-        );
1275
-        $offset = ($current_page - 1) * $per_page;
1276
-        $limit = array($offset, $per_page);
1277
-        if (isset($this->_req_data['s'])) {
1278
-            $sstr = '%' . $this->_req_data['s'] . '%';
1279
-            $_where['OR'] = array(
1280
-                'TKT_name'        => array('LIKE', $sstr),
1281
-                'TKT_description' => array('LIKE', $sstr),
1282
-            );
1283
-        }
1284
-        $query_params = array(
1285
-            $_where,
1286
-            'order_by' => $orderby,
1287
-            'limit'    => $limit,
1288
-            'group_by' => 'TKT_ID',
1289
-        );
1290
-        if ($count) {
1291
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1292
-        } else {
1293
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1294
-        }
1295
-    }
1296
-
1297
-
1298
-    /**
1299
-     * @param bool $trash
1300
-     * @throws EE_Error
1301
-     * @throws InvalidArgumentException
1302
-     * @throws InvalidDataTypeException
1303
-     * @throws InvalidInterfaceException
1304
-     */
1305
-    protected function _trash_or_restore_ticket($trash = false)
1306
-    {
1307
-        $success = 1;
1308
-        $TKT = EEM_Ticket::instance();
1309
-        // checkboxes?
1310
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1311
-            // if array has more than one element then success message should be plural
1312
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1313
-            // cycle thru the boxes
1314
-            foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1315
-                if ($trash) {
1316
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1317
-                        $success = 0;
1318
-                    }
1319
-                } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1320
-                    $success = 0;
1321
-                }
1322
-            }
1323
-        } else {
1324
-            // grab single id and trash
1325
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1326
-            if ($trash) {
1327
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1328
-                    $success = 0;
1329
-                }
1330
-            } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1331
-                $success = 0;
1332
-            }
1333
-        }
1334
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1335
-        $query_args = array(
1336
-            'action' => 'ticket_list_table',
1337
-            'status' => $trash ? '' : 'trashed',
1338
-        );
1339
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1340
-    }
1341
-
1342
-
1343
-    /**
1344
-     * Handles trashing default ticket.
1345
-     *
1346
-     * @throws EE_Error
1347
-     * @throws InvalidArgumentException
1348
-     * @throws InvalidDataTypeException
1349
-     * @throws InvalidInterfaceException
1350
-     * @throws ReflectionException
1351
-     */
1352
-    protected function _delete_ticket()
1353
-    {
1354
-        $success = 1;
1355
-        // checkboxes?
1356
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1357
-            // if array has more than one element then success message should be plural
1358
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1359
-            // cycle thru the boxes
1360
-            foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1361
-                // delete
1362
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1363
-                    $success = 0;
1364
-                }
1365
-            }
1366
-        } else {
1367
-            // grab single id and trash
1368
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1369
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1370
-                $success = 0;
1371
-            }
1372
-        }
1373
-        $action_desc = 'deleted';
1374
-        $query_args = array(
1375
-            'action' => 'ticket_list_table',
1376
-            'status' => 'trashed',
1377
-        );
1378
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1379
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1380
-            array(array('TKT_is_default' => 1)),
1381
-            'TKT_ID',
1382
-            true
1383
-        )
1384
-        ) {
1385
-            $query_args = array();
1386
-        }
1387
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1388
-    }
1389
-
1390
-
1391
-    /**
1392
-     * @param int $TKT_ID
1393
-     * @return bool|int
1394
-     * @throws EE_Error
1395
-     * @throws InvalidArgumentException
1396
-     * @throws InvalidDataTypeException
1397
-     * @throws InvalidInterfaceException
1398
-     * @throws ReflectionException
1399
-     */
1400
-    protected function _delete_the_ticket($TKT_ID)
1401
-    {
1402
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1403
-        $tkt->_remove_relations('Datetime');
1404
-        // delete all related prices first
1405
-        $tkt->delete_related_permanently('Price');
1406
-        return $tkt->delete_permanently();
1407
-    }
20
+	/**
21
+	 * @var AdvancedEditorAdminFormSection
22
+	 */
23
+	protected $advanced_editor_admin_form;
24
+
25
+	/**
26
+	 * @var AdvancedEditorEntityData
27
+	 */
28
+	protected $advanced_editor_data;
29
+
30
+
31
+	/**
32
+	 * Extend_Events_Admin_Page constructor.
33
+	 *
34
+	 * @param bool $routing
35
+	 * @throws EE_Error
36
+	 * @throws InvalidArgumentException
37
+	 * @throws InvalidDataTypeException
38
+	 * @throws InvalidInterfaceException
39
+	 * @throws ReflectionException
40
+	 */
41
+	public function __construct($routing = true)
42
+	{
43
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
44
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
45
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
46
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
47
+		}
48
+		parent::__construct($routing);
49
+	}
50
+
51
+
52
+	/**
53
+	 * Sets routes.
54
+	 *
55
+	 * @throws EE_Error
56
+	 * @throws InvalidArgumentException
57
+	 * @throws InvalidDataTypeException
58
+	 * @throws InvalidInterfaceException
59
+	 * @since $VID:$
60
+	 */
61
+	protected function _extend_page_config()
62
+	{
63
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
64
+		// is there a evt_id in the request?
65
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
66
+			? $this->_req_data['EVT_ID']
67
+			: 0;
68
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
69
+		// tkt_id?
70
+		$tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
71
+			? $this->_req_data['TKT_ID']
72
+			: 0;
73
+		$new_page_routes = array(
74
+			'duplicate_event'          => array(
75
+				'func'       => '_duplicate_event',
76
+				'capability' => 'ee_edit_event',
77
+				'obj_id'     => $evt_id,
78
+				'noheader'   => true,
79
+			),
80
+			'ticket_list_table'        => array(
81
+				'func'       => '_tickets_overview_list_table',
82
+				'capability' => 'ee_read_default_tickets',
83
+			),
84
+			'trash_ticket'             => array(
85
+				'func'       => '_trash_or_restore_ticket',
86
+				'capability' => 'ee_delete_default_ticket',
87
+				'obj_id'     => $tkt_id,
88
+				'noheader'   => true,
89
+				'args'       => array('trash' => true),
90
+			),
91
+			'trash_tickets'            => array(
92
+				'func'       => '_trash_or_restore_ticket',
93
+				'capability' => 'ee_delete_default_tickets',
94
+				'noheader'   => true,
95
+				'args'       => array('trash' => true),
96
+			),
97
+			'restore_ticket'           => array(
98
+				'func'       => '_trash_or_restore_ticket',
99
+				'capability' => 'ee_delete_default_ticket',
100
+				'obj_id'     => $tkt_id,
101
+				'noheader'   => true,
102
+			),
103
+			'restore_tickets'          => array(
104
+				'func'       => '_trash_or_restore_ticket',
105
+				'capability' => 'ee_delete_default_tickets',
106
+				'noheader'   => true,
107
+			),
108
+			'delete_ticket'            => array(
109
+				'func'       => '_delete_ticket',
110
+				'capability' => 'ee_delete_default_ticket',
111
+				'obj_id'     => $tkt_id,
112
+				'noheader'   => true,
113
+			),
114
+			'delete_tickets'           => array(
115
+				'func'       => '_delete_ticket',
116
+				'capability' => 'ee_delete_default_tickets',
117
+				'noheader'   => true,
118
+			),
119
+			'import_page'              => array(
120
+				'func'       => '_import_page',
121
+				'capability' => 'import',
122
+			),
123
+			'import'                   => array(
124
+				'func'       => '_import_events',
125
+				'capability' => 'import',
126
+				'noheader'   => true,
127
+			),
128
+			'import_events'            => array(
129
+				'func'       => '_import_events',
130
+				'capability' => 'import',
131
+				'noheader'   => true,
132
+			),
133
+			'export_events'            => array(
134
+				'func'       => '_events_export',
135
+				'capability' => 'export',
136
+				'noheader'   => true,
137
+			),
138
+			'export_categories'        => array(
139
+				'func'       => '_categories_export',
140
+				'capability' => 'export',
141
+				'noheader'   => true,
142
+			),
143
+			'sample_export_file'       => array(
144
+				'func'       => '_sample_export_file',
145
+				'capability' => 'export',
146
+				'noheader'   => true,
147
+			),
148
+			'update_template_settings' => array(
149
+				'func'       => '_update_template_settings',
150
+				'capability' => 'manage_options',
151
+				'noheader'   => true,
152
+			),
153
+		);
154
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
155
+		// partial route/config override
156
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
157
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
158
+		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
159
+		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
160
+		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
161
+		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
162
+		// add tickets tab but only if there are more than one default ticket!
163
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
164
+			array(array('TKT_is_default' => 1)),
165
+			'TKT_ID',
166
+			true
167
+		);
168
+		if ($tkt_count > 1) {
169
+			$new_page_config = array(
170
+				'ticket_list_table' => array(
171
+					'nav'           => array(
172
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
173
+						'order' => 60,
174
+					),
175
+					'list_table'    => 'Tickets_List_Table',
176
+					'require_nonce' => false,
177
+				),
178
+			);
179
+		}
180
+		// template settings
181
+		$new_page_config['template_settings'] = array(
182
+			'nav'           => array(
183
+				'label' => esc_html__('Templates', 'event_espresso'),
184
+				'order' => 30,
185
+			),
186
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
187
+			'help_tabs'     => array(
188
+				'general_settings_templates_help_tab' => array(
189
+					'title'    => esc_html__('Templates', 'event_espresso'),
190
+					'filename' => 'general_settings_templates',
191
+				),
192
+			),
193
+			'help_tour'     => array('Templates_Help_Tour'),
194
+			'require_nonce' => false,
195
+		);
196
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
197
+		// add filters and actions
198
+		// modifying _views
199
+		add_filter(
200
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
201
+			array($this, 'add_additional_datetime_button'),
202
+			10,
203
+			2
204
+		);
205
+		add_filter(
206
+			'FHEE_event_datetime_metabox_clone_button_template',
207
+			array($this, 'add_datetime_clone_button'),
208
+			10,
209
+			2
210
+		);
211
+		add_filter(
212
+			'FHEE_event_datetime_metabox_timezones_template',
213
+			array($this, 'datetime_timezones_template'),
214
+			10,
215
+			2
216
+		);
217
+		// filters for event list table
218
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
219
+		add_filter(
220
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
221
+			array($this, 'extra_list_table_actions'),
222
+			10,
223
+			2
224
+		);
225
+		// legend item
226
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
227
+		add_action('admin_init', array($this, 'admin_init'));
228
+		// setup Advanced Editor ???
229
+		if (isset($this->_req_data['action'])
230
+			&& (
231
+				$this->_req_data['action'] === 'default_event_settings'
232
+				|| $this->_req_data['action'] === 'update_default_event_settings'
233
+			)
234
+		) {
235
+			$this->advanced_editor_admin_form = $this->loader->getShared(
236
+				'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection'
237
+			);
238
+		}
239
+		$admin_config = $this->loader->getShared('EE_Admin_Config');
240
+		if (isset($this->_req_data['action'])
241
+			&& ($this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
242
+			&& $admin_config instanceof EE_Admin_Config && $admin_config->useAdvancedEditor()
243
+		) {
244
+			$this->advanced_editor_data = $this->loader->getShared(
245
+				'EventEspresso\core\domain\services\admin\events\editor\AdvancedEditorEntityData',
246
+				[$this->_cpt_model_obj]
247
+			);
248
+		}
249
+	}
250
+
251
+
252
+	/**
253
+	 * admin_init
254
+	 */
255
+	public function admin_init()
256
+	{
257
+		EE_Registry::$i18n_js_strings = array_merge(
258
+			EE_Registry::$i18n_js_strings,
259
+			array(
260
+				'image_confirm'          => esc_html__(
261
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
262
+					'event_espresso'
263
+				),
264
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
265
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
266
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
267
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
268
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
269
+			)
270
+		);
271
+	}
272
+
273
+
274
+	/**
275
+	 * Add per page screen options to the default ticket list table view.
276
+	 *
277
+	 * @throws InvalidArgumentException
278
+	 * @throws InvalidDataTypeException
279
+	 * @throws InvalidInterfaceException
280
+	 */
281
+	protected function _add_screen_options_ticket_list_table()
282
+	{
283
+		$this->_per_page_screen_option();
284
+	}
285
+
286
+
287
+	/**
288
+	 * @param string $return
289
+	 * @param int    $id
290
+	 * @param string $new_title
291
+	 * @param string $new_slug
292
+	 * @return string
293
+	 */
294
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
295
+	{
296
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
297
+		// make sure this is only when editing
298
+		if (! empty($id)) {
299
+			$href = EE_Admin_Page::add_query_args_and_nonce(
300
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
301
+				$this->_admin_base_url
302
+			);
303
+			$title = esc_attr__('Duplicate Event', 'event_espresso');
304
+			$return .= '<a href="'
305
+					   . $href
306
+					   . '" title="'
307
+					   . $title
308
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
309
+					   . $title
310
+					   . '</a>';
311
+		}
312
+		return $return;
313
+	}
314
+
315
+
316
+	/**
317
+	 * Set the list table views for the default ticket list table view.
318
+	 */
319
+	public function _set_list_table_views_ticket_list_table()
320
+	{
321
+		$this->_views = array(
322
+			'all'     => array(
323
+				'slug'        => 'all',
324
+				'label'       => esc_html__('All', 'event_espresso'),
325
+				'count'       => 0,
326
+				'bulk_action' => array(
327
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
328
+				),
329
+			),
330
+			'trashed' => array(
331
+				'slug'        => 'trashed',
332
+				'label'       => esc_html__('Trash', 'event_espresso'),
333
+				'count'       => 0,
334
+				'bulk_action' => array(
335
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
336
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
337
+				),
338
+			),
339
+		);
340
+	}
341
+
342
+
343
+	/**
344
+	 * Enqueue scripts and styles for the event editor.
345
+	 */
346
+	public function load_scripts_styles_edit()
347
+	{
348
+		wp_register_script(
349
+			'ee-event-editor-heartbeat',
350
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
351
+			array('ee_admin_js', 'heartbeat'),
352
+			EVENT_ESPRESSO_VERSION,
353
+			true
354
+		);
355
+		wp_enqueue_script('ee-accounting');
356
+		// styles
357
+		wp_enqueue_style('espresso-ui-theme');
358
+		wp_enqueue_script('event_editor_js');
359
+		wp_enqueue_script('ee-event-editor-heartbeat');
360
+	}
361
+
362
+
363
+	/**
364
+	 * Returns template for the additional datetime.
365
+	 *
366
+	 * @param $template
367
+	 * @param $template_args
368
+	 * @return mixed
369
+	 * @throws DomainException
370
+	 */
371
+	public function add_additional_datetime_button($template, $template_args)
372
+	{
373
+		return EEH_Template::display_template(
374
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
375
+			$template_args,
376
+			true
377
+		);
378
+	}
379
+
380
+
381
+	/**
382
+	 * Returns the template for cloning a datetime.
383
+	 *
384
+	 * @param $template
385
+	 * @param $template_args
386
+	 * @return mixed
387
+	 * @throws DomainException
388
+	 */
389
+	public function add_datetime_clone_button($template, $template_args)
390
+	{
391
+		return EEH_Template::display_template(
392
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
393
+			$template_args,
394
+			true
395
+		);
396
+	}
397
+
398
+
399
+	/**
400
+	 * Returns the template for datetime timezones.
401
+	 *
402
+	 * @param $template
403
+	 * @param $template_args
404
+	 * @return mixed
405
+	 * @throws DomainException
406
+	 */
407
+	public function datetime_timezones_template($template, $template_args)
408
+	{
409
+		return EEH_Template::display_template(
410
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
411
+			$template_args,
412
+			true
413
+		);
414
+	}
415
+
416
+
417
+	/**
418
+	 * Sets the views for the default list table view.
419
+	 */
420
+	protected function _set_list_table_views_default()
421
+	{
422
+		parent::_set_list_table_views_default();
423
+		$new_views = array(
424
+			'today' => array(
425
+				'slug'        => 'today',
426
+				'label'       => esc_html__('Today', 'event_espresso'),
427
+				'count'       => $this->total_events_today(),
428
+				'bulk_action' => array(
429
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
430
+				),
431
+			),
432
+			'month' => array(
433
+				'slug'        => 'month',
434
+				'label'       => esc_html__('This Month', 'event_espresso'),
435
+				'count'       => $this->total_events_this_month(),
436
+				'bulk_action' => array(
437
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
438
+				),
439
+			),
440
+		);
441
+		$this->_views = array_merge($this->_views, $new_views);
442
+	}
443
+
444
+
445
+	/**
446
+	 * Returns the extra action links for the default list table view.
447
+	 *
448
+	 * @param array    $action_links
449
+	 * @param EE_Event $event
450
+	 * @return array
451
+	 * @throws EE_Error
452
+	 * @throws InvalidArgumentException
453
+	 * @throws InvalidDataTypeException
454
+	 * @throws InvalidInterfaceException
455
+	 * @throws ReflectionException
456
+	 */
457
+	public function extra_list_table_actions(array $action_links, EE_Event $event)
458
+	{
459
+		if (EE_Registry::instance()->CAP->current_user_can(
460
+			'ee_read_registrations',
461
+			'espresso_registrations_reports',
462
+			$event->ID()
463
+		)
464
+		) {
465
+			$reports_query_args = array(
466
+				'action' => 'reports',
467
+				'EVT_ID' => $event->ID(),
468
+			);
469
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
470
+			$action_links[] = '<a href="'
471
+							  . $reports_link
472
+							  . '" title="'
473
+							  . esc_attr__('View Report', 'event_espresso')
474
+							  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
475
+							  . "\n\t";
476
+		}
477
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
478
+			EE_Registry::instance()->load_helper('MSG_Template');
479
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
480
+				'see_notifications_for',
481
+				null,
482
+				array('EVT_ID' => $event->ID())
483
+			);
484
+		}
485
+		return $action_links;
486
+	}
487
+
488
+
489
+	/**
490
+	 * @param $items
491
+	 * @return mixed
492
+	 */
493
+	public function additional_legend_items($items)
494
+	{
495
+		if (EE_Registry::instance()->CAP->current_user_can(
496
+			'ee_read_registrations',
497
+			'espresso_registrations_reports'
498
+		)
499
+		) {
500
+			$items['reports'] = array(
501
+				'class' => 'dashicons dashicons-chart-bar',
502
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
503
+			);
504
+		}
505
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
506
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
507
+			// $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
508
+			// (can only use numeric offsets when treating strings as arrays)
509
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
510
+				$items['view_related_messages'] = array(
511
+					'class' => $related_for_icon['css_class'],
512
+					'desc'  => $related_for_icon['label'],
513
+				);
514
+			}
515
+		}
516
+		return $items;
517
+	}
518
+
519
+
520
+	/**
521
+	 * This is the callback method for the duplicate event route
522
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
523
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
524
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
525
+	 * After duplication the redirect is to the new event edit page.
526
+	 *
527
+	 * @return void
528
+	 * @throws EE_Error If EE_Event is not available with given ID
529
+	 * @throws InvalidArgumentException
530
+	 * @throws InvalidDataTypeException
531
+	 * @throws InvalidInterfaceException
532
+	 * @throws ReflectionException
533
+	 * @access protected
534
+	 */
535
+	protected function _duplicate_event()
536
+	{
537
+		// first make sure the ID for the event is in the request.
538
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
539
+		if (! isset($this->_req_data['EVT_ID'])) {
540
+			EE_Error::add_error(
541
+				esc_html__(
542
+					'In order to duplicate an event an Event ID is required.  None was given.',
543
+					'event_espresso'
544
+				),
545
+				__FILE__,
546
+				__FUNCTION__,
547
+				__LINE__
548
+			);
549
+			$this->_redirect_after_action(false, '', '', array(), true);
550
+			return;
551
+		}
552
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
553
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
554
+		if (! $orig_event instanceof EE_Event) {
555
+			throw new EE_Error(
556
+				sprintf(
557
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
558
+					$this->_req_data['EVT_ID']
559
+				)
560
+			);
561
+		}
562
+		// k now let's clone the $orig_event before getting relations
563
+		$new_event = clone $orig_event;
564
+		// original datetimes
565
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
566
+		// other original relations
567
+		$orig_ven = $orig_event->get_many_related('Venue');
568
+		// reset the ID and modify other details to make it clear this is a dupe
569
+		$new_event->set('EVT_ID', 0);
570
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
571
+		$new_event->set('EVT_name', $new_name);
572
+		$new_event->set(
573
+			'EVT_slug',
574
+			wp_unique_post_slug(
575
+				sanitize_title($orig_event->name()),
576
+				0,
577
+				'publish',
578
+				'espresso_events',
579
+				0
580
+			)
581
+		);
582
+		$new_event->set('status', 'draft');
583
+		// duplicate discussion settings
584
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
585
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
586
+		// save the new event
587
+		$new_event->save();
588
+		// venues
589
+		foreach ($orig_ven as $ven) {
590
+			$new_event->_add_relation_to($ven, 'Venue');
591
+		}
592
+		$new_event->save();
593
+		// now we need to get the question group relations and handle that
594
+		// first primary question groups
595
+		$orig_primary_qgs = $orig_event->get_many_related(
596
+			'Question_Group',
597
+			[['Event_Question_Group.EQG_primary' => true]]
598
+		);
599
+		if (! empty($orig_primary_qgs)) {
600
+			foreach ($orig_primary_qgs as $id => $obj) {
601
+				if ($obj instanceof EE_Question_Group) {
602
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
603
+				}
604
+			}
605
+		}
606
+		// next additional attendee question groups
607
+		$orig_additional_qgs = $orig_event->get_many_related(
608
+			'Question_Group',
609
+			[['Event_Question_Group.EQG_additional' => true]]
610
+		);
611
+		if (! empty($orig_additional_qgs)) {
612
+			foreach ($orig_additional_qgs as $id => $obj) {
613
+				if ($obj instanceof EE_Question_Group) {
614
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
615
+				}
616
+			}
617
+		}
618
+
619
+		$new_event->save();
620
+
621
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
622
+		$cloned_tickets = array();
623
+		foreach ($orig_datetimes as $orig_dtt) {
624
+			if (! $orig_dtt instanceof EE_Datetime) {
625
+				continue;
626
+			}
627
+			$new_dtt = clone $orig_dtt;
628
+			$orig_tkts = $orig_dtt->tickets();
629
+			// save new dtt then add to event
630
+			$new_dtt->set('DTT_ID', 0);
631
+			$new_dtt->set('DTT_sold', 0);
632
+			$new_dtt->set_reserved(0);
633
+			$new_dtt->save();
634
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
635
+			$new_event->save();
636
+			// now let's get the ticket relations setup.
637
+			foreach ((array) $orig_tkts as $orig_tkt) {
638
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
639
+				if (! $orig_tkt instanceof EE_Ticket) {
640
+					continue;
641
+				}
642
+				// is this ticket archived?  If it is then let's skip
643
+				if ($orig_tkt->get('TKT_deleted')) {
644
+					continue;
645
+				}
646
+				// does this original ticket already exist in the clone_tickets cache?
647
+				//  If so we'll just use the new ticket from it.
648
+				if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
649
+					$new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
650
+				} else {
651
+					$new_tkt = clone $orig_tkt;
652
+					// get relations on the $orig_tkt that we need to setup.
653
+					$orig_prices = $orig_tkt->prices();
654
+					$new_tkt->set('TKT_ID', 0);
655
+					$new_tkt->set('TKT_sold', 0);
656
+					$new_tkt->set('TKT_reserved', 0);
657
+					$new_tkt->save(); // make sure new ticket has ID.
658
+					// price relations on new ticket need to be setup.
659
+					foreach ($orig_prices as $orig_price) {
660
+						$new_price = clone $orig_price;
661
+						$new_price->set('PRC_ID', 0);
662
+						$new_price->save();
663
+						$new_tkt->_add_relation_to($new_price, 'Price');
664
+						$new_tkt->save();
665
+					}
666
+
667
+					do_action(
668
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
669
+						$orig_tkt,
670
+						$new_tkt,
671
+						$orig_prices,
672
+						$orig_event,
673
+						$orig_dtt,
674
+						$new_dtt
675
+					);
676
+				}
677
+				// k now we can add the new ticket as a relation to the new datetime
678
+				// and make sure its added to our cached $cloned_tickets array
679
+				// for use with later datetimes that have the same ticket.
680
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
681
+				$new_dtt->save();
682
+				$cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
683
+			}
684
+		}
685
+		// clone taxonomy information
686
+		$taxonomies_to_clone_with = apply_filters(
687
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
688
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
689
+		);
690
+		// get terms for original event (notice)
691
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
692
+		// loop through terms and add them to new event.
693
+		foreach ($orig_terms as $term) {
694
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
695
+		}
696
+
697
+		// duplicate other core WP_Post items for this event.
698
+		// post thumbnail (feature image).
699
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
700
+		if ($feature_image_id) {
701
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
702
+		}
703
+
704
+		// duplicate page_template setting
705
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
706
+		if ($page_template) {
707
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
708
+		}
709
+
710
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
711
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
712
+		if ($new_event->ID()) {
713
+			$redirect_args = array(
714
+				'post'   => $new_event->ID(),
715
+				'action' => 'edit',
716
+			);
717
+			EE_Error::add_success(
718
+				esc_html__(
719
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
720
+					'event_espresso'
721
+				)
722
+			);
723
+		} else {
724
+			$redirect_args = array(
725
+				'action' => 'default',
726
+			);
727
+			EE_Error::add_error(
728
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
729
+				__FILE__,
730
+				__FUNCTION__,
731
+				__LINE__
732
+			);
733
+		}
734
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
735
+	}
736
+
737
+
738
+	/**
739
+	 * Generates output for the import page.
740
+	 *
741
+	 * @throws DomainException
742
+	 * @throws EE_Error
743
+	 * @throws InvalidArgumentException
744
+	 * @throws InvalidDataTypeException
745
+	 * @throws InvalidInterfaceException
746
+	 */
747
+	protected function _import_page()
748
+	{
749
+		$title = esc_html__('Import', 'event_espresso');
750
+		$intro = esc_html__(
751
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
752
+			'event_espresso'
753
+		);
754
+		$form_url = EVENTS_ADMIN_URL;
755
+		$action = 'import_events';
756
+		$type = 'csv';
757
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
758
+			$title,
759
+			$intro,
760
+			$form_url,
761
+			$action,
762
+			$type
763
+		);
764
+		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
765
+			array('action' => 'sample_export_file'),
766
+			$this->_admin_base_url
767
+		);
768
+		$content = EEH_Template::display_template(
769
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
770
+			$this->_template_args,
771
+			true
772
+		);
773
+		$this->_template_args['admin_page_content'] = $content;
774
+		$this->display_admin_page_with_sidebar();
775
+	}
776
+
777
+
778
+	/**
779
+	 * _import_events
780
+	 * This handles displaying the screen and running imports for importing events.
781
+	 *
782
+	 * @return void
783
+	 * @throws EE_Error
784
+	 * @throws InvalidArgumentException
785
+	 * @throws InvalidDataTypeException
786
+	 * @throws InvalidInterfaceException
787
+	 */
788
+	protected function _import_events()
789
+	{
790
+		require_once(EE_CLASSES . 'EE_Import.class.php');
791
+		$success = EE_Import::instance()->import();
792
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
793
+	}
794
+
795
+
796
+	/**
797
+	 * _events_export
798
+	 * Will export all (or just the given event) to a Excel compatible file.
799
+	 *
800
+	 * @access protected
801
+	 * @return void
802
+	 */
803
+	protected function _events_export()
804
+	{
805
+		if (isset($this->_req_data['EVT_ID'])) {
806
+			$event_ids = $this->_req_data['EVT_ID'];
807
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
808
+			$event_ids = $this->_req_data['EVT_IDs'];
809
+		} else {
810
+			$event_ids = null;
811
+		}
812
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
813
+		$new_request_args = array(
814
+			'export' => 'report',
815
+			'action' => 'all_event_data',
816
+			'EVT_ID' => $event_ids,
817
+		);
818
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
819
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
820
+			require_once(EE_CLASSES . 'EE_Export.class.php');
821
+			$EE_Export = EE_Export::instance($this->_req_data);
822
+			$EE_Export->export();
823
+		}
824
+	}
825
+
826
+
827
+	/**
828
+	 * handle category exports()
829
+	 *
830
+	 * @return void
831
+	 */
832
+	protected function _categories_export()
833
+	{
834
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
835
+		$new_request_args = array(
836
+			'export'       => 'report',
837
+			'action'       => 'categories',
838
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
839
+		);
840
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
841
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
842
+			require_once(EE_CLASSES . 'EE_Export.class.php');
843
+			$EE_Export = EE_Export::instance($this->_req_data);
844
+			$EE_Export->export();
845
+		}
846
+	}
847
+
848
+
849
+	/**
850
+	 * Creates a sample CSV file for importing
851
+	 */
852
+	protected function _sample_export_file()
853
+	{
854
+		// require_once(EE_CLASSES . 'EE_Export.class.php');
855
+		EE_Export::instance()->export_sample();
856
+	}
857
+
858
+
859
+	/*************        Template Settings        *************/
860
+	/**
861
+	 * Generates template settings page output
862
+	 *
863
+	 * @throws DomainException
864
+	 * @throws EE_Error
865
+	 * @throws InvalidArgumentException
866
+	 * @throws InvalidDataTypeException
867
+	 * @throws InvalidInterfaceException
868
+	 */
869
+	protected function _template_settings()
870
+	{
871
+		$this->_template_args['values'] = $this->_yes_no_values;
872
+		/**
873
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
874
+		 * from General_Settings_Admin_Page to here.
875
+		 */
876
+		$this->_template_args = apply_filters(
877
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
878
+			$this->_template_args
879
+		);
880
+		$this->_set_add_edit_form_tags('update_template_settings');
881
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
882
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
883
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
884
+			$this->_template_args,
885
+			true
886
+		);
887
+		$this->display_admin_page_with_sidebar();
888
+	}
889
+
890
+
891
+	/**
892
+	 * Handler for updating template settings.
893
+	 *
894
+	 * @throws EE_Error
895
+	 * @throws InvalidArgumentException
896
+	 * @throws InvalidDataTypeException
897
+	 * @throws InvalidInterfaceException
898
+	 */
899
+	protected function _update_template_settings()
900
+	{
901
+		/**
902
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
903
+		 * from General_Settings_Admin_Page to here.
904
+		 */
905
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
906
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
907
+			EE_Registry::instance()->CFG->template_settings,
908
+			$this->_req_data
909
+		);
910
+		// update custom post type slugs and detect if we need to flush rewrite rules
911
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
912
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
913
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
914
+			: EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
915
+		$what = 'Template Settings';
916
+		$success = $this->_update_espresso_configuration(
917
+			$what,
918
+			EE_Registry::instance()->CFG->template_settings,
919
+			__FILE__,
920
+			__FUNCTION__,
921
+			__LINE__
922
+		);
923
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
924
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
925
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
926
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
927
+			);
928
+			$rewrite_rules->flush();
929
+		}
930
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
931
+	}
932
+
933
+
934
+	/**
935
+	 * _premium_event_editor_meta_boxes
936
+	 * add all metaboxes related to the event_editor
937
+	 *
938
+	 * @access protected
939
+	 * @return void
940
+	 * @throws EE_Error
941
+	 * @throws InvalidArgumentException
942
+	 * @throws InvalidDataTypeException
943
+	 * @throws InvalidInterfaceException
944
+	 * @throws ReflectionException
945
+	 */
946
+	protected function _premium_event_editor_meta_boxes()
947
+	{
948
+		$this->verify_cpt_object();
949
+		add_meta_box(
950
+			'espresso_event_editor_event_options',
951
+			esc_html__('Event Registration Options', 'event_espresso'),
952
+			array($this, 'registration_options_meta_box'),
953
+			$this->page_slug,
954
+			'side',
955
+			'core'
956
+		);
957
+	}
958
+
959
+
960
+	/**
961
+	 * override caf metabox
962
+	 *
963
+	 * @return void
964
+	 * @throws DomainException
965
+	 * @throws EE_Error
966
+	 */
967
+	public function registration_options_meta_box()
968
+	{
969
+		$yes_no_values = array(
970
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
971
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
972
+		);
973
+		$default_reg_status_values = EEM_Registration::reg_status_array(
974
+			array(
975
+				EEM_Registration::status_id_cancelled,
976
+				EEM_Registration::status_id_declined,
977
+				EEM_Registration::status_id_incomplete,
978
+				EEM_Registration::status_id_wait_list,
979
+			),
980
+			true
981
+		);
982
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
983
+		$template_args['_event'] = $this->_cpt_model_obj;
984
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
985
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
986
+			'default_reg_status',
987
+			$default_reg_status_values,
988
+			$this->_cpt_model_obj->default_registration_status()
989
+		);
990
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
991
+			'display_desc',
992
+			$yes_no_values,
993
+			$this->_cpt_model_obj->display_description()
994
+		);
995
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
996
+			'display_ticket_selector',
997
+			$yes_no_values,
998
+			$this->_cpt_model_obj->display_ticket_selector(),
999
+			'',
1000
+			'',
1001
+			false
1002
+		);
1003
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
1004
+			'EVT_default_registration_status',
1005
+			$default_reg_status_values,
1006
+			$this->_cpt_model_obj->default_registration_status()
1007
+		);
1008
+		$template_args['additional_registration_options'] = apply_filters(
1009
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1010
+			'',
1011
+			$template_args,
1012
+			$yes_no_values,
1013
+			$default_reg_status_values
1014
+		);
1015
+		EEH_Template::display_template(
1016
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1017
+			$template_args
1018
+		);
1019
+	}
1020
+
1021
+
1022
+
1023
+	/**
1024
+	 * wp_list_table_mods for caf
1025
+	 * ============================
1026
+	 */
1027
+	/**
1028
+	 * hook into list table filters and provide filters for caffeinated list table
1029
+	 *
1030
+	 * @param array $old_filters    any existing filters present
1031
+	 * @param array $list_table_obj the list table object
1032
+	 * @return array                  new filters
1033
+	 * @throws EE_Error
1034
+	 * @throws InvalidArgumentException
1035
+	 * @throws InvalidDataTypeException
1036
+	 * @throws InvalidInterfaceException
1037
+	 * @throws ReflectionException
1038
+	 */
1039
+	public function list_table_filters($old_filters, $list_table_obj)
1040
+	{
1041
+		$filters = array();
1042
+		// first month/year filters
1043
+		$filters[] = $this->espresso_event_months_dropdown();
1044
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1045
+		// active status dropdown
1046
+		if ($status !== 'draft') {
1047
+			$filters[] = $this->active_status_dropdown(
1048
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
1049
+			);
1050
+			$filters[] = $this->venuesDropdown(
1051
+				isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1052
+			);
1053
+		}
1054
+		// category filter
1055
+		$filters[] = $this->category_dropdown();
1056
+		return array_merge($old_filters, $filters);
1057
+	}
1058
+
1059
+
1060
+	/**
1061
+	 * espresso_event_months_dropdown
1062
+	 *
1063
+	 * @access public
1064
+	 * @return string                dropdown listing month/year selections for events.
1065
+	 */
1066
+	public function espresso_event_months_dropdown()
1067
+	{
1068
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
1069
+		// Note we need to include any other filters that are set!
1070
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1071
+		// categories?
1072
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1073
+			? $this->_req_data['EVT_CAT']
1074
+			: null;
1075
+		// active status?
1076
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1077
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1078
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1079
+	}
1080
+
1081
+
1082
+	/**
1083
+	 * returns a list of "active" statuses on the event
1084
+	 *
1085
+	 * @param  string $current_value whatever the current active status is
1086
+	 * @return string
1087
+	 */
1088
+	public function active_status_dropdown($current_value = '')
1089
+	{
1090
+		$select_name = 'active_status';
1091
+		$values = array(
1092
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1093
+			'active'   => esc_html__('Active', 'event_espresso'),
1094
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1095
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1096
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1097
+		);
1098
+
1099
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1100
+	}
1101
+
1102
+
1103
+	/**
1104
+	 * returns a list of "venues"
1105
+	 *
1106
+	 * @param string $current_value whatever the current active status is
1107
+	 * @return string
1108
+	 * @throws EE_Error
1109
+	 * @throws InvalidArgumentException
1110
+	 * @throws InvalidDataTypeException
1111
+	 * @throws InvalidInterfaceException
1112
+	 * @throws ReflectionException
1113
+	 */
1114
+	protected function venuesDropdown($current_value = '')
1115
+	{
1116
+		$select_name = 'venue';
1117
+		$values = array(
1118
+			'' => esc_html__('All Venues', 'event_espresso'),
1119
+		);
1120
+		// populate the list of venues.
1121
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1122
+		$venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1123
+
1124
+		foreach ($venues as $venue) {
1125
+			$values[ $venue->ID() ] = $venue->name();
1126
+		}
1127
+
1128
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1129
+	}
1130
+
1131
+
1132
+	/**
1133
+	 * output a dropdown of the categories for the category filter on the event admin list table
1134
+	 *
1135
+	 * @access  public
1136
+	 * @return string html
1137
+	 */
1138
+	public function category_dropdown()
1139
+	{
1140
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1141
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1142
+	}
1143
+
1144
+
1145
+	/**
1146
+	 * get total number of events today
1147
+	 *
1148
+	 * @access public
1149
+	 * @return int
1150
+	 * @throws EE_Error
1151
+	 * @throws InvalidArgumentException
1152
+	 * @throws InvalidDataTypeException
1153
+	 * @throws InvalidInterfaceException
1154
+	 */
1155
+	public function total_events_today()
1156
+	{
1157
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1158
+			'DTT_EVT_start',
1159
+			date('Y-m-d') . ' 00:00:00',
1160
+			'Y-m-d H:i:s',
1161
+			'UTC'
1162
+		);
1163
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1164
+			'DTT_EVT_start',
1165
+			date('Y-m-d') . ' 23:59:59',
1166
+			'Y-m-d H:i:s',
1167
+			'UTC'
1168
+		);
1169
+		$where = array(
1170
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1171
+		);
1172
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1173
+		return $count;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * get total number of events this month
1179
+	 *
1180
+	 * @access public
1181
+	 * @return int
1182
+	 * @throws EE_Error
1183
+	 * @throws InvalidArgumentException
1184
+	 * @throws InvalidDataTypeException
1185
+	 * @throws InvalidInterfaceException
1186
+	 */
1187
+	public function total_events_this_month()
1188
+	{
1189
+		// Dates
1190
+		$this_year_r = date('Y');
1191
+		$this_month_r = date('m');
1192
+		$days_this_month = date('t');
1193
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1194
+			'DTT_EVT_start',
1195
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1196
+			'Y-m-d H:i:s',
1197
+			'UTC'
1198
+		);
1199
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1200
+			'DTT_EVT_start',
1201
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1202
+			'Y-m-d H:i:s',
1203
+			'UTC'
1204
+		);
1205
+		$where = array(
1206
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1207
+		);
1208
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1209
+		return $count;
1210
+	}
1211
+
1212
+
1213
+	/** DEFAULT TICKETS STUFF **/
1214
+
1215
+	/**
1216
+	 * Output default tickets list table view.
1217
+	 *
1218
+	 * @throws DomainException
1219
+	 * @throws EE_Error
1220
+	 * @throws InvalidArgumentException
1221
+	 * @throws InvalidDataTypeException
1222
+	 * @throws InvalidInterfaceException
1223
+	 */
1224
+	public function _tickets_overview_list_table()
1225
+	{
1226
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1227
+		$this->display_admin_list_table_page_with_no_sidebar();
1228
+	}
1229
+
1230
+
1231
+	/**
1232
+	 * @param int  $per_page
1233
+	 * @param bool $count
1234
+	 * @param bool $trashed
1235
+	 * @return EE_Soft_Delete_Base_Class[]|int
1236
+	 * @throws EE_Error
1237
+	 * @throws InvalidArgumentException
1238
+	 * @throws InvalidDataTypeException
1239
+	 * @throws InvalidInterfaceException
1240
+	 */
1241
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1242
+	{
1243
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1244
+		$order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1245
+		switch ($orderby) {
1246
+			case 'TKT_name':
1247
+				$orderby = array('TKT_name' => $order);
1248
+				break;
1249
+			case 'TKT_price':
1250
+				$orderby = array('TKT_price' => $order);
1251
+				break;
1252
+			case 'TKT_uses':
1253
+				$orderby = array('TKT_uses' => $order);
1254
+				break;
1255
+			case 'TKT_min':
1256
+				$orderby = array('TKT_min' => $order);
1257
+				break;
1258
+			case 'TKT_max':
1259
+				$orderby = array('TKT_max' => $order);
1260
+				break;
1261
+			case 'TKT_qty':
1262
+				$orderby = array('TKT_qty' => $order);
1263
+				break;
1264
+		}
1265
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1266
+			? $this->_req_data['paged']
1267
+			: 1;
1268
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1269
+			? $this->_req_data['perpage']
1270
+			: $per_page;
1271
+		$_where = array(
1272
+			'TKT_is_default' => 1,
1273
+			'TKT_deleted'    => $trashed,
1274
+		);
1275
+		$offset = ($current_page - 1) * $per_page;
1276
+		$limit = array($offset, $per_page);
1277
+		if (isset($this->_req_data['s'])) {
1278
+			$sstr = '%' . $this->_req_data['s'] . '%';
1279
+			$_where['OR'] = array(
1280
+				'TKT_name'        => array('LIKE', $sstr),
1281
+				'TKT_description' => array('LIKE', $sstr),
1282
+			);
1283
+		}
1284
+		$query_params = array(
1285
+			$_where,
1286
+			'order_by' => $orderby,
1287
+			'limit'    => $limit,
1288
+			'group_by' => 'TKT_ID',
1289
+		);
1290
+		if ($count) {
1291
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1292
+		} else {
1293
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1294
+		}
1295
+	}
1296
+
1297
+
1298
+	/**
1299
+	 * @param bool $trash
1300
+	 * @throws EE_Error
1301
+	 * @throws InvalidArgumentException
1302
+	 * @throws InvalidDataTypeException
1303
+	 * @throws InvalidInterfaceException
1304
+	 */
1305
+	protected function _trash_or_restore_ticket($trash = false)
1306
+	{
1307
+		$success = 1;
1308
+		$TKT = EEM_Ticket::instance();
1309
+		// checkboxes?
1310
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1311
+			// if array has more than one element then success message should be plural
1312
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1313
+			// cycle thru the boxes
1314
+			foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1315
+				if ($trash) {
1316
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1317
+						$success = 0;
1318
+					}
1319
+				} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1320
+					$success = 0;
1321
+				}
1322
+			}
1323
+		} else {
1324
+			// grab single id and trash
1325
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1326
+			if ($trash) {
1327
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1328
+					$success = 0;
1329
+				}
1330
+			} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1331
+				$success = 0;
1332
+			}
1333
+		}
1334
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1335
+		$query_args = array(
1336
+			'action' => 'ticket_list_table',
1337
+			'status' => $trash ? '' : 'trashed',
1338
+		);
1339
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1340
+	}
1341
+
1342
+
1343
+	/**
1344
+	 * Handles trashing default ticket.
1345
+	 *
1346
+	 * @throws EE_Error
1347
+	 * @throws InvalidArgumentException
1348
+	 * @throws InvalidDataTypeException
1349
+	 * @throws InvalidInterfaceException
1350
+	 * @throws ReflectionException
1351
+	 */
1352
+	protected function _delete_ticket()
1353
+	{
1354
+		$success = 1;
1355
+		// checkboxes?
1356
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1357
+			// if array has more than one element then success message should be plural
1358
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1359
+			// cycle thru the boxes
1360
+			foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1361
+				// delete
1362
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1363
+					$success = 0;
1364
+				}
1365
+			}
1366
+		} else {
1367
+			// grab single id and trash
1368
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1369
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1370
+				$success = 0;
1371
+			}
1372
+		}
1373
+		$action_desc = 'deleted';
1374
+		$query_args = array(
1375
+			'action' => 'ticket_list_table',
1376
+			'status' => 'trashed',
1377
+		);
1378
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1379
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1380
+			array(array('TKT_is_default' => 1)),
1381
+			'TKT_ID',
1382
+			true
1383
+		)
1384
+		) {
1385
+			$query_args = array();
1386
+		}
1387
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1388
+	}
1389
+
1390
+
1391
+	/**
1392
+	 * @param int $TKT_ID
1393
+	 * @return bool|int
1394
+	 * @throws EE_Error
1395
+	 * @throws InvalidArgumentException
1396
+	 * @throws InvalidDataTypeException
1397
+	 * @throws InvalidInterfaceException
1398
+	 * @throws ReflectionException
1399
+	 */
1400
+	protected function _delete_the_ticket($TKT_ID)
1401
+	{
1402
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1403
+		$tkt->_remove_relations('Datetime');
1404
+		// delete all related prices first
1405
+		$tkt->delete_related_permanently('Price');
1406
+		return $tkt->delete_permanently();
1407
+	}
1408 1408
 }
Please login to merge, or discard this patch.