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