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