Completed
Branch master (7421d0)
by
unknown
11:25 queued 06:55
created
admin/extend/registration_form/forms/SessionLifespanFormHandler.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -9,64 +9,64 @@
 block discarded – undo
9 9
 
10 10
 class SessionLifespanFormHandler
11 11
 {
12
-    private SessionLifespanOption $session_lifespan_option;
13
-    private EE_Config $config;
12
+	private SessionLifespanOption $session_lifespan_option;
13
+	private EE_Config $config;
14 14
 
15 15
 
16
-    /**
17
-     * SessionLifespanForm constructor.
18
-     *
19
-     * @param SessionLifespanOption $session_lifespan_option
20
-     * @param EE_Config $config
21
-     */
22
-    public function __construct(SessionLifespanOption $session_lifespan_option, EE_Config $config)
23
-    {
24
-        $this->session_lifespan_option = $session_lifespan_option;
25
-        $this->config = $config;
26
-    }
16
+	/**
17
+	 * SessionLifespanForm constructor.
18
+	 *
19
+	 * @param SessionLifespanOption $session_lifespan_option
20
+	 * @param EE_Config $config
21
+	 */
22
+	public function __construct(SessionLifespanOption $session_lifespan_option, EE_Config $config)
23
+	{
24
+		$this->session_lifespan_option = $session_lifespan_option;
25
+		$this->config = $config;
26
+	}
27 27
 
28 28
 
29
-    public function process(SessionLifespanForm $form)
30
-    {
31
-        try {
32
-            // if not displaying a form, then check for form submission
33
-            if ($form->was_submitted()) {
34
-                // capture form data
35
-                $form->receive_form_submission();
36
-                // validate form data
37
-                if ($form->is_valid()) {
38
-                    // grab validated data from form
39
-                    $valid_data = $form->valid_data();
40
-                    if (isset($valid_data['session_lifespan'])) {
41
-                        $session_lifespan = (int) $valid_data['session_lifespan'];
42
-                        $this->session_lifespan_option->setSessionLifespan($session_lifespan);
43
-                        $this->config->registration->setUseSessionCountdown(
44
-                            isset($valid_data['use_session_countdown'])
45
-                            && $valid_data['use_session_countdown'] === EE_Switch_Input::OPTION_ON
46
-                        );
47
-                        $this->config->update_espresso_config();
48
-                    } else {
49
-                        EE_Error::add_error(
50
-                            esc_html__(
51
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
52
-                                'event_espresso'
53
-                            ),
54
-                            __FILE__,
55
-                            __FUNCTION__,
56
-                            __LINE__
57
-                        );
58
-                    }
59
-                } elseif ($form->submission_error_message() !== '') {
60
-                    EE_Error::add_error(
61
-                        $form->submission_error_message(),
62
-                        __FILE__,
63
-                        __FUNCTION__,
64
-                        __LINE__
65
-                    );
66
-                }
67
-            }
68
-        } catch (EE_Error $e) {
69
-            $e->get_error();
70
-        }
71
-    }
29
+	public function process(SessionLifespanForm $form)
30
+	{
31
+		try {
32
+			// if not displaying a form, then check for form submission
33
+			if ($form->was_submitted()) {
34
+				// capture form data
35
+				$form->receive_form_submission();
36
+				// validate form data
37
+				if ($form->is_valid()) {
38
+					// grab validated data from form
39
+					$valid_data = $form->valid_data();
40
+					if (isset($valid_data['session_lifespan'])) {
41
+						$session_lifespan = (int) $valid_data['session_lifespan'];
42
+						$this->session_lifespan_option->setSessionLifespan($session_lifespan);
43
+						$this->config->registration->setUseSessionCountdown(
44
+							isset($valid_data['use_session_countdown'])
45
+							&& $valid_data['use_session_countdown'] === EE_Switch_Input::OPTION_ON
46
+						);
47
+						$this->config->update_espresso_config();
48
+					} else {
49
+						EE_Error::add_error(
50
+							esc_html__(
51
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
52
+								'event_espresso'
53
+							),
54
+							__FILE__,
55
+							__FUNCTION__,
56
+							__LINE__
57
+						);
58
+					}
59
+				} elseif ($form->submission_error_message() !== '') {
60
+					EE_Error::add_error(
61
+						$form->submission_error_message(),
62
+						__FILE__,
63
+						__FUNCTION__,
64
+						__LINE__
65
+					);
66
+				}
67
+			}
68
+		} catch (EE_Error $e) {
69
+			$e->get_error();
70
+		}
71
+	}
72 72
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/registration_form/forms/SessionLifespanForm.php 2 patches
Indentation   +66 added lines, -66 removed lines patch added patch discarded remove patch
@@ -14,70 +14,70 @@
 block discarded – undo
14 14
 
15 15
 class SessionLifespanForm extends EE_Form_Section_Proper
16 16
 {
17
-    /**
18
-     * SessionLifespanForm constructor.
19
-     *
20
-     * @param SessionLifespanOption  $session_lifespan_option
21
-     * @param EE_Registration_Config $reg_config
22
-     * @throws EE_Error
23
-     */
24
-    public function __construct(SessionLifespanOption $session_lifespan_option, EE_Registration_Config $reg_config)
25
-    {
26
-        parent::__construct([
27
-            'name'            => 'session_lifespan',
28
-            'html_id'         => 'session_lifespan',
29
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
30
-            'subsections'     => apply_filters(
31
-                'FHEE__EventEspresso_caffeinated_admin_extend_registration_form_forms_SessionLifespanForm__construct__form_subsections',
32
-                [
33
-                    'session_lifespan_hdr'   => new EE_Form_Section_HTML(
34
-                        EEH_HTML::h2(esc_html__('Session Settings', 'event_espresso'))
35
-                    ),
36
-                    'session_lifespan' => new EE_Select_Input(
37
-                        [
38
-                            300     => esc_html__('Five Minutes', 'event_espresso'),
39
-                            900     => esc_html__('Fifteen Minutes', 'event_espresso'),
40
-                            1800    => esc_html__('Thirty Minutes', 'event_espresso'),
41
-                            3600    => esc_html__('One Hour', 'event_espresso'),
42
-                            7200    => esc_html__('Two Hours', 'event_espresso'),
43
-                        ],
44
-                        [
45
-                            'html_label_text' => esc_html__('Session Lifespan', 'event_espresso'),
46
-                            'html_help_text'  => esc_html__(
47
-                                'Controls how long a user has to complete the registration form. Defaults to 1 hour.',
48
-                                'event_espresso'
49
-                            ),
50
-                            'default'         => $session_lifespan_option->getSessionLifespan(),
51
-                            'required'        => false,
52
-                        ]
53
-                    ),
54
-                    'use_session_countdown' => new EE_Switch_Input(
55
-                        [
56
-                            'html_label_text' => esc_html__('Session Countdown Timer', 'event_espresso'),
57
-                            'default'        => $reg_config->useSessionCountdown()
58
-                                ? EE_Switch_Input::OPTION_ON
59
-                                : EE_Switch_Input::OPTION_OFF,
60
-                            'html_name'      => 'use_session_countdown',
61
-                            'html_help_text' => esc_html__(
62
-                                'Whether to display a countdown timer to the user showing how much time they have left to complete the registration form. Defaults to off.',
63
-                                'event_espresso'
64
-                            ),
65
-                            'layout_container_class' => 'ee-feature-highlight-2024',
66
-                            'extra_container_html' => '<span class="ee-feature-highlight-2024-notice">✨ ' . esc_html__('NEW','event_espresso') . '</span>',
67
-                        ],
68
-                        [
69
-                            EE_Switch_Input::OPTION_OFF => esc_html__(
70
-                                'session countdown timer is NOT displayed',
71
-                                'event_espresso'
72
-                            ),
73
-                            EE_Switch_Input::OPTION_ON  => esc_html__(
74
-                                'session countdown timer is displayed',
75
-                                'event_espresso'
76
-                            ),
77
-                        ]
78
-                    ),
79
-                ]
80
-            ),
81
-        ]);
82
-    }
17
+	/**
18
+	 * SessionLifespanForm constructor.
19
+	 *
20
+	 * @param SessionLifespanOption  $session_lifespan_option
21
+	 * @param EE_Registration_Config $reg_config
22
+	 * @throws EE_Error
23
+	 */
24
+	public function __construct(SessionLifespanOption $session_lifespan_option, EE_Registration_Config $reg_config)
25
+	{
26
+		parent::__construct([
27
+			'name'            => 'session_lifespan',
28
+			'html_id'         => 'session_lifespan',
29
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
30
+			'subsections'     => apply_filters(
31
+				'FHEE__EventEspresso_caffeinated_admin_extend_registration_form_forms_SessionLifespanForm__construct__form_subsections',
32
+				[
33
+					'session_lifespan_hdr'   => new EE_Form_Section_HTML(
34
+						EEH_HTML::h2(esc_html__('Session Settings', 'event_espresso'))
35
+					),
36
+					'session_lifespan' => new EE_Select_Input(
37
+						[
38
+							300     => esc_html__('Five Minutes', 'event_espresso'),
39
+							900     => esc_html__('Fifteen Minutes', 'event_espresso'),
40
+							1800    => esc_html__('Thirty Minutes', 'event_espresso'),
41
+							3600    => esc_html__('One Hour', 'event_espresso'),
42
+							7200    => esc_html__('Two Hours', 'event_espresso'),
43
+						],
44
+						[
45
+							'html_label_text' => esc_html__('Session Lifespan', 'event_espresso'),
46
+							'html_help_text'  => esc_html__(
47
+								'Controls how long a user has to complete the registration form. Defaults to 1 hour.',
48
+								'event_espresso'
49
+							),
50
+							'default'         => $session_lifespan_option->getSessionLifespan(),
51
+							'required'        => false,
52
+						]
53
+					),
54
+					'use_session_countdown' => new EE_Switch_Input(
55
+						[
56
+							'html_label_text' => esc_html__('Session Countdown Timer', 'event_espresso'),
57
+							'default'        => $reg_config->useSessionCountdown()
58
+								? EE_Switch_Input::OPTION_ON
59
+								: EE_Switch_Input::OPTION_OFF,
60
+							'html_name'      => 'use_session_countdown',
61
+							'html_help_text' => esc_html__(
62
+								'Whether to display a countdown timer to the user showing how much time they have left to complete the registration form. Defaults to off.',
63
+								'event_espresso'
64
+							),
65
+							'layout_container_class' => 'ee-feature-highlight-2024',
66
+							'extra_container_html' => '<span class="ee-feature-highlight-2024-notice">✨ ' . esc_html__('NEW','event_espresso') . '</span>',
67
+						],
68
+						[
69
+							EE_Switch_Input::OPTION_OFF => esc_html__(
70
+								'session countdown timer is NOT displayed',
71
+								'event_espresso'
72
+							),
73
+							EE_Switch_Input::OPTION_ON  => esc_html__(
74
+								'session countdown timer is displayed',
75
+								'event_espresso'
76
+							),
77
+						]
78
+					),
79
+				]
80
+			),
81
+		]);
82
+	}
83 83
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -63,7 +63,7 @@
 block discarded – undo
63 63
                                 'event_espresso'
64 64
                             ),
65 65
                             'layout_container_class' => 'ee-feature-highlight-2024',
66
-                            'extra_container_html' => '<span class="ee-feature-highlight-2024-notice">✨ ' . esc_html__('NEW','event_espresso') . '</span>',
66
+                            'extra_container_html' => '<span class="ee-feature-highlight-2024-notice">✨ '.esc_html__('NEW', 'event_espresso').'</span>',
67 67
                         ],
68 68
                         [
69 69
                             EE_Switch_Input::OPTION_OFF => esc_html__(
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1287 added lines, -1287 removed lines patch added patch discarded remove patch
@@ -18,1297 +18,1297 @@
 block discarded – undo
18 18
  */
19 19
 class Extend_Events_Admin_Page extends Events_Admin_Page
20 20
 {
21
-    /**
22
-     * Extend_Events_Admin_Page constructor.
23
-     *
24
-     * @param bool $routing
25
-     * @throws ReflectionException
26
-     */
27
-    public function __construct($routing = true)
28
-    {
29
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
30
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
31
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
32
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
33
-        }
34
-        parent::__construct($routing);
35
-        $this->admin_config = $this->loader->getShared('EE_Admin_Config');
36
-    }
37
-
38
-
39
-    protected function _set_page_config()
40
-    {
41
-        parent::_set_page_config();
42
-
43
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
44
-        // is there an evt_id in the request?
45
-        $EVT_ID                                          = $this->request->getRequestParam('EVT_ID', 0, 'int');
46
-        $EVT_ID                                          = $this->request->getRequestParam('post', $EVT_ID, 'int');
47
-        $TKT_ID                                          = $this->request->getRequestParam('TKT_ID', 0, 'int');
48
-        $new_page_routes                                 = [
49
-            'duplicate_event'          => [
50
-                'func'       => '_duplicate_event',
51
-                'capability' => 'ee_edit_event',
52
-                'obj_id'     => $EVT_ID,
53
-                'noheader'   => true,
54
-            ],
55
-            'import_page'              => [
56
-                'func'       => '_import_page',
57
-                'capability' => 'import',
58
-            ],
59
-            'import'                   => [
60
-                'func'       => '_import_events',
61
-                'capability' => 'import',
62
-                'noheader'   => true,
63
-            ],
64
-            'import_events'            => [
65
-                'func'       => '_import_events',
66
-                'capability' => 'import',
67
-                'noheader'   => true,
68
-            ],
69
-            'export_events'            => [
70
-                'func'       => '_events_export',
71
-                'capability' => 'export',
72
-                'noheader'   => true,
73
-            ],
74
-            'export_categories'        => [
75
-                'func'       => '_categories_export',
76
-                'capability' => 'export',
77
-                'noheader'   => true,
78
-            ],
79
-            'sample_export_file'       => [
80
-                'func'       => '_sample_export_file',
81
-                'capability' => 'export',
82
-                'noheader'   => true,
83
-            ],
84
-            'update_template_settings' => [
85
-                'func'       => '_update_template_settings',
86
-                'capability' => 'manage_options',
87
-                'noheader'   => true,
88
-            ],
89
-            'ticket_list_table'        => [
90
-                'func'       => '_tickets_overview_list_table',
91
-                'capability' => 'ee_read_default_tickets',
92
-            ],
93
-        ];
94
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
95
-        $this->_page_config['edit']['metaboxes'][]       = '_premium_event_editor_meta_boxes';
96
-        // don't load these meta boxes if using the advanced editor
97
-        if (
98
-            ! $this->admin_config->useAdvancedEditor()
99
-            || ! $this->feature->allowed('use_default_ticket_manager')
100
-        ) {
101
-            $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
102
-            $this->_page_config['edit']['qtips'][]       = 'EE_Event_Editor_Tips';
103
-
104
-            $legacy_editor_page_routes = [
105
-                'trash_ticket'    => [
106
-                    'func'       => '_trash_or_restore_ticket',
107
-                    'capability' => 'ee_delete_default_ticket',
108
-                    'obj_id'     => $TKT_ID,
109
-                    'noheader'   => true,
110
-                    'args'       => ['trash' => true],
111
-                ],
112
-                'trash_tickets'   => [
113
-                    'func'       => '_trash_or_restore_ticket',
114
-                    'capability' => 'ee_delete_default_tickets',
115
-                    'noheader'   => true,
116
-                    'args'       => ['trash' => true],
117
-                ],
118
-                'restore_ticket'  => [
119
-                    'func'       => '_trash_or_restore_ticket',
120
-                    'capability' => 'ee_delete_default_ticket',
121
-                    'obj_id'     => $TKT_ID,
122
-                    'noheader'   => true,
123
-                ],
124
-                'restore_tickets' => [
125
-                    'func'       => '_trash_or_restore_ticket',
126
-                    'capability' => 'ee_delete_default_tickets',
127
-                    'noheader'   => true,
128
-                ],
129
-                'delete_ticket'   => [
130
-                    'func'       => '_delete_ticket',
131
-                    'capability' => 'ee_delete_default_ticket',
132
-                    'obj_id'     => $TKT_ID,
133
-                    'noheader'   => true,
134
-                ],
135
-                'delete_tickets'  => [
136
-                    'func'       => '_delete_ticket',
137
-                    'capability' => 'ee_delete_default_tickets',
138
-                    'noheader'   => true,
139
-                ],
140
-            ];
141
-            $new_page_routes           = array_merge($new_page_routes, $legacy_editor_page_routes);
142
-        }
143
-
144
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
145
-        // partial route/config override
146
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
147
-        $this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
148
-
149
-        // add default tickets tab and template settings nav tabs (note union at end)
150
-        $this->_page_config = [
151
-                                  'ticket_list_table' => [
152
-                                      'nav'           => [
153
-                                          'label' => esc_html__('Default Tickets', 'event_espresso'),
154
-                                          'icon'  => 'dashicons-tickets-alt',
155
-                                          'order' => 60,
156
-                                      ],
157
-                                      'list_table'    => 'Tickets_List_Table',
158
-                                      'require_nonce' => false,
159
-                                  ],
160
-                                  'template_settings' => [
161
-                                      'nav'           => [
162
-                                          'label' => esc_html__('Templates', 'event_espresso'),
163
-                                          'icon'  => 'dashicons-layout',
164
-                                          'order' => 30,
165
-                                      ],
166
-                                      'metaboxes'     => array_merge(
167
-                                          ['_publish_post_box'],
168
-                                          $this->_default_espresso_metaboxes
169
-                                      ),
170
-                                      'help_tabs'     => [
171
-                                          'general_settings_templates_help_tab' => [
172
-                                              'title'    => esc_html__('Templates', 'event_espresso'),
173
-                                              'filename' => 'general_settings_templates',
174
-                                          ],
175
-                                      ],
176
-                                      'require_nonce' => false,
177
-                                  ],
178
-                              ] + $this->_page_config;
179
-
180
-        // add filters and actions
181
-        // modifying _views
182
-        add_filter(
183
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
184
-            [$this, 'add_additional_datetime_button'],
185
-            10,
186
-            2
187
-        );
188
-        add_filter(
189
-            'FHEE_event_datetime_metabox_clone_button_template',
190
-            [$this, 'add_datetime_clone_button'],
191
-            10,
192
-            2
193
-        );
194
-        add_filter(
195
-            'FHEE_event_datetime_metabox_timezones_template',
196
-            [$this, 'datetime_timezones_template'],
197
-            10,
198
-            2
199
-        );
200
-        // filters for event list table
201
-        add_filter(
202
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
203
-            [$this, 'extra_list_table_actions'],
204
-            10,
205
-            2
206
-        );
207
-        // legend item
208
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', [$this, 'additional_legend_items']);
209
-        add_action('admin_init', [$this, 'admin_init']);
210
-        // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
211
-        // add_filter('get_sample_permalink_html', [DuplicateEventButton::class, 'addButton'], 8, 2);
212
-        DuplicateEventButton::addEventEditorPermalinkButton(8);
213
-    }
214
-
215
-
216
-    /**
217
-     * admin_init
218
-     */
219
-    public function admin_init()
220
-    {
221
-        EE_Registry::$i18n_js_strings = array_merge(
222
-            EE_Registry::$i18n_js_strings,
223
-            [
224
-                'image_confirm'          => esc_html__(
225
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
226
-                    'event_espresso'
227
-                ),
228
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
229
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
230
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
231
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
232
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
233
-            ]
234
-        );
235
-    }
236
-
237
-
238
-    /**
239
-     * Add per page screen options to the default ticket list table view.
240
-     *
241
-     * @throws InvalidArgumentException
242
-     * @throws InvalidDataTypeException
243
-     * @throws InvalidInterfaceException
244
-     */
245
-    protected function _add_screen_options_ticket_list_table()
246
-    {
247
-        $this->_per_page_screen_option();
248
-    }
249
-
250
-
251
-    /**
252
-     * @param string      $return    the current html
253
-     * @param int         $id        the post id for the page
254
-     * @param string|null $new_title What the title is
255
-     * @param string|null $new_slug  what the slug is
256
-     * @return string
257
-     * @deprecated 5.0.0.p
258
-     */
259
-    public function extra_permalink_field_buttons(
260
-        string $return,
261
-        int $id,
262
-        ?string $new_title,
263
-        ?string $new_slug
264
-    ): string {
265
-        $return = DuplicateEventButton::addButton($return, $id, $new_title, $new_slug);
266
-        return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
267
-    }
268
-
269
-
270
-    /**
271
-     * Set the list table views for the default ticket list table view.
272
-     */
273
-    public function _set_list_table_views_ticket_list_table()
274
-    {
275
-        $this->_views = [
276
-            'all'     => [
277
-                'slug'        => 'all',
278
-                'label'       => esc_html__('All', 'event_espresso'),
279
-                'count'       => 0,
280
-                'bulk_action' => [
281
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
282
-                ],
283
-            ],
284
-            'trashed' => [
285
-                'slug'        => 'trashed',
286
-                'label'       => esc_html__('Trash', 'event_espresso'),
287
-                'count'       => 0,
288
-                'bulk_action' => [
289
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
290
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
291
-                ],
292
-            ],
293
-        ];
294
-    }
295
-
296
-
297
-    /**
298
-     * Enqueue scripts and styles for the event editor.
299
-     */
300
-    public function load_scripts_styles_edit()
301
-    {
302
-        if (! $this->admin_config->useAdvancedEditor()) {
303
-            wp_register_script(
304
-                'ee-event-editor-heartbeat',
305
-                EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
306
-                ['ee_admin_js', 'heartbeat'],
307
-                EVENT_ESPRESSO_VERSION,
308
-                true
309
-            );
310
-            wp_enqueue_script('ee-accounting');
311
-            wp_enqueue_script('ee-event-editor-heartbeat');
312
-        }
313
-        wp_enqueue_script('event_editor_js');
314
-        wp_register_style(
315
-            'event-editor-css',
316
-            EVENTS_ASSETS_URL . 'event-editor.css',
317
-            ['ee-admin-css'],
318
-            EVENT_ESPRESSO_VERSION
319
-        );
320
-        wp_enqueue_style('event-editor-css');
321
-        // styles
322
-        wp_enqueue_style('espresso-ui-theme');
323
-    }
324
-
325
-
326
-    /**
327
-     * Sets the views for the default list table view.
328
-     *
329
-     * @throws EE_Error
330
-     * @throws ReflectionException
331
-     */
332
-    protected function _set_list_table_views_default()
333
-    {
334
-        parent::_set_list_table_views_default();
335
-        $new_views    = [
336
-            'today' => [
337
-                'slug'        => 'today',
338
-                'label'       => esc_html__('Today', 'event_espresso'),
339
-                'count'       => $this->total_events_today(),
340
-                'bulk_action' => [
341
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
342
-                ],
343
-            ],
344
-            'month' => [
345
-                'slug'        => 'month',
346
-                'label'       => esc_html__('This Month', 'event_espresso'),
347
-                'count'       => $this->total_events_this_month(),
348
-                'bulk_action' => [
349
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
350
-                ],
351
-            ],
352
-        ];
353
-        $this->_views = array_merge($this->_views, $new_views);
354
-    }
355
-
356
-
357
-    /**
358
-     * Returns the extra action links for the default list table view.
359
-     *
360
-     * @param array    $action_links
361
-     * @param EE_Event $event
362
-     * @return array
363
-     * @throws EE_Error
364
-     * @throws ReflectionException
365
-     */
366
-    public function extra_list_table_actions(array $action_links, EE_Event $event): array
367
-    {
368
-        if (
369
-        EE_Registry::instance()->CAP->current_user_can(
370
-            'ee_read_registrations',
371
-            'espresso_registrations_reports',
372
-            $event->ID()
373
-        )
374
-        ) {
375
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce(
376
-                [
377
-                    'action' => 'reports',
378
-                    'EVT_ID' => $event->ID(),
379
-                ],
380
-                REG_ADMIN_URL
381
-            );
382
-
383
-            $action_links[] = '
21
+	/**
22
+	 * Extend_Events_Admin_Page constructor.
23
+	 *
24
+	 * @param bool $routing
25
+	 * @throws ReflectionException
26
+	 */
27
+	public function __construct($routing = true)
28
+	{
29
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
30
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
31
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
32
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
33
+		}
34
+		parent::__construct($routing);
35
+		$this->admin_config = $this->loader->getShared('EE_Admin_Config');
36
+	}
37
+
38
+
39
+	protected function _set_page_config()
40
+	{
41
+		parent::_set_page_config();
42
+
43
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
44
+		// is there an evt_id in the request?
45
+		$EVT_ID                                          = $this->request->getRequestParam('EVT_ID', 0, 'int');
46
+		$EVT_ID                                          = $this->request->getRequestParam('post', $EVT_ID, 'int');
47
+		$TKT_ID                                          = $this->request->getRequestParam('TKT_ID', 0, 'int');
48
+		$new_page_routes                                 = [
49
+			'duplicate_event'          => [
50
+				'func'       => '_duplicate_event',
51
+				'capability' => 'ee_edit_event',
52
+				'obj_id'     => $EVT_ID,
53
+				'noheader'   => true,
54
+			],
55
+			'import_page'              => [
56
+				'func'       => '_import_page',
57
+				'capability' => 'import',
58
+			],
59
+			'import'                   => [
60
+				'func'       => '_import_events',
61
+				'capability' => 'import',
62
+				'noheader'   => true,
63
+			],
64
+			'import_events'            => [
65
+				'func'       => '_import_events',
66
+				'capability' => 'import',
67
+				'noheader'   => true,
68
+			],
69
+			'export_events'            => [
70
+				'func'       => '_events_export',
71
+				'capability' => 'export',
72
+				'noheader'   => true,
73
+			],
74
+			'export_categories'        => [
75
+				'func'       => '_categories_export',
76
+				'capability' => 'export',
77
+				'noheader'   => true,
78
+			],
79
+			'sample_export_file'       => [
80
+				'func'       => '_sample_export_file',
81
+				'capability' => 'export',
82
+				'noheader'   => true,
83
+			],
84
+			'update_template_settings' => [
85
+				'func'       => '_update_template_settings',
86
+				'capability' => 'manage_options',
87
+				'noheader'   => true,
88
+			],
89
+			'ticket_list_table'        => [
90
+				'func'       => '_tickets_overview_list_table',
91
+				'capability' => 'ee_read_default_tickets',
92
+			],
93
+		];
94
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
95
+		$this->_page_config['edit']['metaboxes'][]       = '_premium_event_editor_meta_boxes';
96
+		// don't load these meta boxes if using the advanced editor
97
+		if (
98
+			! $this->admin_config->useAdvancedEditor()
99
+			|| ! $this->feature->allowed('use_default_ticket_manager')
100
+		) {
101
+			$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
102
+			$this->_page_config['edit']['qtips'][]       = 'EE_Event_Editor_Tips';
103
+
104
+			$legacy_editor_page_routes = [
105
+				'trash_ticket'    => [
106
+					'func'       => '_trash_or_restore_ticket',
107
+					'capability' => 'ee_delete_default_ticket',
108
+					'obj_id'     => $TKT_ID,
109
+					'noheader'   => true,
110
+					'args'       => ['trash' => true],
111
+				],
112
+				'trash_tickets'   => [
113
+					'func'       => '_trash_or_restore_ticket',
114
+					'capability' => 'ee_delete_default_tickets',
115
+					'noheader'   => true,
116
+					'args'       => ['trash' => true],
117
+				],
118
+				'restore_ticket'  => [
119
+					'func'       => '_trash_or_restore_ticket',
120
+					'capability' => 'ee_delete_default_ticket',
121
+					'obj_id'     => $TKT_ID,
122
+					'noheader'   => true,
123
+				],
124
+				'restore_tickets' => [
125
+					'func'       => '_trash_or_restore_ticket',
126
+					'capability' => 'ee_delete_default_tickets',
127
+					'noheader'   => true,
128
+				],
129
+				'delete_ticket'   => [
130
+					'func'       => '_delete_ticket',
131
+					'capability' => 'ee_delete_default_ticket',
132
+					'obj_id'     => $TKT_ID,
133
+					'noheader'   => true,
134
+				],
135
+				'delete_tickets'  => [
136
+					'func'       => '_delete_ticket',
137
+					'capability' => 'ee_delete_default_tickets',
138
+					'noheader'   => true,
139
+				],
140
+			];
141
+			$new_page_routes           = array_merge($new_page_routes, $legacy_editor_page_routes);
142
+		}
143
+
144
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
145
+		// partial route/config override
146
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
147
+		$this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
148
+
149
+		// add default tickets tab and template settings nav tabs (note union at end)
150
+		$this->_page_config = [
151
+								  'ticket_list_table' => [
152
+									  'nav'           => [
153
+										  'label' => esc_html__('Default Tickets', 'event_espresso'),
154
+										  'icon'  => 'dashicons-tickets-alt',
155
+										  'order' => 60,
156
+									  ],
157
+									  'list_table'    => 'Tickets_List_Table',
158
+									  'require_nonce' => false,
159
+								  ],
160
+								  'template_settings' => [
161
+									  'nav'           => [
162
+										  'label' => esc_html__('Templates', 'event_espresso'),
163
+										  'icon'  => 'dashicons-layout',
164
+										  'order' => 30,
165
+									  ],
166
+									  'metaboxes'     => array_merge(
167
+										  ['_publish_post_box'],
168
+										  $this->_default_espresso_metaboxes
169
+									  ),
170
+									  'help_tabs'     => [
171
+										  'general_settings_templates_help_tab' => [
172
+											  'title'    => esc_html__('Templates', 'event_espresso'),
173
+											  'filename' => 'general_settings_templates',
174
+										  ],
175
+									  ],
176
+									  'require_nonce' => false,
177
+								  ],
178
+							  ] + $this->_page_config;
179
+
180
+		// add filters and actions
181
+		// modifying _views
182
+		add_filter(
183
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
184
+			[$this, 'add_additional_datetime_button'],
185
+			10,
186
+			2
187
+		);
188
+		add_filter(
189
+			'FHEE_event_datetime_metabox_clone_button_template',
190
+			[$this, 'add_datetime_clone_button'],
191
+			10,
192
+			2
193
+		);
194
+		add_filter(
195
+			'FHEE_event_datetime_metabox_timezones_template',
196
+			[$this, 'datetime_timezones_template'],
197
+			10,
198
+			2
199
+		);
200
+		// filters for event list table
201
+		add_filter(
202
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
203
+			[$this, 'extra_list_table_actions'],
204
+			10,
205
+			2
206
+		);
207
+		// legend item
208
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', [$this, 'additional_legend_items']);
209
+		add_action('admin_init', [$this, 'admin_init']);
210
+		// this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
211
+		// add_filter('get_sample_permalink_html', [DuplicateEventButton::class, 'addButton'], 8, 2);
212
+		DuplicateEventButton::addEventEditorPermalinkButton(8);
213
+	}
214
+
215
+
216
+	/**
217
+	 * admin_init
218
+	 */
219
+	public function admin_init()
220
+	{
221
+		EE_Registry::$i18n_js_strings = array_merge(
222
+			EE_Registry::$i18n_js_strings,
223
+			[
224
+				'image_confirm'          => esc_html__(
225
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
226
+					'event_espresso'
227
+				),
228
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
229
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
230
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
231
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
232
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
233
+			]
234
+		);
235
+	}
236
+
237
+
238
+	/**
239
+	 * Add per page screen options to the default ticket list table view.
240
+	 *
241
+	 * @throws InvalidArgumentException
242
+	 * @throws InvalidDataTypeException
243
+	 * @throws InvalidInterfaceException
244
+	 */
245
+	protected function _add_screen_options_ticket_list_table()
246
+	{
247
+		$this->_per_page_screen_option();
248
+	}
249
+
250
+
251
+	/**
252
+	 * @param string      $return    the current html
253
+	 * @param int         $id        the post id for the page
254
+	 * @param string|null $new_title What the title is
255
+	 * @param string|null $new_slug  what the slug is
256
+	 * @return string
257
+	 * @deprecated 5.0.0.p
258
+	 */
259
+	public function extra_permalink_field_buttons(
260
+		string $return,
261
+		int $id,
262
+		?string $new_title,
263
+		?string $new_slug
264
+	): string {
265
+		$return = DuplicateEventButton::addButton($return, $id, $new_title, $new_slug);
266
+		return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
267
+	}
268
+
269
+
270
+	/**
271
+	 * Set the list table views for the default ticket list table view.
272
+	 */
273
+	public function _set_list_table_views_ticket_list_table()
274
+	{
275
+		$this->_views = [
276
+			'all'     => [
277
+				'slug'        => 'all',
278
+				'label'       => esc_html__('All', 'event_espresso'),
279
+				'count'       => 0,
280
+				'bulk_action' => [
281
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
282
+				],
283
+			],
284
+			'trashed' => [
285
+				'slug'        => 'trashed',
286
+				'label'       => esc_html__('Trash', 'event_espresso'),
287
+				'count'       => 0,
288
+				'bulk_action' => [
289
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
290
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
291
+				],
292
+			],
293
+		];
294
+	}
295
+
296
+
297
+	/**
298
+	 * Enqueue scripts and styles for the event editor.
299
+	 */
300
+	public function load_scripts_styles_edit()
301
+	{
302
+		if (! $this->admin_config->useAdvancedEditor()) {
303
+			wp_register_script(
304
+				'ee-event-editor-heartbeat',
305
+				EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
306
+				['ee_admin_js', 'heartbeat'],
307
+				EVENT_ESPRESSO_VERSION,
308
+				true
309
+			);
310
+			wp_enqueue_script('ee-accounting');
311
+			wp_enqueue_script('ee-event-editor-heartbeat');
312
+		}
313
+		wp_enqueue_script('event_editor_js');
314
+		wp_register_style(
315
+			'event-editor-css',
316
+			EVENTS_ASSETS_URL . 'event-editor.css',
317
+			['ee-admin-css'],
318
+			EVENT_ESPRESSO_VERSION
319
+		);
320
+		wp_enqueue_style('event-editor-css');
321
+		// styles
322
+		wp_enqueue_style('espresso-ui-theme');
323
+	}
324
+
325
+
326
+	/**
327
+	 * Sets the views for the default list table view.
328
+	 *
329
+	 * @throws EE_Error
330
+	 * @throws ReflectionException
331
+	 */
332
+	protected function _set_list_table_views_default()
333
+	{
334
+		parent::_set_list_table_views_default();
335
+		$new_views    = [
336
+			'today' => [
337
+				'slug'        => 'today',
338
+				'label'       => esc_html__('Today', 'event_espresso'),
339
+				'count'       => $this->total_events_today(),
340
+				'bulk_action' => [
341
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
342
+				],
343
+			],
344
+			'month' => [
345
+				'slug'        => 'month',
346
+				'label'       => esc_html__('This Month', 'event_espresso'),
347
+				'count'       => $this->total_events_this_month(),
348
+				'bulk_action' => [
349
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
350
+				],
351
+			],
352
+		];
353
+		$this->_views = array_merge($this->_views, $new_views);
354
+	}
355
+
356
+
357
+	/**
358
+	 * Returns the extra action links for the default list table view.
359
+	 *
360
+	 * @param array    $action_links
361
+	 * @param EE_Event $event
362
+	 * @return array
363
+	 * @throws EE_Error
364
+	 * @throws ReflectionException
365
+	 */
366
+	public function extra_list_table_actions(array $action_links, EE_Event $event): array
367
+	{
368
+		if (
369
+		EE_Registry::instance()->CAP->current_user_can(
370
+			'ee_read_registrations',
371
+			'espresso_registrations_reports',
372
+			$event->ID()
373
+		)
374
+		) {
375
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce(
376
+				[
377
+					'action' => 'reports',
378
+					'EVT_ID' => $event->ID(),
379
+				],
380
+				REG_ADMIN_URL
381
+			);
382
+
383
+			$action_links[] = '
384 384
                 <a href="' . $reports_link . '"
385 385
                     aria-label="' . esc_attr__('View Report', 'event_espresso') . '"
386 386
                     class="ee-aria-tooltip button button--icon-only"
387 387
                 >
388 388
                     <span class="dashicons dashicons-chart-bar"></span>
389 389
                 </a>';
390
-        }
391
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
392
-            EE_Registry::instance()->load_helper('MSG_Template');
393
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
394
-                'see_notifications_for',
395
-                null,
396
-                ['EVT_ID' => $event->ID()]
397
-            );
398
-        }
399
-        return $action_links;
400
-    }
401
-
402
-
403
-    /**
404
-     * @param $items
405
-     * @return mixed
406
-     */
407
-    public function additional_legend_items($items)
408
-    {
409
-        if (
410
-        EE_Registry::instance()->CAP->current_user_can(
411
-            'ee_read_registrations',
412
-            'espresso_registrations_reports'
413
-        )
414
-        ) {
415
-            $items['reports'] = [
416
-                'class' => 'dashicons dashicons-chart-bar',
417
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
418
-            ];
419
-        }
420
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
421
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
422
-            // $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
423
-            // (can only use numeric offsets when treating strings as arrays)
424
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
425
-                $items['view_related_messages'] = [
426
-                    'class' => $related_for_icon['css_class'],
427
-                    'desc'  => $related_for_icon['label'],
428
-                ];
429
-            }
430
-        }
431
-        return $items;
432
-    }
433
-
434
-
435
-    /**
436
-     * This is the callback method for the duplicate event route
437
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
438
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
439
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
440
-     * After duplication the redirect is to the new event edit page.
441
-     *
442
-     * @return void
443
-     * @throws EE_Error If EE_Event is not available with given ID
444
-     * @throws ReflectionException
445
-     * @access protected
446
-     */
447
-    protected function _duplicate_event()
448
-    {
449
-        // first make sure the ID for the event is in the request.
450
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
451
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
452
-        if (! $EVT_ID) {
453
-            EE_Error::add_error(
454
-                esc_html__(
455
-                    'In order to duplicate an event an Event ID is required.  None was given.',
456
-                    'event_espresso'
457
-                ),
458
-                __FILE__,
459
-                __FUNCTION__,
460
-                __LINE__
461
-            );
462
-            $this->_redirect_after_action(false, '', '', [], true);
463
-            return;
464
-        }
465
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
466
-        $orig_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
467
-        if (! $orig_event instanceof EE_Event) {
468
-            throw new EE_Error(
469
-                sprintf(
470
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
471
-                    $EVT_ID
472
-                )
473
-            );
474
-        }
475
-        // k now let's clone the $orig_event before getting relations
476
-        $new_event = clone $orig_event;
477
-        // original datetimes
478
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
479
-        // other original relations
480
-        $orig_ven = $orig_event->get_many_related('Venue');
481
-        // reset the ID and modify other details to make it clear this is a dupe
482
-        $new_event->set('EVT_ID', 0);
483
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
484
-        $new_event->set('EVT_name', $new_name);
485
-        $new_event->set(
486
-            'EVT_slug',
487
-            wp_unique_post_slug(
488
-                sanitize_title($orig_event->name()),
489
-                0,
490
-                'publish',
491
-                EspressoPostType::EVENTS,
492
-                0
493
-            )
494
-        );
495
-        $new_event->set('status', 'draft');
496
-        // duplicate discussion settings
497
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
498
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
499
-        // save the new event
500
-        $new_event->save();
501
-        // venues
502
-        foreach ($orig_ven as $ven) {
503
-            $new_event->_add_relation_to($ven, 'Venue');
504
-        }
505
-        $new_event->save();
506
-        // now we need to get the question group relations and handle that
507
-        // first primary question groups
508
-        $orig_primary_qgs = $orig_event->get_many_related(
509
-            'Question_Group',
510
-            [['Event_Question_Group.EQG_primary' => true]]
511
-        );
512
-        if (! empty($orig_primary_qgs)) {
513
-            foreach ($orig_primary_qgs as $obj) {
514
-                if ($obj instanceof EE_Question_Group) {
515
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
516
-                }
517
-            }
518
-        }
519
-        // next additional attendee question groups
520
-        $orig_additional_qgs = $orig_event->get_many_related(
521
-            'Question_Group',
522
-            [['Event_Question_Group.EQG_additional' => true]]
523
-        );
524
-        if (! empty($orig_additional_qgs)) {
525
-            foreach ($orig_additional_qgs as $obj) {
526
-                if ($obj instanceof EE_Question_Group) {
527
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
528
-                }
529
-            }
530
-        }
531
-
532
-        $new_event->save();
533
-
534
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
535
-        $cloned_tickets = [];
536
-        foreach ($orig_datetimes as $orig_dtt) {
537
-            if (! $orig_dtt instanceof EE_Datetime) {
538
-                continue;
539
-            }
540
-            $new_dtt      = clone $orig_dtt;
541
-            $orig_tickets = $orig_dtt->tickets();
542
-            // save new dtt then add to event
543
-            $new_dtt->set('DTT_ID', 0);
544
-            $new_dtt->set('DTT_sold', 0);
545
-            $new_dtt->set_reserved(0);
546
-            $new_dtt->save();
547
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
548
-            $new_event->save();
549
-            // now let's get the ticket relations setup.
550
-            foreach ((array) $orig_tickets as $orig_ticket) {
551
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
552
-                if (! $orig_ticket instanceof EE_Ticket) {
553
-                    continue;
554
-                }
555
-                // is this ticket archived?  If it is then let's skip
556
-                if ($orig_ticket->get('TKT_deleted')) {
557
-                    continue;
558
-                }
559
-                // does this original ticket already exist in the clone_tickets cache?
560
-                //  If so we'll just use the new ticket from it.
561
-                if (isset($cloned_tickets[ $orig_ticket->ID() ])) {
562
-                    $new_ticket = $cloned_tickets[ $orig_ticket->ID() ];
563
-                } else {
564
-                    $new_ticket = clone $orig_ticket;
565
-                    // get relations on the $orig_ticket that we need to set up.
566
-                    $orig_prices = $orig_ticket->prices();
567
-                    $new_ticket->set('TKT_ID', 0);
568
-                    $new_ticket->set('TKT_sold', 0);
569
-                    $new_ticket->set('TKT_reserved', 0);
570
-                    // make sure new ticket has ID.
571
-                    $new_ticket->save();
572
-                    // price relations on new ticket need to be setup.
573
-                    foreach ($orig_prices as $orig_price) {
574
-                        // don't clone default prices, just add a relation
575
-                        if ($orig_price->is_default()) {
576
-                            $new_ticket->_add_relation_to($orig_price, 'Price');
577
-                            $new_ticket->save();
578
-                            continue;
579
-                        }
580
-                        $new_price = clone $orig_price;
581
-                        $new_price->set('PRC_ID', 0);
582
-                        $new_price->save();
583
-                        $new_ticket->_add_relation_to($new_price, 'Price');
584
-                    }
585
-                    $new_ticket->save();
586
-
587
-                    do_action(
588
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
589
-                        $orig_ticket,
590
-                        $new_ticket,
591
-                        $orig_prices,
592
-                        $orig_event,
593
-                        $orig_dtt,
594
-                        $new_dtt
595
-                    );
596
-                    $cloned_tickets[ $orig_ticket->ID() ] = $new_ticket;
597
-                }
598
-                // k now we can add the new ticket as a relation to the new datetime
599
-                // and make sure it's added to our cached $cloned_tickets array
600
-                // for use with later datetimes that have the same ticket.
601
-                $new_dtt->_add_relation_to($new_ticket, 'Ticket');
602
-            }
603
-            $new_dtt->save();
604
-        }
605
-        // clone taxonomy information
606
-        $taxonomies_to_clone_with = apply_filters(
607
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
608
-            ['espresso_event_categories', 'espresso_event_type', 'post_tag']
609
-        );
610
-        // get terms for original event (notice)
611
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
612
-        // loop through terms and add them to new event.
613
-        foreach ($orig_terms as $term) {
614
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
615
-        }
616
-
617
-        // duplicate other core WP_Post items for this event.
618
-        // post thumbnail (feature image).
619
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
620
-        if ($feature_image_id) {
621
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
622
-        }
623
-
624
-        // duplicate page_template setting
625
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
626
-        if ($page_template) {
627
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
628
-        }
629
-
630
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
631
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
632
-        if ($new_event->ID()) {
633
-            $redirect_args = [
634
-                'post'   => $new_event->ID(),
635
-                'action' => 'edit',
636
-            ];
637
-            EE_Error::add_success(
638
-                esc_html__(
639
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
640
-                    'event_espresso'
641
-                )
642
-            );
643
-        } else {
644
-            $redirect_args = [
645
-                'action' => 'default',
646
-            ];
647
-            EE_Error::add_error(
648
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
649
-                __FILE__,
650
-                __FUNCTION__,
651
-                __LINE__
652
-            );
653
-        }
654
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
655
-    }
656
-
657
-
658
-    /**
659
-     * Generates output for the import page.
660
-     *
661
-     * @throws EE_Error
662
-     */
663
-    protected function _import_page()
664
-    {
665
-        $title = esc_html__('Import', 'event_espresso');
666
-        $intro = esc_html__(
667
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
668
-            'event_espresso'
669
-        );
670
-
671
-        $form_url = EVENTS_ADMIN_URL;
672
-        $action   = 'import_events';
673
-        $type     = 'csv';
674
-
675
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
676
-            $title,
677
-            $intro,
678
-            $form_url,
679
-            $action,
680
-            $type
681
-        );
682
-
683
-        $this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
684
-            ['action' => 'sample_export_file'],
685
-            $this->_admin_base_url
686
-        );
687
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
688
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
689
-            $this->_template_args,
690
-            true
691
-        );
692
-        $this->display_admin_page_with_sidebar();
693
-    }
694
-
695
-
696
-    /**
697
-     * _import_events
698
-     * This handles displaying the screen and running imports for importing events.
699
-     *
700
-     * @return void
701
-     * @throws EE_Error
702
-     */
703
-    protected function _import_events()
704
-    {
705
-        require_once(EE_CLASSES . 'EE_Import.class.php');
706
-        $success = EE_Import::instance()->import();
707
-        $this->_redirect_after_action(
708
-            $success,
709
-            esc_html__('Import File', 'event_espresso'),
710
-            'ran',
711
-            ['action' => 'import_page'],
712
-            true
713
-        );
714
-    }
715
-
716
-
717
-    /**
718
-     * _events_export
719
-     * Will export all (or just the given event) to a Excel compatible file.
720
-     *
721
-     * @access protected
722
-     * @return void
723
-     */
724
-    protected function _events_export()
725
-    {
726
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
727
-        $EVT_ID = $this->request->getRequestParam('EVT_IDs', $EVT_ID, 'int');
728
-        $this->request->mergeRequestParams(
729
-            [
730
-                'export' => 'report',
731
-                'action' => 'all_event_data',
732
-                'EVT_ID' => $EVT_ID,
733
-            ]
734
-        );
735
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
736
-            require_once(EE_CLASSES . 'EE_Export.class.php');
737
-            $EE_Export = EE_Export::instance($this->request->requestParams());
738
-            $EE_Export->export();
739
-        }
740
-    }
741
-
742
-
743
-    /**
744
-     * handle category exports()
745
-     *
746
-     * @return void
747
-     */
748
-    protected function _categories_export()
749
-    {
750
-        $EVT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
751
-        $this->request->mergeRequestParams(
752
-            [
753
-                'export' => 'report',
754
-                'action' => 'categories',
755
-                'EVT_ID' => $EVT_ID,
756
-            ]
757
-        );
758
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
759
-            require_once(EE_CLASSES . 'EE_Export.class.php');
760
-            $EE_Export = EE_Export::instance($this->request->requestParams());
761
-            $EE_Export->export();
762
-        }
763
-    }
764
-
765
-
766
-    /**
767
-     * Creates a sample CSV file for importing
768
-     */
769
-    protected function _sample_export_file()
770
-    {
771
-        $EE_Export = EE_Export::instance();
772
-        if ($EE_Export instanceof EE_Export) {
773
-            $EE_Export->export();
774
-        }
775
-    }
776
-
777
-
778
-    /*************        Template Settings        *************/
779
-    /**
780
-     * Generates template settings page output
781
-     *
782
-     * @throws DomainException
783
-     * @throws EE_Error
784
-     * @throws InvalidArgumentException
785
-     * @throws InvalidDataTypeException
786
-     * @throws InvalidInterfaceException
787
-     */
788
-    protected function _template_settings()
789
-    {
790
-        $this->_template_args['values'] = $this->_yes_no_values;
791
-        /**
792
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
793
-         * from General_Settings_Admin_Page to here.
794
-         */
795
-        $this->_template_args = apply_filters(
796
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
797
-            $this->_template_args
798
-        );
799
-        $this->_set_add_edit_form_tags('update_template_settings');
800
-        $this->_set_publish_post_box_vars();
801
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
802
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
803
-            $this->_template_args,
804
-            true
805
-        );
806
-        $this->display_admin_page_with_sidebar();
807
-    }
808
-
809
-
810
-    /**
811
-     * Handler for updating template settings.
812
-     *
813
-     * @throws EE_Error
814
-     */
815
-    protected function _update_template_settings()
816
-    {
817
-        /**
818
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
819
-         * from General_Settings_Admin_Page to here.
820
-         */
821
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
822
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
823
-            EE_Registry::instance()->CFG->template_settings,
824
-            $this->request->requestParams()
825
-        );
826
-        // update custom post type slugs and detect if we need to flush rewrite rules
827
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
828
-
829
-        $event_cpt_slug = $this->request->getRequestParam('event_cpt_slug');
830
-
831
-        EE_Registry::instance()->CFG->core->event_cpt_slug = $event_cpt_slug
832
-            ? EEH_URL::slugify($event_cpt_slug, 'events')
833
-            : EE_Registry::instance()->CFG->core->event_cpt_slug;
834
-
835
-        $what    = esc_html__('Template Settings', 'event_espresso');
836
-        $success = $this->_update_espresso_configuration(
837
-            $what,
838
-            EE_Registry::instance()->CFG->template_settings,
839
-            __FILE__,
840
-            __FUNCTION__,
841
-            __LINE__
842
-        );
843
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
844
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
845
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
846
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
847
-            );
848
-            $rewrite_rules->flush();
849
-        }
850
-        $this->_redirect_after_action($success, $what, 'updated', ['action' => 'template_settings']);
851
-    }
852
-
853
-
854
-    /**
855
-     * _premium_event_editor_meta_boxes
856
-     * add all metaboxes related to the event_editor
857
-     *
858
-     * @access protected
859
-     * @return void
860
-     * @throws EE_Error
861
-     * @throws ReflectionException
862
-     */
863
-    protected function _premium_event_editor_meta_boxes()
864
-    {
865
-        $this->verify_cpt_object();
866
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
867
-        if (
868
-            ! $this->admin_config->useAdvancedEditor()
869
-            || ! $this->feature->allowed('use_reg_options_meta_box')
870
-        ) {
871
-            $this->addMetaBox(
872
-                'espresso_event_editor_event_options',
873
-                esc_html__('Event Registration Options', 'event_espresso'),
874
-                [$this, 'registration_options_meta_box'],
875
-                $this->page_slug,
876
-                'side',
877
-                'core'
878
-            );
879
-        }
880
-    }
881
-
882
-
883
-    /**
884
-     * override caf metabox
885
-     *
886
-     * @return void
887
-     * @throws EE_Error
888
-     * @throws ReflectionException
889
-     */
890
-    public function registration_options_meta_box()
891
-    {
892
-        $yes_no_values = [
893
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
894
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
895
-        ];
896
-
897
-        $default_reg_status_values = EEM_Registration::reg_status_array(
898
-            [
899
-                RegStatus::CANCELLED,
900
-                RegStatus::DECLINED,
901
-                RegStatus::INCOMPLETE,
902
-                RegStatus::WAIT_LIST,
903
-            ],
904
-            true
905
-        );
906
-
907
-        $template_args['active_status']    = $this->_cpt_model_obj->pretty_active_status(false);
908
-        $template_args['_event']           = $this->_cpt_model_obj;
909
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
910
-
911
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
912
-            'default_reg_status',
913
-            $default_reg_status_values,
914
-            $this->_cpt_model_obj->default_registration_status(),
915
-            '',
916
-            'ee-input-width--reg',
917
-            false
918
-        );
919
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
920
-            'display_desc',
921
-            $yes_no_values,
922
-            $this->_cpt_model_obj->display_description()
923
-        );
924
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
925
-            'display_ticket_selector',
926
-            $yes_no_values,
927
-            $this->_cpt_model_obj->display_ticket_selector(),
928
-            '',
929
-            'ee-input-width--small',
930
-            false
931
-        );
932
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
933
-            'EVT_default_registration_status',
934
-            $default_reg_status_values,
935
-            $this->_cpt_model_obj->default_registration_status(),
936
-            '',
937
-            'ee-input-width--reg',
938
-            false
939
-        );
940
-        $template_args['additional_registration_options'] = apply_filters(
941
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
942
-            '',
943
-            $template_args,
944
-            $yes_no_values,
945
-            $default_reg_status_values
946
-        );
947
-        EEH_Template::display_template(
948
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
949
-            $template_args
950
-        );
951
-    }
952
-
953
-
954
-
955
-    /**
956
-     * wp_list_table_mods for caf
957
-     * ============================
958
-     */
959
-
960
-
961
-    /**
962
-     * espresso_event_months_dropdown
963
-     *
964
-     * @deprecatd 5.0.0.p
965
-     * @access public
966
-     * @return string                dropdown listing month/year selections for events.
967
-     * @throws EE_Error
968
-     */
969
-    public function espresso_event_months_dropdown(): string
970
-    {
971
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
972
-        // Note we need to include any other filters that are set!
973
-        return EEH_Form_Fields::generate_event_months_dropdown(
974
-            $this->request->getRequestParam('month_range', ''),
975
-            $this->request->getRequestParam('status', ''),
976
-            $this->request->getRequestParam('EVT_CAT', 0, 'int'),
977
-            $this->request->getRequestParam('active_status', '')
978
-        );
979
-    }
980
-
981
-
982
-    /**
983
-     * returns a list of "active" statuses on the event
984
-     *
985
-     * @deprecatd 5.0.0.p
986
-     * @param string $current_value whatever the current active status is
987
-     * @return string
988
-     */
989
-    public function active_status_dropdown(string $current_value = ''): string
990
-    {
991
-        $select_name = 'active_status';
992
-        $values      = [
993
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
994
-            'active'   => esc_html__('Active', 'event_espresso'),
995
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
996
-            'expired'  => esc_html__('Expired', 'event_espresso'),
997
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
998
-        ];
999
-
1000
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value);
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     * returns a list of "venues"
1006
-     *
1007
-     * @deprecatd 5.0.0.p
1008
-     * @param string $current_value whatever the current active status is
1009
-     * @return string
1010
-     * @throws EE_Error
1011
-     * @throws ReflectionException
1012
-     */
1013
-    protected function venuesDropdown(string $current_value = ''): string
1014
-    {
1015
-        $values = ['' => esc_html__('All Venues', 'event_espresso')];
1016
-        // populate the list of venues.
1017
-        $venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
1018
-
1019
-        foreach ($venues as $venue) {
1020
-            $values[ $venue->ID() ] = $venue->name();
1021
-        }
1022
-
1023
-        return EEH_Form_Fields::select_input('venue', $values, $current_value);
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * output a dropdown of the categories for the category filter on the event admin list table
1029
-     *
1030
-     * @deprecatd 5.0.0.p
1031
-     * @access  public
1032
-     * @return string html
1033
-     * @throws EE_Error
1034
-     * @throws ReflectionException
1035
-     */
1036
-    public function category_dropdown(): string
1037
-    {
1038
-        return EEH_Form_Fields::generate_event_category_dropdown(
1039
-            $this->request->getRequestParam('EVT_CAT', -1, 'int')
1040
-        );
1041
-    }
1042
-
1043
-
1044
-    /**
1045
-     * get total number of events today
1046
-     *
1047
-     * @access public
1048
-     * @return int
1049
-     * @throws EE_Error
1050
-     * @throws InvalidArgumentException
1051
-     * @throws InvalidDataTypeException
1052
-     * @throws InvalidInterfaceException
1053
-     * @throws ReflectionException
1054
-     */
1055
-    public function total_events_today(): int
1056
-    {
1057
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1058
-            'DTT_EVT_start',
1059
-            date('Y-m-d') . ' 00:00:00',
1060
-            'Y-m-d H:i:s',
1061
-            'UTC'
1062
-        );
1063
-        $end   = EEM_Datetime::instance()->convert_datetime_for_query(
1064
-            'DTT_EVT_start',
1065
-            date('Y-m-d') . ' 23:59:59',
1066
-            'Y-m-d H:i:s',
1067
-            'UTC'
1068
-        );
1069
-        $where = [
1070
-            'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1071
-        ];
1072
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1073
-    }
1074
-
1075
-
1076
-    /**
1077
-     * get total number of events this month
1078
-     *
1079
-     * @access public
1080
-     * @return int
1081
-     * @throws EE_Error
1082
-     * @throws InvalidArgumentException
1083
-     * @throws InvalidDataTypeException
1084
-     * @throws InvalidInterfaceException
1085
-     * @throws ReflectionException
1086
-     */
1087
-    public function total_events_this_month(): int
1088
-    {
1089
-        // Dates
1090
-        $this_year_r     = date('Y');
1091
-        $this_month_r    = date('m');
1092
-        $days_this_month = date('t');
1093
-        $start           = EEM_Datetime::instance()->convert_datetime_for_query(
1094
-            'DTT_EVT_start',
1095
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1096
-            'Y-m-d H:i:s',
1097
-            'UTC'
1098
-        );
1099
-        $end             = EEM_Datetime::instance()->convert_datetime_for_query(
1100
-            'DTT_EVT_start',
1101
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1102
-            'Y-m-d H:i:s',
1103
-            'UTC'
1104
-        );
1105
-        $where           = [
1106
-            'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1107
-        ];
1108
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1109
-    }
1110
-
1111
-
1112
-    /** DEFAULT TICKETS STUFF **/
1113
-
1114
-    /**
1115
-     * Output default tickets list table view.
1116
-     *
1117
-     * @throws EE_Error
1118
-     */
1119
-    public function _tickets_overview_list_table()
1120
-    {
1121
-        if (
1122
-            $this->admin_config->useAdvancedEditor()
1123
-            && $this->feature->allowed('use_default_ticket_manager')
1124
-        ) {
1125
-            // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1126
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1127
-                EVENTS_CAF_TEMPLATE_PATH . 'default_tickets_moved_notice.template.php',
1128
-                [],
1129
-                true
1130
-            );
1131
-            $this->display_admin_page_with_no_sidebar();
1132
-        } else {
1133
-            $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1134
-            $this->display_admin_list_table_page_with_no_sidebar();
1135
-        }
1136
-    }
1137
-
1138
-
1139
-    /**
1140
-     * @param int  $per_page
1141
-     * @param bool $count
1142
-     * @param bool $trashed
1143
-     * @return EE_Soft_Delete_Base_Class[]|int
1144
-     * @throws EE_Error
1145
-     * @throws ReflectionException
1146
-     */
1147
-    public function get_default_tickets(int $per_page = 10, bool $count = false, bool $trashed = false)
1148
-    {
1149
-        $orderby = $this->request->getRequestParam('orderby', 'TKT_name');
1150
-        $order   = $this->request->getRequestParam('order', 'ASC');
1151
-        switch ($orderby) {
1152
-            case 'TKT_name':
1153
-                $orderby = ['TKT_name' => $order];
1154
-                break;
1155
-            case 'TKT_price':
1156
-                $orderby = ['TKT_price' => $order];
1157
-                break;
1158
-            case 'TKT_uses':
1159
-                $orderby = ['TKT_uses' => $order];
1160
-                break;
1161
-            case 'TKT_min':
1162
-                $orderby = ['TKT_min' => $order];
1163
-                break;
1164
-            case 'TKT_max':
1165
-                $orderby = ['TKT_max' => $order];
1166
-                break;
1167
-            case 'TKT_qty':
1168
-                $orderby = ['TKT_qty' => $order];
1169
-                break;
1170
-        }
1171
-
1172
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
1173
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1174
-        $offset       = ($current_page - 1) * $per_page;
1175
-
1176
-        $where = [
1177
-            'TKT_is_default' => 1,
1178
-            'TKT_deleted'    => $trashed,
1179
-        ];
1180
-
1181
-        $search_term = $this->request->getRequestParam('s');
1182
-        if ($search_term) {
1183
-            $search_term = '%' . $search_term . '%';
1184
-            $where['OR'] = [
1185
-                'TKT_name'        => ['LIKE', $search_term],
1186
-                'TKT_description' => ['LIKE', $search_term],
1187
-            ];
1188
-        }
1189
-
1190
-        return $count
1191
-            ? EEM_Ticket::instance()->count_deleted_and_undeleted([$where])
1192
-            : EEM_Ticket::instance()->get_all_deleted_and_undeleted(
1193
-                [
1194
-                    $where,
1195
-                    'order_by' => $orderby,
1196
-                    'limit'    => [$offset, $per_page],
1197
-                    'group_by' => 'TKT_ID',
1198
-                ]
1199
-            );
1200
-    }
1201
-
1202
-
1203
-    /**
1204
-     * @param bool $trash
1205
-     * @throws EE_Error
1206
-     * @throws InvalidArgumentException
1207
-     * @throws InvalidDataTypeException
1208
-     * @throws InvalidInterfaceException
1209
-     * @throws ReflectionException
1210
-     */
1211
-    protected function _trash_or_restore_ticket(bool $trash = false)
1212
-    {
1213
-        $success = 1;
1214
-        $TKT     = EEM_Ticket::instance();
1215
-        // checkboxes?
1216
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1217
-        if (! empty($checkboxes)) {
1218
-            // if array has more than one element then success message should be plural
1219
-            $success = count($checkboxes) > 1 ? 2 : 1;
1220
-            // cycle thru the boxes
1221
-            foreach ($checkboxes as $TKT_ID => $value) {
1222
-                if ($trash) {
1223
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1224
-                        $success = 0;
1225
-                    }
1226
-                } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1227
-                    $success = 0;
1228
-                }
1229
-            }
1230
-        } else {
1231
-            // grab single id and trash
1232
-            $TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1233
-            if ($trash) {
1234
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1235
-                    $success = 0;
1236
-                }
1237
-            } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1238
-                $success = 0;
1239
-            }
1240
-        }
1241
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1242
-        $query_args  = [
1243
-            'action' => 'ticket_list_table',
1244
-            'status' => $trash ? '' : 'trashed',
1245
-        ];
1246
-        $this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     * Handles trashing default ticket.
1252
-     *
1253
-     * @throws EE_Error
1254
-     * @throws ReflectionException
1255
-     */
1256
-    protected function _delete_ticket()
1257
-    {
1258
-        $success = 1;
1259
-        // checkboxes?
1260
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1261
-        if (! empty($checkboxes)) {
1262
-            // if array has more than one element then success message should be plural
1263
-            $success = count($checkboxes) > 1 ? 2 : 1;
1264
-            // cycle thru the boxes
1265
-            foreach ($checkboxes as $TKT_ID => $value) {
1266
-                // delete
1267
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1268
-                    $success = 0;
1269
-                }
1270
-            }
1271
-        } else {
1272
-            // grab single id and trash
1273
-            $TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1274
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1275
-                $success = 0;
1276
-            }
1277
-        }
1278
-        $action_desc = 'deleted';
1279
-        $query_args  = [
1280
-            'action' => 'ticket_list_table',
1281
-            'status' => 'trashed',
1282
-        ];
1283
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1284
-        if (
1285
-        EEM_Ticket::instance()->count_deleted_and_undeleted(
1286
-            [['TKT_is_default' => 1]],
1287
-            'TKT_ID',
1288
-            true
1289
-        )
1290
-        ) {
1291
-            $query_args = [];
1292
-        }
1293
-        $this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1294
-    }
1295
-
1296
-
1297
-    /**
1298
-     * @param int $TKT_ID
1299
-     * @return bool|int
1300
-     * @throws EE_Error
1301
-     * @throws ReflectionException
1302
-     */
1303
-    protected function _delete_the_ticket(int $TKT_ID)
1304
-    {
1305
-        $ticket = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1306
-        if (! $ticket instanceof EE_Ticket) {
1307
-            return false;
1308
-        }
1309
-        $ticket->_remove_relations('Datetime');
1310
-        // delete all related prices first
1311
-        $ticket->delete_related_permanently('Price');
1312
-        return $ticket->delete_permanently();
1313
-    }
390
+		}
391
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
392
+			EE_Registry::instance()->load_helper('MSG_Template');
393
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
394
+				'see_notifications_for',
395
+				null,
396
+				['EVT_ID' => $event->ID()]
397
+			);
398
+		}
399
+		return $action_links;
400
+	}
401
+
402
+
403
+	/**
404
+	 * @param $items
405
+	 * @return mixed
406
+	 */
407
+	public function additional_legend_items($items)
408
+	{
409
+		if (
410
+		EE_Registry::instance()->CAP->current_user_can(
411
+			'ee_read_registrations',
412
+			'espresso_registrations_reports'
413
+		)
414
+		) {
415
+			$items['reports'] = [
416
+				'class' => 'dashicons dashicons-chart-bar',
417
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
418
+			];
419
+		}
420
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
421
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
422
+			// $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
423
+			// (can only use numeric offsets when treating strings as arrays)
424
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
425
+				$items['view_related_messages'] = [
426
+					'class' => $related_for_icon['css_class'],
427
+					'desc'  => $related_for_icon['label'],
428
+				];
429
+			}
430
+		}
431
+		return $items;
432
+	}
433
+
434
+
435
+	/**
436
+	 * This is the callback method for the duplicate event route
437
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
438
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
439
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
440
+	 * After duplication the redirect is to the new event edit page.
441
+	 *
442
+	 * @return void
443
+	 * @throws EE_Error If EE_Event is not available with given ID
444
+	 * @throws ReflectionException
445
+	 * @access protected
446
+	 */
447
+	protected function _duplicate_event()
448
+	{
449
+		// first make sure the ID for the event is in the request.
450
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
451
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
452
+		if (! $EVT_ID) {
453
+			EE_Error::add_error(
454
+				esc_html__(
455
+					'In order to duplicate an event an Event ID is required.  None was given.',
456
+					'event_espresso'
457
+				),
458
+				__FILE__,
459
+				__FUNCTION__,
460
+				__LINE__
461
+			);
462
+			$this->_redirect_after_action(false, '', '', [], true);
463
+			return;
464
+		}
465
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
466
+		$orig_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
467
+		if (! $orig_event instanceof EE_Event) {
468
+			throw new EE_Error(
469
+				sprintf(
470
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
471
+					$EVT_ID
472
+				)
473
+			);
474
+		}
475
+		// k now let's clone the $orig_event before getting relations
476
+		$new_event = clone $orig_event;
477
+		// original datetimes
478
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
479
+		// other original relations
480
+		$orig_ven = $orig_event->get_many_related('Venue');
481
+		// reset the ID and modify other details to make it clear this is a dupe
482
+		$new_event->set('EVT_ID', 0);
483
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
484
+		$new_event->set('EVT_name', $new_name);
485
+		$new_event->set(
486
+			'EVT_slug',
487
+			wp_unique_post_slug(
488
+				sanitize_title($orig_event->name()),
489
+				0,
490
+				'publish',
491
+				EspressoPostType::EVENTS,
492
+				0
493
+			)
494
+		);
495
+		$new_event->set('status', 'draft');
496
+		// duplicate discussion settings
497
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
498
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
499
+		// save the new event
500
+		$new_event->save();
501
+		// venues
502
+		foreach ($orig_ven as $ven) {
503
+			$new_event->_add_relation_to($ven, 'Venue');
504
+		}
505
+		$new_event->save();
506
+		// now we need to get the question group relations and handle that
507
+		// first primary question groups
508
+		$orig_primary_qgs = $orig_event->get_many_related(
509
+			'Question_Group',
510
+			[['Event_Question_Group.EQG_primary' => true]]
511
+		);
512
+		if (! empty($orig_primary_qgs)) {
513
+			foreach ($orig_primary_qgs as $obj) {
514
+				if ($obj instanceof EE_Question_Group) {
515
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
516
+				}
517
+			}
518
+		}
519
+		// next additional attendee question groups
520
+		$orig_additional_qgs = $orig_event->get_many_related(
521
+			'Question_Group',
522
+			[['Event_Question_Group.EQG_additional' => true]]
523
+		);
524
+		if (! empty($orig_additional_qgs)) {
525
+			foreach ($orig_additional_qgs as $obj) {
526
+				if ($obj instanceof EE_Question_Group) {
527
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
528
+				}
529
+			}
530
+		}
531
+
532
+		$new_event->save();
533
+
534
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
535
+		$cloned_tickets = [];
536
+		foreach ($orig_datetimes as $orig_dtt) {
537
+			if (! $orig_dtt instanceof EE_Datetime) {
538
+				continue;
539
+			}
540
+			$new_dtt      = clone $orig_dtt;
541
+			$orig_tickets = $orig_dtt->tickets();
542
+			// save new dtt then add to event
543
+			$new_dtt->set('DTT_ID', 0);
544
+			$new_dtt->set('DTT_sold', 0);
545
+			$new_dtt->set_reserved(0);
546
+			$new_dtt->save();
547
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
548
+			$new_event->save();
549
+			// now let's get the ticket relations setup.
550
+			foreach ((array) $orig_tickets as $orig_ticket) {
551
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
552
+				if (! $orig_ticket instanceof EE_Ticket) {
553
+					continue;
554
+				}
555
+				// is this ticket archived?  If it is then let's skip
556
+				if ($orig_ticket->get('TKT_deleted')) {
557
+					continue;
558
+				}
559
+				// does this original ticket already exist in the clone_tickets cache?
560
+				//  If so we'll just use the new ticket from it.
561
+				if (isset($cloned_tickets[ $orig_ticket->ID() ])) {
562
+					$new_ticket = $cloned_tickets[ $orig_ticket->ID() ];
563
+				} else {
564
+					$new_ticket = clone $orig_ticket;
565
+					// get relations on the $orig_ticket that we need to set up.
566
+					$orig_prices = $orig_ticket->prices();
567
+					$new_ticket->set('TKT_ID', 0);
568
+					$new_ticket->set('TKT_sold', 0);
569
+					$new_ticket->set('TKT_reserved', 0);
570
+					// make sure new ticket has ID.
571
+					$new_ticket->save();
572
+					// price relations on new ticket need to be setup.
573
+					foreach ($orig_prices as $orig_price) {
574
+						// don't clone default prices, just add a relation
575
+						if ($orig_price->is_default()) {
576
+							$new_ticket->_add_relation_to($orig_price, 'Price');
577
+							$new_ticket->save();
578
+							continue;
579
+						}
580
+						$new_price = clone $orig_price;
581
+						$new_price->set('PRC_ID', 0);
582
+						$new_price->save();
583
+						$new_ticket->_add_relation_to($new_price, 'Price');
584
+					}
585
+					$new_ticket->save();
586
+
587
+					do_action(
588
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
589
+						$orig_ticket,
590
+						$new_ticket,
591
+						$orig_prices,
592
+						$orig_event,
593
+						$orig_dtt,
594
+						$new_dtt
595
+					);
596
+					$cloned_tickets[ $orig_ticket->ID() ] = $new_ticket;
597
+				}
598
+				// k now we can add the new ticket as a relation to the new datetime
599
+				// and make sure it's added to our cached $cloned_tickets array
600
+				// for use with later datetimes that have the same ticket.
601
+				$new_dtt->_add_relation_to($new_ticket, 'Ticket');
602
+			}
603
+			$new_dtt->save();
604
+		}
605
+		// clone taxonomy information
606
+		$taxonomies_to_clone_with = apply_filters(
607
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
608
+			['espresso_event_categories', 'espresso_event_type', 'post_tag']
609
+		);
610
+		// get terms for original event (notice)
611
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
612
+		// loop through terms and add them to new event.
613
+		foreach ($orig_terms as $term) {
614
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
615
+		}
616
+
617
+		// duplicate other core WP_Post items for this event.
618
+		// post thumbnail (feature image).
619
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
620
+		if ($feature_image_id) {
621
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
622
+		}
623
+
624
+		// duplicate page_template setting
625
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
626
+		if ($page_template) {
627
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
628
+		}
629
+
630
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
631
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
632
+		if ($new_event->ID()) {
633
+			$redirect_args = [
634
+				'post'   => $new_event->ID(),
635
+				'action' => 'edit',
636
+			];
637
+			EE_Error::add_success(
638
+				esc_html__(
639
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
640
+					'event_espresso'
641
+				)
642
+			);
643
+		} else {
644
+			$redirect_args = [
645
+				'action' => 'default',
646
+			];
647
+			EE_Error::add_error(
648
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
649
+				__FILE__,
650
+				__FUNCTION__,
651
+				__LINE__
652
+			);
653
+		}
654
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
655
+	}
656
+
657
+
658
+	/**
659
+	 * Generates output for the import page.
660
+	 *
661
+	 * @throws EE_Error
662
+	 */
663
+	protected function _import_page()
664
+	{
665
+		$title = esc_html__('Import', 'event_espresso');
666
+		$intro = esc_html__(
667
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
668
+			'event_espresso'
669
+		);
670
+
671
+		$form_url = EVENTS_ADMIN_URL;
672
+		$action   = 'import_events';
673
+		$type     = 'csv';
674
+
675
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
676
+			$title,
677
+			$intro,
678
+			$form_url,
679
+			$action,
680
+			$type
681
+		);
682
+
683
+		$this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
684
+			['action' => 'sample_export_file'],
685
+			$this->_admin_base_url
686
+		);
687
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
688
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
689
+			$this->_template_args,
690
+			true
691
+		);
692
+		$this->display_admin_page_with_sidebar();
693
+	}
694
+
695
+
696
+	/**
697
+	 * _import_events
698
+	 * This handles displaying the screen and running imports for importing events.
699
+	 *
700
+	 * @return void
701
+	 * @throws EE_Error
702
+	 */
703
+	protected function _import_events()
704
+	{
705
+		require_once(EE_CLASSES . 'EE_Import.class.php');
706
+		$success = EE_Import::instance()->import();
707
+		$this->_redirect_after_action(
708
+			$success,
709
+			esc_html__('Import File', 'event_espresso'),
710
+			'ran',
711
+			['action' => 'import_page'],
712
+			true
713
+		);
714
+	}
715
+
716
+
717
+	/**
718
+	 * _events_export
719
+	 * Will export all (or just the given event) to a Excel compatible file.
720
+	 *
721
+	 * @access protected
722
+	 * @return void
723
+	 */
724
+	protected function _events_export()
725
+	{
726
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
727
+		$EVT_ID = $this->request->getRequestParam('EVT_IDs', $EVT_ID, 'int');
728
+		$this->request->mergeRequestParams(
729
+			[
730
+				'export' => 'report',
731
+				'action' => 'all_event_data',
732
+				'EVT_ID' => $EVT_ID,
733
+			]
734
+		);
735
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
736
+			require_once(EE_CLASSES . 'EE_Export.class.php');
737
+			$EE_Export = EE_Export::instance($this->request->requestParams());
738
+			$EE_Export->export();
739
+		}
740
+	}
741
+
742
+
743
+	/**
744
+	 * handle category exports()
745
+	 *
746
+	 * @return void
747
+	 */
748
+	protected function _categories_export()
749
+	{
750
+		$EVT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
751
+		$this->request->mergeRequestParams(
752
+			[
753
+				'export' => 'report',
754
+				'action' => 'categories',
755
+				'EVT_ID' => $EVT_ID,
756
+			]
757
+		);
758
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
759
+			require_once(EE_CLASSES . 'EE_Export.class.php');
760
+			$EE_Export = EE_Export::instance($this->request->requestParams());
761
+			$EE_Export->export();
762
+		}
763
+	}
764
+
765
+
766
+	/**
767
+	 * Creates a sample CSV file for importing
768
+	 */
769
+	protected function _sample_export_file()
770
+	{
771
+		$EE_Export = EE_Export::instance();
772
+		if ($EE_Export instanceof EE_Export) {
773
+			$EE_Export->export();
774
+		}
775
+	}
776
+
777
+
778
+	/*************        Template Settings        *************/
779
+	/**
780
+	 * Generates template settings page output
781
+	 *
782
+	 * @throws DomainException
783
+	 * @throws EE_Error
784
+	 * @throws InvalidArgumentException
785
+	 * @throws InvalidDataTypeException
786
+	 * @throws InvalidInterfaceException
787
+	 */
788
+	protected function _template_settings()
789
+	{
790
+		$this->_template_args['values'] = $this->_yes_no_values;
791
+		/**
792
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
793
+		 * from General_Settings_Admin_Page to here.
794
+		 */
795
+		$this->_template_args = apply_filters(
796
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
797
+			$this->_template_args
798
+		);
799
+		$this->_set_add_edit_form_tags('update_template_settings');
800
+		$this->_set_publish_post_box_vars();
801
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
802
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
803
+			$this->_template_args,
804
+			true
805
+		);
806
+		$this->display_admin_page_with_sidebar();
807
+	}
808
+
809
+
810
+	/**
811
+	 * Handler for updating template settings.
812
+	 *
813
+	 * @throws EE_Error
814
+	 */
815
+	protected function _update_template_settings()
816
+	{
817
+		/**
818
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
819
+		 * from General_Settings_Admin_Page to here.
820
+		 */
821
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
822
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
823
+			EE_Registry::instance()->CFG->template_settings,
824
+			$this->request->requestParams()
825
+		);
826
+		// update custom post type slugs and detect if we need to flush rewrite rules
827
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
828
+
829
+		$event_cpt_slug = $this->request->getRequestParam('event_cpt_slug');
830
+
831
+		EE_Registry::instance()->CFG->core->event_cpt_slug = $event_cpt_slug
832
+			? EEH_URL::slugify($event_cpt_slug, 'events')
833
+			: EE_Registry::instance()->CFG->core->event_cpt_slug;
834
+
835
+		$what    = esc_html__('Template Settings', 'event_espresso');
836
+		$success = $this->_update_espresso_configuration(
837
+			$what,
838
+			EE_Registry::instance()->CFG->template_settings,
839
+			__FILE__,
840
+			__FUNCTION__,
841
+			__LINE__
842
+		);
843
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
844
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
845
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
846
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
847
+			);
848
+			$rewrite_rules->flush();
849
+		}
850
+		$this->_redirect_after_action($success, $what, 'updated', ['action' => 'template_settings']);
851
+	}
852
+
853
+
854
+	/**
855
+	 * _premium_event_editor_meta_boxes
856
+	 * add all metaboxes related to the event_editor
857
+	 *
858
+	 * @access protected
859
+	 * @return void
860
+	 * @throws EE_Error
861
+	 * @throws ReflectionException
862
+	 */
863
+	protected function _premium_event_editor_meta_boxes()
864
+	{
865
+		$this->verify_cpt_object();
866
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
867
+		if (
868
+			! $this->admin_config->useAdvancedEditor()
869
+			|| ! $this->feature->allowed('use_reg_options_meta_box')
870
+		) {
871
+			$this->addMetaBox(
872
+				'espresso_event_editor_event_options',
873
+				esc_html__('Event Registration Options', 'event_espresso'),
874
+				[$this, 'registration_options_meta_box'],
875
+				$this->page_slug,
876
+				'side',
877
+				'core'
878
+			);
879
+		}
880
+	}
881
+
882
+
883
+	/**
884
+	 * override caf metabox
885
+	 *
886
+	 * @return void
887
+	 * @throws EE_Error
888
+	 * @throws ReflectionException
889
+	 */
890
+	public function registration_options_meta_box()
891
+	{
892
+		$yes_no_values = [
893
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
894
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
895
+		];
896
+
897
+		$default_reg_status_values = EEM_Registration::reg_status_array(
898
+			[
899
+				RegStatus::CANCELLED,
900
+				RegStatus::DECLINED,
901
+				RegStatus::INCOMPLETE,
902
+				RegStatus::WAIT_LIST,
903
+			],
904
+			true
905
+		);
906
+
907
+		$template_args['active_status']    = $this->_cpt_model_obj->pretty_active_status(false);
908
+		$template_args['_event']           = $this->_cpt_model_obj;
909
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
910
+
911
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
912
+			'default_reg_status',
913
+			$default_reg_status_values,
914
+			$this->_cpt_model_obj->default_registration_status(),
915
+			'',
916
+			'ee-input-width--reg',
917
+			false
918
+		);
919
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
920
+			'display_desc',
921
+			$yes_no_values,
922
+			$this->_cpt_model_obj->display_description()
923
+		);
924
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
925
+			'display_ticket_selector',
926
+			$yes_no_values,
927
+			$this->_cpt_model_obj->display_ticket_selector(),
928
+			'',
929
+			'ee-input-width--small',
930
+			false
931
+		);
932
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
933
+			'EVT_default_registration_status',
934
+			$default_reg_status_values,
935
+			$this->_cpt_model_obj->default_registration_status(),
936
+			'',
937
+			'ee-input-width--reg',
938
+			false
939
+		);
940
+		$template_args['additional_registration_options'] = apply_filters(
941
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
942
+			'',
943
+			$template_args,
944
+			$yes_no_values,
945
+			$default_reg_status_values
946
+		);
947
+		EEH_Template::display_template(
948
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
949
+			$template_args
950
+		);
951
+	}
952
+
953
+
954
+
955
+	/**
956
+	 * wp_list_table_mods for caf
957
+	 * ============================
958
+	 */
959
+
960
+
961
+	/**
962
+	 * espresso_event_months_dropdown
963
+	 *
964
+	 * @deprecatd 5.0.0.p
965
+	 * @access public
966
+	 * @return string                dropdown listing month/year selections for events.
967
+	 * @throws EE_Error
968
+	 */
969
+	public function espresso_event_months_dropdown(): string
970
+	{
971
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
972
+		// Note we need to include any other filters that are set!
973
+		return EEH_Form_Fields::generate_event_months_dropdown(
974
+			$this->request->getRequestParam('month_range', ''),
975
+			$this->request->getRequestParam('status', ''),
976
+			$this->request->getRequestParam('EVT_CAT', 0, 'int'),
977
+			$this->request->getRequestParam('active_status', '')
978
+		);
979
+	}
980
+
981
+
982
+	/**
983
+	 * returns a list of "active" statuses on the event
984
+	 *
985
+	 * @deprecatd 5.0.0.p
986
+	 * @param string $current_value whatever the current active status is
987
+	 * @return string
988
+	 */
989
+	public function active_status_dropdown(string $current_value = ''): string
990
+	{
991
+		$select_name = 'active_status';
992
+		$values      = [
993
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
994
+			'active'   => esc_html__('Active', 'event_espresso'),
995
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
996
+			'expired'  => esc_html__('Expired', 'event_espresso'),
997
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
998
+		];
999
+
1000
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value);
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 * returns a list of "venues"
1006
+	 *
1007
+	 * @deprecatd 5.0.0.p
1008
+	 * @param string $current_value whatever the current active status is
1009
+	 * @return string
1010
+	 * @throws EE_Error
1011
+	 * @throws ReflectionException
1012
+	 */
1013
+	protected function venuesDropdown(string $current_value = ''): string
1014
+	{
1015
+		$values = ['' => esc_html__('All Venues', 'event_espresso')];
1016
+		// populate the list of venues.
1017
+		$venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
1018
+
1019
+		foreach ($venues as $venue) {
1020
+			$values[ $venue->ID() ] = $venue->name();
1021
+		}
1022
+
1023
+		return EEH_Form_Fields::select_input('venue', $values, $current_value);
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * output a dropdown of the categories for the category filter on the event admin list table
1029
+	 *
1030
+	 * @deprecatd 5.0.0.p
1031
+	 * @access  public
1032
+	 * @return string html
1033
+	 * @throws EE_Error
1034
+	 * @throws ReflectionException
1035
+	 */
1036
+	public function category_dropdown(): string
1037
+	{
1038
+		return EEH_Form_Fields::generate_event_category_dropdown(
1039
+			$this->request->getRequestParam('EVT_CAT', -1, 'int')
1040
+		);
1041
+	}
1042
+
1043
+
1044
+	/**
1045
+	 * get total number of events today
1046
+	 *
1047
+	 * @access public
1048
+	 * @return int
1049
+	 * @throws EE_Error
1050
+	 * @throws InvalidArgumentException
1051
+	 * @throws InvalidDataTypeException
1052
+	 * @throws InvalidInterfaceException
1053
+	 * @throws ReflectionException
1054
+	 */
1055
+	public function total_events_today(): int
1056
+	{
1057
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1058
+			'DTT_EVT_start',
1059
+			date('Y-m-d') . ' 00:00:00',
1060
+			'Y-m-d H:i:s',
1061
+			'UTC'
1062
+		);
1063
+		$end   = EEM_Datetime::instance()->convert_datetime_for_query(
1064
+			'DTT_EVT_start',
1065
+			date('Y-m-d') . ' 23:59:59',
1066
+			'Y-m-d H:i:s',
1067
+			'UTC'
1068
+		);
1069
+		$where = [
1070
+			'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1071
+		];
1072
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1073
+	}
1074
+
1075
+
1076
+	/**
1077
+	 * get total number of events this month
1078
+	 *
1079
+	 * @access public
1080
+	 * @return int
1081
+	 * @throws EE_Error
1082
+	 * @throws InvalidArgumentException
1083
+	 * @throws InvalidDataTypeException
1084
+	 * @throws InvalidInterfaceException
1085
+	 * @throws ReflectionException
1086
+	 */
1087
+	public function total_events_this_month(): int
1088
+	{
1089
+		// Dates
1090
+		$this_year_r     = date('Y');
1091
+		$this_month_r    = date('m');
1092
+		$days_this_month = date('t');
1093
+		$start           = EEM_Datetime::instance()->convert_datetime_for_query(
1094
+			'DTT_EVT_start',
1095
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1096
+			'Y-m-d H:i:s',
1097
+			'UTC'
1098
+		);
1099
+		$end             = EEM_Datetime::instance()->convert_datetime_for_query(
1100
+			'DTT_EVT_start',
1101
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1102
+			'Y-m-d H:i:s',
1103
+			'UTC'
1104
+		);
1105
+		$where           = [
1106
+			'Datetime.DTT_EVT_start' => ['BETWEEN', [$start, $end]],
1107
+		];
1108
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
1109
+	}
1110
+
1111
+
1112
+	/** DEFAULT TICKETS STUFF **/
1113
+
1114
+	/**
1115
+	 * Output default tickets list table view.
1116
+	 *
1117
+	 * @throws EE_Error
1118
+	 */
1119
+	public function _tickets_overview_list_table()
1120
+	{
1121
+		if (
1122
+			$this->admin_config->useAdvancedEditor()
1123
+			&& $this->feature->allowed('use_default_ticket_manager')
1124
+		) {
1125
+			// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1126
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1127
+				EVENTS_CAF_TEMPLATE_PATH . 'default_tickets_moved_notice.template.php',
1128
+				[],
1129
+				true
1130
+			);
1131
+			$this->display_admin_page_with_no_sidebar();
1132
+		} else {
1133
+			$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1134
+			$this->display_admin_list_table_page_with_no_sidebar();
1135
+		}
1136
+	}
1137
+
1138
+
1139
+	/**
1140
+	 * @param int  $per_page
1141
+	 * @param bool $count
1142
+	 * @param bool $trashed
1143
+	 * @return EE_Soft_Delete_Base_Class[]|int
1144
+	 * @throws EE_Error
1145
+	 * @throws ReflectionException
1146
+	 */
1147
+	public function get_default_tickets(int $per_page = 10, bool $count = false, bool $trashed = false)
1148
+	{
1149
+		$orderby = $this->request->getRequestParam('orderby', 'TKT_name');
1150
+		$order   = $this->request->getRequestParam('order', 'ASC');
1151
+		switch ($orderby) {
1152
+			case 'TKT_name':
1153
+				$orderby = ['TKT_name' => $order];
1154
+				break;
1155
+			case 'TKT_price':
1156
+				$orderby = ['TKT_price' => $order];
1157
+				break;
1158
+			case 'TKT_uses':
1159
+				$orderby = ['TKT_uses' => $order];
1160
+				break;
1161
+			case 'TKT_min':
1162
+				$orderby = ['TKT_min' => $order];
1163
+				break;
1164
+			case 'TKT_max':
1165
+				$orderby = ['TKT_max' => $order];
1166
+				break;
1167
+			case 'TKT_qty':
1168
+				$orderby = ['TKT_qty' => $order];
1169
+				break;
1170
+		}
1171
+
1172
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
1173
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1174
+		$offset       = ($current_page - 1) * $per_page;
1175
+
1176
+		$where = [
1177
+			'TKT_is_default' => 1,
1178
+			'TKT_deleted'    => $trashed,
1179
+		];
1180
+
1181
+		$search_term = $this->request->getRequestParam('s');
1182
+		if ($search_term) {
1183
+			$search_term = '%' . $search_term . '%';
1184
+			$where['OR'] = [
1185
+				'TKT_name'        => ['LIKE', $search_term],
1186
+				'TKT_description' => ['LIKE', $search_term],
1187
+			];
1188
+		}
1189
+
1190
+		return $count
1191
+			? EEM_Ticket::instance()->count_deleted_and_undeleted([$where])
1192
+			: EEM_Ticket::instance()->get_all_deleted_and_undeleted(
1193
+				[
1194
+					$where,
1195
+					'order_by' => $orderby,
1196
+					'limit'    => [$offset, $per_page],
1197
+					'group_by' => 'TKT_ID',
1198
+				]
1199
+			);
1200
+	}
1201
+
1202
+
1203
+	/**
1204
+	 * @param bool $trash
1205
+	 * @throws EE_Error
1206
+	 * @throws InvalidArgumentException
1207
+	 * @throws InvalidDataTypeException
1208
+	 * @throws InvalidInterfaceException
1209
+	 * @throws ReflectionException
1210
+	 */
1211
+	protected function _trash_or_restore_ticket(bool $trash = false)
1212
+	{
1213
+		$success = 1;
1214
+		$TKT     = EEM_Ticket::instance();
1215
+		// checkboxes?
1216
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1217
+		if (! empty($checkboxes)) {
1218
+			// if array has more than one element then success message should be plural
1219
+			$success = count($checkboxes) > 1 ? 2 : 1;
1220
+			// cycle thru the boxes
1221
+			foreach ($checkboxes as $TKT_ID => $value) {
1222
+				if ($trash) {
1223
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1224
+						$success = 0;
1225
+					}
1226
+				} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1227
+					$success = 0;
1228
+				}
1229
+			}
1230
+		} else {
1231
+			// grab single id and trash
1232
+			$TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1233
+			if ($trash) {
1234
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1235
+					$success = 0;
1236
+				}
1237
+			} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1238
+				$success = 0;
1239
+			}
1240
+		}
1241
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1242
+		$query_args  = [
1243
+			'action' => 'ticket_list_table',
1244
+			'status' => $trash ? '' : 'trashed',
1245
+		];
1246
+		$this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 * Handles trashing default ticket.
1252
+	 *
1253
+	 * @throws EE_Error
1254
+	 * @throws ReflectionException
1255
+	 */
1256
+	protected function _delete_ticket()
1257
+	{
1258
+		$success = 1;
1259
+		// checkboxes?
1260
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
1261
+		if (! empty($checkboxes)) {
1262
+			// if array has more than one element then success message should be plural
1263
+			$success = count($checkboxes) > 1 ? 2 : 1;
1264
+			// cycle thru the boxes
1265
+			foreach ($checkboxes as $TKT_ID => $value) {
1266
+				// delete
1267
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1268
+					$success = 0;
1269
+				}
1270
+			}
1271
+		} else {
1272
+			// grab single id and trash
1273
+			$TKT_ID = $this->request->getRequestParam('TKT_ID', 0, 'int');
1274
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1275
+				$success = 0;
1276
+			}
1277
+		}
1278
+		$action_desc = 'deleted';
1279
+		$query_args  = [
1280
+			'action' => 'ticket_list_table',
1281
+			'status' => 'trashed',
1282
+		];
1283
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1284
+		if (
1285
+		EEM_Ticket::instance()->count_deleted_and_undeleted(
1286
+			[['TKT_is_default' => 1]],
1287
+			'TKT_ID',
1288
+			true
1289
+		)
1290
+		) {
1291
+			$query_args = [];
1292
+		}
1293
+		$this->_redirect_after_action($success, esc_html__('Tickets', 'event_espresso'), $action_desc, $query_args);
1294
+	}
1295
+
1296
+
1297
+	/**
1298
+	 * @param int $TKT_ID
1299
+	 * @return bool|int
1300
+	 * @throws EE_Error
1301
+	 * @throws ReflectionException
1302
+	 */
1303
+	protected function _delete_the_ticket(int $TKT_ID)
1304
+	{
1305
+		$ticket = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1306
+		if (! $ticket instanceof EE_Ticket) {
1307
+			return false;
1308
+		}
1309
+		$ticket->_remove_relations('Datetime');
1310
+		// delete all related prices first
1311
+		$ticket->delete_related_permanently('Price');
1312
+		return $ticket->delete_permanently();
1313
+	}
1314 1314
 }
Please login to merge, or discard this patch.
admin/extend/events/espresso_events_Events_Hooks_Extend.class.php 1 patch
Indentation   +2313 added lines, -2313 removed lines patch added patch discarded remove patch
@@ -16,2331 +16,2331 @@
 block discarded – undo
16 16
  */
17 17
 class espresso_events_Events_Hooks_Extend extends EE_Admin_Hooks
18 18
 {
19
-    /**
20
-     * This property is just used to hold the status of whether an event is currently being
21
-     * created (true) or edited (false)
22
-     *
23
-     * @access protected
24
-     * @var bool
25
-     */
26
-    protected $_is_creating_event;
27
-
28
-    /**
29
-     * Used to contain the format strings for date and time that will be used for php date and
30
-     * time.
31
-     * Is set in the _set_hooks_properties() method.
32
-     *
33
-     * @var array
34
-     */
35
-    protected $_date_format_strings;
36
-
37
-    /**
38
-     * @var string $_date_time_format
39
-     */
40
-    protected $_date_time_format;
41
-
42
-
43
-    /**
44
-     * @throws InvalidArgumentException
45
-     * @throws InvalidInterfaceException
46
-     * @throws InvalidDataTypeException
47
-     */
48
-    protected function _set_hooks_properties()
49
-    {
50
-        $this->_name = 'events';
51
-        // capability check
52
-        if (
53
-            $this->_adminpage_obj->adminConfig()->useAdvancedEditor()
54
-            || ! EE_Registry::instance()->CAP->current_user_can(
55
-                'ee_read_default_prices',
56
-                'advanced_ticket_datetime_metabox'
57
-            )
58
-        ) {
59
-            $this->_metaboxes      = [];
60
-            $this->_scripts_styles = [];
61
-            return;
62
-        }
63
-        $this->_setup_metaboxes();
64
-        $this->_set_date_time_formats();
65
-        $this->_validate_format_strings();
66
-        $this->_set_scripts_styles();
67
-        add_filter(
68
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
-            [$this, 'caf_updates']
70
-        );
71
-    }
72
-
73
-
74
-    /**
75
-     * @return void
76
-     */
77
-    protected function _setup_metaboxes()
78
-    {
79
-        // if we were going to add our own metaboxes we'd use the below.
80
-        $this->_metaboxes        = [
81
-            0 => [
82
-                'page_route' => ['edit', 'create_new'],
83
-                'func'       => [$this, 'pricing_metabox'],
84
-                'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
85
-                'priority'   => 'high',
86
-                'context'    => 'normal',
87
-            ],
88
-        ];
89
-        $this->_remove_metaboxes = [
90
-            0 => [
91
-                'page_route' => ['edit', 'create_new'],
92
-                'id'         => 'espresso_event_editor_tickets',
93
-                'context'    => 'normal',
94
-            ],
95
-        ];
96
-    }
97
-
98
-
99
-    /**
100
-     * @return void
101
-     */
102
-    protected function _set_date_time_formats()
103
-    {
104
-        /**
105
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
106
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
107
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
108
-         *
109
-         * @since 4.6.7
110
-         * @var array  Expected an array returned with 'date' and 'time' keys.
111
-         */
112
-        $this->_date_format_strings = apply_filters(
113
-            'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
114
-            [
115
-                'date' => 'Y-m-d',
116
-                'time' => 'h:i a',
117
-            ]
118
-        );
119
-        // validate
120
-        $this->_date_format_strings['date'] = $this->_date_format_strings['date'] ?? '';
121
-        $this->_date_format_strings['time'] = $this->_date_format_strings['time'] ?? '';
122
-
123
-        $this->_date_time_format = $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'];
124
-    }
125
-
126
-
127
-    /**
128
-     * @return void
129
-     */
130
-    protected function _validate_format_strings()
131
-    {
132
-        // validate format strings
133
-        $format_validation = EEH_DTT_Helper::validate_format_string(
134
-            $this->_date_time_format
135
-        );
136
-        if (is_array($format_validation)) {
137
-            $msg = '<p>';
138
-            $msg .= sprintf(
139
-                esc_html__(
140
-                    'The format "%s" was likely added via a filter and is invalid for the following reasons:',
141
-                    'event_espresso'
142
-                ),
143
-                $this->_date_time_format
144
-            );
145
-            $msg .= '</p><ul>';
146
-            foreach ($format_validation as $error) {
147
-                $msg .= '<li>' . $error . '</li>';
148
-            }
149
-            $msg .= '</ul><p>';
150
-            $msg .= sprintf(
151
-                esc_html__(
152
-                    '%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
153
-                    'event_espresso'
154
-                ),
155
-                '<span style="color:#D54E21;">',
156
-                '</span>'
157
-            );
158
-            $msg .= '</p>';
159
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
160
-            $this->_date_format_strings = [
161
-                'date' => 'Y-m-d',
162
-                'time' => 'h:i a',
163
-            ];
164
-        }
165
-    }
166
-
167
-
168
-    /**
169
-     * @return void
170
-     */
171
-    protected function _set_scripts_styles()
172
-    {
173
-        $this->_scripts_styles = [
174
-            'registers'   => [
175
-                'ee-tickets-datetimes-css' => [
176
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
177
-                    'type' => 'css',
178
-                ],
179
-                'ee-dtt-ticket-metabox'    => [
180
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
181
-                    'depends' => ['ee-datepicker', 'ee-dialog', 'underscore'],
182
-                ],
183
-            ],
184
-            'deregisters' => [
185
-                'event-editor-css'       => ['type' => 'css'],
186
-                'event-datetime-metabox' => ['type' => 'js'],
187
-            ],
188
-            'enqueues'    => [
189
-                'ee-tickets-datetimes-css' => ['edit', 'create_new'],
190
-                'ee-dtt-ticket-metabox'    => ['edit', 'create_new'],
191
-            ],
192
-            'localize'    => [
193
-                'ee-dtt-ticket-metabox' => [
194
-                    'DTT_TRASH_BLOCK'       => [
195
-                        'main_warning'            => esc_html__(
196
-                            'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
197
-                            'event_espresso'
198
-                        ),
199
-                        'after_warning'           => esc_html__(
200
-                            'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
201
-                            'event_espresso'
202
-                        ),
203
-                        'cancel_button'           => '
19
+	/**
20
+	 * This property is just used to hold the status of whether an event is currently being
21
+	 * created (true) or edited (false)
22
+	 *
23
+	 * @access protected
24
+	 * @var bool
25
+	 */
26
+	protected $_is_creating_event;
27
+
28
+	/**
29
+	 * Used to contain the format strings for date and time that will be used for php date and
30
+	 * time.
31
+	 * Is set in the _set_hooks_properties() method.
32
+	 *
33
+	 * @var array
34
+	 */
35
+	protected $_date_format_strings;
36
+
37
+	/**
38
+	 * @var string $_date_time_format
39
+	 */
40
+	protected $_date_time_format;
41
+
42
+
43
+	/**
44
+	 * @throws InvalidArgumentException
45
+	 * @throws InvalidInterfaceException
46
+	 * @throws InvalidDataTypeException
47
+	 */
48
+	protected function _set_hooks_properties()
49
+	{
50
+		$this->_name = 'events';
51
+		// capability check
52
+		if (
53
+			$this->_adminpage_obj->adminConfig()->useAdvancedEditor()
54
+			|| ! EE_Registry::instance()->CAP->current_user_can(
55
+				'ee_read_default_prices',
56
+				'advanced_ticket_datetime_metabox'
57
+			)
58
+		) {
59
+			$this->_metaboxes      = [];
60
+			$this->_scripts_styles = [];
61
+			return;
62
+		}
63
+		$this->_setup_metaboxes();
64
+		$this->_set_date_time_formats();
65
+		$this->_validate_format_strings();
66
+		$this->_set_scripts_styles();
67
+		add_filter(
68
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
+			[$this, 'caf_updates']
70
+		);
71
+	}
72
+
73
+
74
+	/**
75
+	 * @return void
76
+	 */
77
+	protected function _setup_metaboxes()
78
+	{
79
+		// if we were going to add our own metaboxes we'd use the below.
80
+		$this->_metaboxes        = [
81
+			0 => [
82
+				'page_route' => ['edit', 'create_new'],
83
+				'func'       => [$this, 'pricing_metabox'],
84
+				'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
85
+				'priority'   => 'high',
86
+				'context'    => 'normal',
87
+			],
88
+		];
89
+		$this->_remove_metaboxes = [
90
+			0 => [
91
+				'page_route' => ['edit', 'create_new'],
92
+				'id'         => 'espresso_event_editor_tickets',
93
+				'context'    => 'normal',
94
+			],
95
+		];
96
+	}
97
+
98
+
99
+	/**
100
+	 * @return void
101
+	 */
102
+	protected function _set_date_time_formats()
103
+	{
104
+		/**
105
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
106
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
107
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
108
+		 *
109
+		 * @since 4.6.7
110
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
111
+		 */
112
+		$this->_date_format_strings = apply_filters(
113
+			'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
114
+			[
115
+				'date' => 'Y-m-d',
116
+				'time' => 'h:i a',
117
+			]
118
+		);
119
+		// validate
120
+		$this->_date_format_strings['date'] = $this->_date_format_strings['date'] ?? '';
121
+		$this->_date_format_strings['time'] = $this->_date_format_strings['time'] ?? '';
122
+
123
+		$this->_date_time_format = $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'];
124
+	}
125
+
126
+
127
+	/**
128
+	 * @return void
129
+	 */
130
+	protected function _validate_format_strings()
131
+	{
132
+		// validate format strings
133
+		$format_validation = EEH_DTT_Helper::validate_format_string(
134
+			$this->_date_time_format
135
+		);
136
+		if (is_array($format_validation)) {
137
+			$msg = '<p>';
138
+			$msg .= sprintf(
139
+				esc_html__(
140
+					'The format "%s" was likely added via a filter and is invalid for the following reasons:',
141
+					'event_espresso'
142
+				),
143
+				$this->_date_time_format
144
+			);
145
+			$msg .= '</p><ul>';
146
+			foreach ($format_validation as $error) {
147
+				$msg .= '<li>' . $error . '</li>';
148
+			}
149
+			$msg .= '</ul><p>';
150
+			$msg .= sprintf(
151
+				esc_html__(
152
+					'%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
153
+					'event_espresso'
154
+				),
155
+				'<span style="color:#D54E21;">',
156
+				'</span>'
157
+			);
158
+			$msg .= '</p>';
159
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
160
+			$this->_date_format_strings = [
161
+				'date' => 'Y-m-d',
162
+				'time' => 'h:i a',
163
+			];
164
+		}
165
+	}
166
+
167
+
168
+	/**
169
+	 * @return void
170
+	 */
171
+	protected function _set_scripts_styles()
172
+	{
173
+		$this->_scripts_styles = [
174
+			'registers'   => [
175
+				'ee-tickets-datetimes-css' => [
176
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
177
+					'type' => 'css',
178
+				],
179
+				'ee-dtt-ticket-metabox'    => [
180
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
181
+					'depends' => ['ee-datepicker', 'ee-dialog', 'underscore'],
182
+				],
183
+			],
184
+			'deregisters' => [
185
+				'event-editor-css'       => ['type' => 'css'],
186
+				'event-datetime-metabox' => ['type' => 'js'],
187
+			],
188
+			'enqueues'    => [
189
+				'ee-tickets-datetimes-css' => ['edit', 'create_new'],
190
+				'ee-dtt-ticket-metabox'    => ['edit', 'create_new'],
191
+			],
192
+			'localize'    => [
193
+				'ee-dtt-ticket-metabox' => [
194
+					'DTT_TRASH_BLOCK'       => [
195
+						'main_warning'            => esc_html__(
196
+							'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
197
+							'event_espresso'
198
+						),
199
+						'after_warning'           => esc_html__(
200
+							'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
201
+							'event_espresso'
202
+						),
203
+						'cancel_button'           => '
204 204
                             <button class="button--secondary ee-modal-cancel">
205 205
                                 ' . esc_html__('Cancel', 'event_espresso') . '
206 206
                             </button>',
207
-                        'close_button'            => '
207
+						'close_button'            => '
208 208
                             <button class="button--secondary ee-modal-cancel">
209 209
                                 ' . esc_html__('Close', 'event_espresso') . '
210 210
                             </button>',
211
-                        'single_warning_from_tkt' => esc_html__(
212
-                            'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
213
-                            'event_espresso'
214
-                        ),
215
-                        'single_warning_from_dtt' => esc_html__(
216
-                            'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
217
-                            'event_espresso'
218
-                        ),
219
-                        'dismiss_button'          => '
211
+						'single_warning_from_tkt' => esc_html__(
212
+							'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
213
+							'event_espresso'
214
+						),
215
+						'single_warning_from_dtt' => esc_html__(
216
+							'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
217
+							'event_espresso'
218
+						),
219
+						'dismiss_button'          => '
220 220
                             <button class="button--secondary ee-modal-cancel">
221 221
                                 ' . esc_html__('Dismiss', 'event_espresso') . '
222 222
                             </button>',
223
-                    ],
224
-                    'DTT_ERROR_MSG'         => [
225
-                        'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
226
-                        'dismiss_button' => '
223
+					],
224
+					'DTT_ERROR_MSG'         => [
225
+						'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
226
+						'dismiss_button' => '
227 227
                             <div class="save-cancel-button-container">
228 228
                                 <button class="button--secondary ee-modal-cancel">
229 229
                                     ' . esc_html__('Dismiss', 'event_espresso') . '
230 230
                                 </button>
231 231
                             </div>',
232
-                    ],
233
-                    'DTT_OVERSELL_WARNING'  => [
234
-                        'datetime_ticket' => esc_html__(
235
-                            'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
236
-                            'event_espresso'
237
-                        ),
238
-                        'ticket_datetime' => esc_html__(
239
-                            'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
240
-                            'event_espresso'
241
-                        ),
242
-                    ],
243
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
244
-                        $this->_date_format_strings['date'],
245
-                        $this->_date_format_strings['time']
246
-                    ),
247
-                    'DTT_START_OF_WEEK'     => ['dayValue' => (int) get_option('start_of_week')],
248
-                ],
249
-            ],
250
-        ];
251
-    }
252
-
253
-
254
-    /**
255
-     * @param array $update_callbacks
256
-     * @return array
257
-     */
258
-    public function caf_updates(array $update_callbacks): array
259
-    {
260
-        unset($update_callbacks['_default_tickets_update']);
261
-        $update_callbacks['datetime_and_tickets_caf_update'] = [$this, 'datetime_and_tickets_caf_update'];
262
-        return $update_callbacks;
263
-    }
264
-
265
-
266
-    /**
267
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
268
-     *
269
-     * @param EE_Event $event The Event object we're attaching data to
270
-     * @param array    $data  The request data from the form
271
-     * @throws ReflectionException
272
-     * @throws Exception
273
-     * @throws InvalidInterfaceException
274
-     * @throws InvalidDataTypeException
275
-     * @throws EE_Error
276
-     * @throws InvalidArgumentException
277
-     */
278
-    public function datetime_and_tickets_caf_update(EE_Event $event, array $data)
279
-    {
280
-        // first we need to start with datetimes cause they are the "root" items attached to events.
281
-        $saved_datetimes = $this->_update_datetimes($event, $data);
282
-        // next tackle the tickets (and prices?)
283
-        $this->_update_tickets($event, $saved_datetimes, $data);
284
-    }
285
-
286
-
287
-    /**
288
-     * update event_datetimes
289
-     *
290
-     * @param EE_Event $event Event being updated
291
-     * @param array    $data  the request data from the form
292
-     * @return EE_Datetime[]
293
-     * @throws Exception
294
-     * @throws ReflectionException
295
-     * @throws InvalidInterfaceException
296
-     * @throws InvalidDataTypeException
297
-     * @throws InvalidArgumentException
298
-     * @throws EE_Error
299
-     */
300
-    protected function _update_datetimes(EE_Event $event, array $data): array
301
-    {
302
-        $saved_datetime_ids  = [];
303
-        $saved_datetime_objs = [];
304
-        $timezone            = $data['timezone_string'] ?? null;
305
-        $datetime_model      = EEM_Datetime::instance($timezone);
306
-
307
-        if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
308
-            throw new InvalidArgumentException(
309
-                esc_html__(
310
-                    'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
311
-                    'event_espresso'
312
-                )
313
-            );
314
-        }
315
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
316
-            // trim all values to ensure any excess whitespace is removed.
317
-            $datetime_data = array_map(
318
-                function ($datetime_data) {
319
-                    return is_array($datetime_data)
320
-                        ? $datetime_data
321
-                        : trim($datetime_data);
322
-                },
323
-                $datetime_data
324
-            );
325
-
326
-            $datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
327
-                                            && ! empty($datetime_data['DTT_EVT_end'])
328
-                ? $datetime_data['DTT_EVT_end']
329
-                : $datetime_data['DTT_EVT_start'];
330
-            $datetime_values              = [
331
-                'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
332
-                    ? $datetime_data['DTT_ID']
333
-                    : null,
334
-                'DTT_name'        => ! empty($datetime_data['DTT_name'])
335
-                    ? $datetime_data['DTT_name']
336
-                    : '',
337
-                'DTT_description' => ! empty($datetime_data['DTT_description'])
338
-                    ? $datetime_data['DTT_description']
339
-                    : '',
340
-                'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
341
-                'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
342
-                'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
343
-                    ? EE_INF
344
-                    : $datetime_data['DTT_reg_limit'],
345
-                'DTT_order'       => ! isset($datetime_data['DTT_order'])
346
-                    ? $row
347
-                    : $datetime_data['DTT_order'],
348
-            ];
349
-
350
-            // if we have an id then let's get existing object first and then set the new values.
351
-            // Otherwise we instantiate a new object for save.
352
-            if (! empty($datetime_data['DTT_ID'])) {
353
-                $datetime = EE_Registry::instance()
354
-                                       ->load_model('Datetime', [$timezone])
355
-                                       ->get_one_by_ID($datetime_data['DTT_ID']);
356
-                // set date and time format according to what is set in this class.
357
-                $datetime->set_date_format($this->_date_format_strings['date']);
358
-                $datetime->set_time_format($this->_date_format_strings['time']);
359
-                foreach ($datetime_values as $field => $value) {
360
-                    $datetime->set($field, $value);
361
-                }
362
-
363
-                // make sure the $datetime_id here is saved just in case
364
-                // after the add_relation_to() the autosave replaces it.
365
-                // We need to do this so we dont' TRASH the parent DTT.
366
-                // (save the ID for both key and value to avoid duplications)
367
-                $saved_datetime_ids[ $datetime->ID() ] = $datetime->ID();
368
-            } else {
369
-                $datetime = EE_Datetime::new_instance(
370
-                    $datetime_values,
371
-                    $timezone,
372
-                    [$this->_date_format_strings['date'], $this->_date_format_strings['time']]
373
-                );
374
-                foreach ($datetime_values as $field => $value) {
375
-                    $datetime->set($field, $value);
376
-                }
377
-            }
378
-            $datetime->save();
379
-            do_action(
380
-                'AHEE__espresso_events_Pricing_Hooks___update_datetimes_after_save',
381
-                $datetime,
382
-                $row,
383
-                $datetime_data,
384
-                $data
385
-            );
386
-            $datetime = $event->_add_relation_to($datetime, 'Datetime');
387
-            // before going any further make sure our dates are setup correctly
388
-            // so that the end date is always equal or greater than the start date.
389
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
390
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
391
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
392
-                $datetime->save();
393
-            }
394
-            // now we have to make sure we add the new DTT_ID to the $saved_datetime_ids array
395
-            // because it is possible there was a new one created for the autosave.
396
-            // (save the ID for both key and value to avoid duplications)
397
-            $DTT_ID                        = $datetime->ID();
398
-            $saved_datetime_ids[ $DTT_ID ] = $DTT_ID;
399
-            $saved_datetime_objs[ $row ]   = $datetime;
400
-            // @todo if ANY of these updates fail then we want the appropriate global error message.
401
-        }
402
-        $event->save();
403
-        // now we need to REMOVE any datetimes that got deleted.
404
-        // Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
405
-        // So its safe to permanently delete at this point.
406
-        $old_datetimes = explode(',', $data['datetime_IDs']);
407
-        $old_datetimes = $old_datetimes[0] === ''
408
-            ? []
409
-            : $old_datetimes;
410
-        if (is_array($old_datetimes)) {
411
-            $datetimes_to_delete = array_diff($old_datetimes, $saved_datetime_ids);
412
-            foreach ($datetimes_to_delete as $id) {
413
-                $id = absint($id);
414
-                if (empty($id)) {
415
-                    continue;
416
-                }
417
-                $dtt_to_remove = $datetime_model->get_one_by_ID($id);
418
-                // remove tkt relationships.
419
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
420
-                foreach ($related_tickets as $ticket) {
421
-                    $dtt_to_remove->_remove_relation_to($ticket, 'Ticket');
422
-                }
423
-                $event->_remove_relation_to($id, 'Datetime');
424
-                $dtt_to_remove->refresh_cache_of_related_objects();
425
-            }
426
-        }
427
-        return $saved_datetime_objs;
428
-    }
429
-
430
-
431
-    /**
432
-     * update tickets
433
-     *
434
-     * @param EE_Event      $event           Event object being updated
435
-     * @param EE_Datetime[] $saved_datetimes an array of datetime ids being updated
436
-     * @param array         $data            incoming request data
437
-     * @return EE_Ticket[]
438
-     * @throws Exception
439
-     * @throws ReflectionException
440
-     * @throws InvalidInterfaceException
441
-     * @throws InvalidDataTypeException
442
-     * @throws InvalidArgumentException
443
-     * @throws EE_Error
444
-     */
445
-    protected function _update_tickets(EE_Event $event, array $saved_datetimes, array $data): array
446
-    {
447
-        $new_ticket = null;
448
-        // stripslashes because WP filtered the $_POST ($data) array to add slashes
449
-        $data         = stripslashes_deep($data);
450
-        $timezone     = $data['timezone_string'] ?? null;
451
-        $ticket_model = EEM_Ticket::instance($timezone);
452
-
453
-        $saved_tickets = [];
454
-        $old_tickets   = isset($data['ticket_IDs'])
455
-            ? explode(',', $data['ticket_IDs'])
456
-            : [];
457
-        if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
458
-            throw new InvalidArgumentException(
459
-                esc_html__(
460
-                    'The "edit_tickets" array is invalid therefore the event can not be updated.',
461
-                    'event_espresso'
462
-                )
463
-            );
464
-        }
465
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
466
-            $update_prices = $create_new_TKT = false;
467
-            // figure out what datetimes were added to the ticket
468
-            // and what datetimes were removed from the ticket in the session.
469
-            $starting_ticket_datetime_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
470
-            $ticket_datetime_rows          = explode(',', $data['ticket_datetime_rows'][ $row ]);
471
-            $datetimes_added               = array_diff($ticket_datetime_rows, $starting_ticket_datetime_rows);
472
-            $datetimes_removed             = array_diff($starting_ticket_datetime_rows, $ticket_datetime_rows);
473
-            // trim inputs to ensure any excess whitespace is removed.
474
-            $ticket_data = array_map(
475
-                function ($ticket_data) {
476
-                    return is_array($ticket_data)
477
-                        ? $ticket_data
478
-                        : trim($ticket_data);
479
-                },
480
-                $ticket_data
481
-            );
482
-            // note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
483
-            // because we're doing calculations prior to using the models.
484
-            // note incoming ['TKT_price'] value is already in standard notation (via js).
485
-            $ticket_price = isset($ticket_data['TKT_price'])
486
-                ? round((float) $ticket_data['TKT_price'], 3)
487
-                : 0;
488
-            // note incoming base price needs converted from localized value.
489
-            $base_price = isset($ticket_data['TKT_base_price'])
490
-                ? EEH_Money::convert_to_float_from_localized_money($ticket_data['TKT_base_price'])
491
-                : 0;
492
-            // if ticket price == 0 and $base_price != 0 then ticket price == base_price
493
-            $ticket_price  = $ticket_price === 0 && $base_price !== 0
494
-                ? $base_price
495
-                : $ticket_price;
496
-            $base_price_id = $ticket_data['TKT_base_price_ID'] ?? 0;
497
-            $price_rows    = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
498
-                ? $data['edit_prices'][ $row ]
499
-                : [];
500
-            $now           = null;
501
-            if (empty($ticket_data['TKT_start_date'])) {
502
-                // lets' use now in the set timezone.
503
-                $now                           = new DateTime('now', new DateTimeZone($event->get_timezone()));
504
-                $ticket_data['TKT_start_date'] = $now->format($this->_date_time_format);
505
-            }
506
-            if (empty($ticket_data['TKT_end_date'])) {
507
-                /**
508
-                 * set the TKT_end_date to the first datetime attached to the ticket.
509
-                 */
510
-                $first_datetime              = $saved_datetimes[ reset($ticket_datetime_rows) ];
511
-                $ticket_data['TKT_end_date'] = $first_datetime->start_date_and_time($this->_date_time_format);
512
-            }
513
-            $TKT_values = [
514
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID'])
515
-                    ? $ticket_data['TKT_ID']
516
-                    : null,
517
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID'])
518
-                    ? $ticket_data['TTM_ID']
519
-                    : 0,
520
-                'TKT_name'        => ! empty($ticket_data['TKT_name'])
521
-                    ? $ticket_data['TKT_name']
522
-                    : '',
523
-                'TKT_description' => ! empty($ticket_data['TKT_description'])
524
-                                     && $ticket_data['TKT_description'] !== esc_html__(
525
-                    'You can modify this description',
526
-                    'event_espresso'
527
-                )
528
-                    ? $ticket_data['TKT_description']
529
-                    : '',
530
-                'TKT_start_date'  => $ticket_data['TKT_start_date'],
531
-                'TKT_end_date'    => $ticket_data['TKT_end_date'],
532
-                'TKT_qty'         => ! isset($ticket_data['TKT_qty']) || $ticket_data['TKT_qty'] === ''
533
-                    ? EE_INF
534
-                    : $ticket_data['TKT_qty'],
535
-                'TKT_uses'        => ! isset($ticket_data['TKT_uses']) || $ticket_data['TKT_uses'] === ''
536
-                    ? EE_INF
537
-                    : $ticket_data['TKT_uses'],
538
-                'TKT_min'         => empty($ticket_data['TKT_min'])
539
-                    ? 0
540
-                    : $ticket_data['TKT_min'],
541
-                'TKT_max'         => empty($ticket_data['TKT_max'])
542
-                    ? EE_INF
543
-                    : $ticket_data['TKT_max'],
544
-                'TKT_row'         => $row,
545
-                'TKT_order'       => $ticket_data['TKT_order'] ?? 0,
546
-                'TKT_taxable'     => ! empty($ticket_data['TKT_taxable'])
547
-                    ? 1
548
-                    : 0,
549
-                'TKT_required'    => ! empty($ticket_data['TKT_required'])
550
-                    ? 1
551
-                    : 0,
552
-                'TKT_price'       => $ticket_price,
553
-            ];
554
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
555
-            // which means in turn that the prices will become new prices as well.
556
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
557
-                $TKT_values['TKT_ID']         = 0;
558
-                $TKT_values['TKT_is_default'] = 0;
559
-                $update_prices                = true;
560
-            }
561
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
562
-            // we actually do our saves ahead of doing any add_relations to
563
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
564
-            // but DID have it's items modified.
565
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
566
-            // then we won't be updating the ticket but instead a new ticket will be created and the old one archived.
567
-            if (absint($TKT_values['TKT_ID'])) {
568
-                $ticket = EE_Registry::instance()
569
-                                     ->load_model('Ticket', [$timezone])
570
-                                     ->get_one_by_ID($TKT_values['TKT_ID']);
571
-                if ($ticket instanceof EE_Ticket) {
572
-                    $ticket = $this->_update_ticket_datetimes(
573
-                        $ticket,
574
-                        $saved_datetimes,
575
-                        $datetimes_added,
576
-                        $datetimes_removed
577
-                    );
578
-                    // are there any registrations using this ticket ?
579
-                    $tickets_sold = $ticket->count_related(
580
-                        'Registration',
581
-                        [
582
-                            [
583
-                                'STS_ID' => ['NOT IN', [RegStatus::INCOMPLETE]],
584
-                            ],
585
-                        ]
586
-                    );
587
-                    // set ticket formats
588
-                    $ticket->set_date_format($this->_date_format_strings['date']);
589
-                    $ticket->set_time_format($this->_date_format_strings['time']);
590
-                    // let's just check the total price for the existing ticket
591
-                    // and determine if it matches the new total price.
592
-                    // if they are different then we create a new ticket (if tickets sold)
593
-                    // if they aren't different then we go ahead and modify existing ticket.
594
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
595
-                    // set new values
596
-                    foreach ($TKT_values as $field => $value) {
597
-                        if ($field === 'TKT_qty') {
598
-                            $ticket->set_qty($value);
599
-                        } else {
600
-                            $ticket->set($field, $value);
601
-                        }
602
-                    }
603
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
604
-                    // Otherwise we have to create a new ticket.
605
-                    if ($create_new_TKT) {
606
-                        $new_ticket = $this->_duplicate_ticket(
607
-                            $ticket,
608
-                            $price_rows,
609
-                            $ticket_price,
610
-                            $base_price,
611
-                            $base_price_id
612
-                        );
613
-                    }
614
-                }
615
-            } else {
616
-                // no TKT_id so a new TKT
617
-                $ticket = EE_Ticket::new_instance(
618
-                    $TKT_values,
619
-                    $timezone,
620
-                    [$this->_date_format_strings['date'], $this->_date_format_strings['time']]
621
-                );
622
-                if ($ticket instanceof EE_Ticket) {
623
-                    // make sure ticket has an ID of setting relations won't work
624
-                    $ticket->save();
625
-                    $ticket        = $this->_update_ticket_datetimes(
626
-                        $ticket,
627
-                        $saved_datetimes,
628
-                        $datetimes_added,
629
-                        $datetimes_removed
630
-                    );
631
-                    $update_prices = true;
632
-                }
633
-            }
634
-            // make sure any current values have been saved.
635
-            // $ticket->save();
636
-            // before going any further make sure our dates are setup correctly
637
-            // so that the end date is always equal or greater than the start date.
638
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
639
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
640
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
641
-            }
642
-            // let's make sure the base price is handled
643
-            $ticket = ! $create_new_TKT
644
-                ? $this->_add_prices_to_ticket(
645
-                    [],
646
-                    $ticket,
647
-                    $update_prices,
648
-                    $base_price,
649
-                    $base_price_id
650
-                )
651
-                : $ticket;
652
-            // add/update price_modifiers
653
-            $ticket = ! $create_new_TKT
654
-                ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
655
-                : $ticket;
656
-            // need to make sue that the TKT_price is accurate after saving the prices.
657
-            $ticket->ensure_TKT_Price_correct();
658
-            // handle CREATING a default ticket from the incoming ticket but ONLY if this isn't an autosave.
659
-            if (! defined('DOING_AUTOSAVE') && ! empty($ticket_data['TKT_is_default_selector'])) {
660
-                $new_default = clone $ticket;
661
-                $new_default->set('TKT_ID', 0);
662
-                $new_default->set('TKT_is_default', 1);
663
-                $new_default->set('TKT_row', 1);
664
-                $new_default->set('TKT_price', $ticket_price);
665
-                // remove any datetime relations cause we DON'T want datetime relations attached
666
-                // (note this is just removing the cached relations in the object)
667
-                $new_default->_remove_relations('Datetime');
668
-                // @todo we need to add the current attached prices as new prices to the new default ticket.
669
-                $new_default = $this->_add_prices_to_ticket(
670
-                    $price_rows,
671
-                    $new_default,
672
-                    true
673
-                );
674
-                // don't forget the base price!
675
-                $new_default = $this->_add_prices_to_ticket(
676
-                    [],
677
-                    $new_default,
678
-                    true,
679
-                    $base_price,
680
-                    $base_price_id
681
-                );
682
-                $new_default->save();
683
-                do_action(
684
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
685
-                    $new_default,
686
-                    $row,
687
-                    $ticket,
688
-                    $data
689
-                );
690
-            }
691
-            // DO ALL datetime relationships for both current tickets and any archived tickets
692
-            // for the given datetime that are related to the current ticket.
693
-            // TODO... not sure exactly how we're going to do this considering we don't know
694
-            // what current ticket the archived tickets are related to
695
-            // (and TKT_parent is used for autosaves so that's not a field we can reliably use).
696
-            // let's assign any tickets that have been setup to the saved_tickets tracker
697
-            // save existing TKT
698
-            $ticket->save();
699
-            if ($create_new_TKT && $new_ticket instanceof EE_Ticket) {
700
-                // save new TKT
701
-                $new_ticket->save();
702
-                // add new ticket to array
703
-                $saved_tickets[ $new_ticket->ID() ] = $new_ticket;
704
-                do_action(
705
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
706
-                    $new_ticket,
707
-                    $row,
708
-                    $ticket_data,
709
-                    $data
710
-                );
711
-            } else {
712
-                // add ticket to saved tickets
713
-                $saved_tickets[ $ticket->ID() ] = $ticket;
714
-                do_action(
715
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
716
-                    $ticket,
717
-                    $row,
718
-                    $ticket_data,
719
-                    $data
720
-                );
721
-            }
722
-        }
723
-        // now we need to handle tickets actually "deleted permanently".
724
-        // There are cases where we'd want this to happen
725
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
726
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
727
-        // No sense in keeping all the related data in the db!
728
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === ''
729
-            ? []
730
-            : $old_tickets;
731
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
732
-        foreach ($tickets_removed as $id) {
733
-            $id = absint($id);
734
-            // get the ticket for this id
735
-            $ticket_to_remove = $ticket_model->get_one_by_ID($id);
736
-            // if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
737
-            if ($ticket_to_remove->get('TKT_is_default')) {
738
-                continue;
739
-            }
740
-            // if this ticket has any registrations attached so then we just ARCHIVE
741
-            // because we don't actually permanently delete these tickets.
742
-            if ($ticket_to_remove->count_related('Registration') > 0) {
743
-                $ticket_to_remove->delete();
744
-                continue;
745
-            }
746
-            // need to get all the related datetimes on this ticket and remove from every single one of them
747
-            // (remember this process can ONLY kick off if there are NO tickets_sold)
748
-            $datetimes = $ticket_to_remove->get_many_related('Datetime');
749
-            foreach ($datetimes as $datetime) {
750
-                $ticket_to_remove->_remove_relation_to($datetime, 'Datetime');
751
-            }
752
-            // need to do the same for prices (except these prices can also be deleted because again,
753
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
754
-            $ticket_to_remove->delete_related('Price');
755
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $ticket_to_remove);
756
-            // finally let's delete this ticket
757
-            // (which should not be blocked at this point b/c we've removed all our relationships)
758
-            $ticket_to_remove->delete_or_restore();
759
-        }
760
-        return $saved_tickets;
761
-    }
762
-
763
-
764
-    /**
765
-     * @access  protected
766
-     * @param EE_Ticket     $ticket
767
-     * @param EE_Datetime[] $saved_datetimes
768
-     * @param int[]         $added_datetimes
769
-     * @param int[]         $removed_datetimes
770
-     * @return EE_Ticket
771
-     * @throws EE_Error
772
-     * @throws ReflectionException
773
-     */
774
-    protected function _update_ticket_datetimes(
775
-        EE_Ticket $ticket,
776
-        array $saved_datetimes = [],
777
-        array $added_datetimes = [],
778
-        array $removed_datetimes = []
779
-    ): EE_Ticket {
780
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
781
-        // and removing the ticket from datetimes it got removed from.
782
-        // first let's add datetimes
783
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
784
-            foreach ($added_datetimes as $row_id) {
785
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
786
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
787
-                    // Is this an existing ticket (has an ID) and does it have any sold?
788
-                    // If so, then we need to add that to the DTT sold because this DTT is getting added.
789
-                    if ($ticket->ID() && $ticket->sold() > 0) {
790
-                        $saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
791
-                    }
792
-                }
793
-            }
794
-        }
795
-        // then remove datetimes
796
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
797
-            foreach ($removed_datetimes as $row_id) {
798
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
799
-                // So make sure we skip over this if the datetime isn't in the $saved_datetimes array)
800
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
801
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
802
-                }
803
-            }
804
-        }
805
-        // cap ticket qty by datetime reg limits
806
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
807
-        return $ticket;
808
-    }
809
-
810
-
811
-    /**
812
-     * @access  protected
813
-     * @param EE_Ticket $ticket
814
-     * @param array     $price_rows
815
-     * @param int|float $ticket_price
816
-     * @param int|float $base_price
817
-     * @param int       $base_price_id
818
-     * @return EE_Ticket
819
-     * @throws ReflectionException
820
-     * @throws InvalidArgumentException
821
-     * @throws InvalidInterfaceException
822
-     * @throws InvalidDataTypeException
823
-     * @throws EE_Error
824
-     */
825
-    protected function _duplicate_ticket(
826
-        EE_Ticket $ticket,
827
-        array $price_rows = [],
828
-        $ticket_price = 0,
829
-        $base_price = 0,
830
-        int $base_price_id = 0
831
-    ): EE_Ticket {
832
-        // create new ticket that's a copy of the existing
833
-        // except a new id of course (and not archived)
834
-        // AND has the new TKT_price associated with it.
835
-        $new_ticket = clone $ticket;
836
-        $new_ticket->set('TKT_ID', 0);
837
-        $new_ticket->set_deleted(0);
838
-        $new_ticket->set_price($ticket_price);
839
-        $new_ticket->set_sold(0);
840
-        // let's get a new ID for this ticket
841
-        $new_ticket->save();
842
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
843
-        $datetimes_on_existing = $ticket->datetimes();
844
-        $new_ticket            = $this->_update_ticket_datetimes(
845
-            $new_ticket,
846
-            $datetimes_on_existing,
847
-            array_keys($datetimes_on_existing)
848
-        );
849
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
850
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
851
-        // available.
852
-        if ($ticket->sold() > 0) {
853
-            $new_qty = $ticket->qty() - $ticket->sold();
854
-            $new_ticket->set_qty($new_qty);
855
-        }
856
-        // now we update the prices just for this ticket
857
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
858
-        // and we update the base price
859
-        return $this->_add_prices_to_ticket(
860
-            [],
861
-            $new_ticket,
862
-            true,
863
-            $base_price,
864
-            $base_price_id
865
-        );
866
-    }
867
-
868
-
869
-    /**
870
-     * This attaches a list of given prices to a ticket.
871
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
872
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
873
-     * price info and prices are automatically "archived" via the ticket.
874
-     *
875
-     * @access  private
876
-     * @param array     $prices        Array of prices from the form.
877
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
878
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
879
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
880
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
881
-     * @return EE_Ticket
882
-     * @throws ReflectionException
883
-     * @throws InvalidArgumentException
884
-     * @throws InvalidInterfaceException
885
-     * @throws InvalidDataTypeException
886
-     * @throws EE_Error
887
-     */
888
-    protected function _add_prices_to_ticket(
889
-        array $prices,
890
-        EE_Ticket $ticket,
891
-        bool $new_prices = false,
892
-        $base_price = false,
893
-        $base_price_id = false
894
-    ): EE_Ticket {
895
-        $price_model = EEM_Price::instance();
896
-        // let's just get any current prices that may exist on the given ticket
897
-        // so we can remove any prices that got trashed in this session.
898
-        $current_prices_on_ticket = $base_price !== false
899
-            ? $ticket->base_price(true)
900
-            : $ticket->price_modifiers();
901
-        $updated_prices           = [];
902
-        // if $base_price ! FALSE then updating a base price.
903
-        if ($base_price !== false) {
904
-            $prices[1] = [
905
-                'PRC_ID'     => $new_prices || $base_price_id === 1
906
-                    ? null
907
-                    : $base_price_id,
908
-                'PRT_ID'     => 1,
909
-                'PRC_amount' => $base_price,
910
-                'PRC_name'   => $ticket->get('TKT_name'),
911
-                'PRC_desc'   => $ticket->get('TKT_description'),
912
-            ];
913
-        }
914
-        // possibly need to save ticket
915
-        if (! $ticket->ID()) {
916
-            $ticket->save();
917
-        }
918
-        foreach ($prices as $row => $prc) {
919
-            $prt_id = ! empty($prc['PRT_ID'])
920
-                ? $prc['PRT_ID']
921
-                : null;
922
-            if (empty($prt_id)) {
923
-                continue;
924
-            } //prices MUST have a price type id.
925
-            $PRC_values = [
926
-                'PRC_ID'         => ! empty($prc['PRC_ID'])
927
-                    ? $prc['PRC_ID']
928
-                    : null,
929
-                'PRT_ID'         => $prt_id,
930
-                'PRC_amount'     => ! empty($prc['PRC_amount'])
931
-                    ? $prc['PRC_amount']
932
-                    : 0,
933
-                'PRC_name'       => ! empty($prc['PRC_name'])
934
-                    ? $prc['PRC_name']
935
-                    : '',
936
-                'PRC_desc'       => ! empty($prc['PRC_desc'])
937
-                    ? $prc['PRC_desc']
938
-                    : '',
939
-                'PRC_is_default' => false,
940
-                // make sure we set PRC_is_default to false for all ticket saves from event_editor
941
-                'PRC_order'      => $row,
942
-            ];
943
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
944
-                $PRC_values['PRC_ID'] = 0;
945
-                $price                = EE_Registry::instance()->load_class(
946
-                    'Price',
947
-                    [$PRC_values],
948
-                    false,
949
-                    false
950
-                );
951
-            } else {
952
-                $price = $price_model->get_one_by_ID($prc['PRC_ID']);
953
-                // update this price with new values
954
-                foreach ($PRC_values as $field => $value) {
955
-                    $price->set($field, $value);
956
-                }
957
-            }
958
-            $price->save();
959
-            $updated_prices[ $price->ID() ] = $price;
960
-            $ticket->_add_relation_to($price, 'Price');
961
-        }
962
-        // now let's remove any prices that got removed from the ticket
963
-        if (! empty($current_prices_on_ticket)) {
964
-            $current          = array_keys($current_prices_on_ticket);
965
-            $updated          = array_keys($updated_prices);
966
-            $prices_to_remove = array_diff($current, $updated);
967
-            if (! empty($prices_to_remove)) {
968
-                foreach ($prices_to_remove as $prc_id) {
969
-                    $p = $current_prices_on_ticket[ $prc_id ];
970
-                    $ticket->_remove_relation_to($p, 'Price');
971
-                    // delete permanently the price
972
-                    $p->delete_or_restore();
973
-                }
974
-            }
975
-        }
976
-        return $ticket;
977
-    }
978
-
979
-
980
-    /**
981
-     * @throws ReflectionException
982
-     * @throws InvalidArgumentException
983
-     * @throws InvalidInterfaceException
984
-     * @throws InvalidDataTypeException
985
-     * @throws DomainException
986
-     * @throws EE_Error
987
-     */
988
-    public function pricing_metabox()
989
-    {
990
-        $event          = $this->_adminpage_obj->get_cpt_model_obj();
991
-        $timezone       = $event instanceof EE_Event
992
-            ? $event->timezone_string()
993
-            : null;
994
-        $price_model    = EEM_Price::instance($timezone);
995
-        $ticket_model   = EEM_Ticket::instance($timezone);
996
-        $datetime_model = EEM_Datetime::instance($timezone);
997
-        $all_tickets    = [];
998
-
999
-        // set is_creating_event property.
1000
-        $EVT_ID                   = $event->ID();
1001
-        $this->_is_creating_event = empty($this->_req_data['post']);
1002
-        $existing_datetime_ids    = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = [];
1003
-
1004
-        // default main template args
1005
-        $main_template_args = [
1006
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link(
1007
-                'event_editor_event_datetimes_help_tab',
1008
-                $this->_adminpage_obj->page_slug,
1009
-                $this->_adminpage_obj->get_req_action()
1010
-            ),
1011
-
1012
-            // todo need to add a filter to the template for the help text
1013
-            // in the Events_Admin_Page core file so we can add further help
1014
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1015
-                'add_new_dtt_info',
1016
-                $this->_adminpage_obj->page_slug,
1017
-                $this->_adminpage_obj->get_req_action()
1018
-            ),
1019
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1020
-            'datetime_rows'            => '',
1021
-            'show_tickets_container'   => '',
1022
-            'ticket_rows'              => '',
1023
-            'ee_collapsible_status'    => ' ee-collapsible-open',
1024
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1025
-        ];
1026
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1027
-
1028
-        /**
1029
-         * 1. Start with retrieving Datetimes
1030
-         * 2. For each datetime get related tickets
1031
-         * 3. For each ticket get related prices
1032
-         */
1033
-        $datetimes                            = $datetime_model->get_all_event_dates($EVT_ID);
1034
-        $main_template_args['total_dtt_rows'] = count($datetimes);
1035
-
1036
-        /**
1037
-         * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1038
-         * for why we are counting $datetime_row and then setting that on the Datetime object
1039
-         */
1040
-        $datetime_row = 1;
1041
-        foreach ($datetimes as $datetime) {
1042
-            $DTT_ID = $datetime->get('DTT_ID');
1043
-            $datetime->set('DTT_order', $datetime_row);
1044
-            $existing_datetime_ids[] = $DTT_ID;
1045
-            // tickets attached
1046
-            $related_tickets = $datetime->ID() > 0
1047
-                ? $datetime->get_many_related(
1048
-                    'Ticket',
1049
-                    [
1050
-                        [
1051
-                            'OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0],
1052
-                        ],
1053
-                        'default_where_conditions' => 'none',
1054
-                        'order_by'                 => ['TKT_order' => 'ASC'],
1055
-                    ]
1056
-                )
1057
-                : [];
1058
-            // if there are no related tickets this is likely a new event OR auto-draft
1059
-            // event so we need to generate the default tickets because datetimes
1060
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1061
-            // datetime on the event.
1062
-            if (empty($related_tickets) && count($datetimes) < 2) {
1063
-                $related_tickets = $ticket_model->get_all_default_tickets();
1064
-                // this should be ordered by TKT_ID, so let's grab the first default ticket
1065
-                // (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1066
-                $default_prices      = $price_model->get_all_default_prices();
1067
-                $main_default_ticket = reset($related_tickets);
1068
-                if ($main_default_ticket instanceof EE_Ticket) {
1069
-                    foreach ($default_prices as $default_price) {
1070
-                        if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1071
-                            continue;
1072
-                        }
1073
-                        $main_default_ticket->cache('Price', $default_price);
1074
-                    }
1075
-                }
1076
-            }
1077
-            // we can't actually setup rows in this loop yet cause we don't know all
1078
-            // the unique tickets for this event yet (tickets are linked through all datetimes).
1079
-            // So we're going to temporarily cache some of that information.
1080
-            // loop through and setup the ticket rows and make sure the order is set.
1081
-            foreach ($related_tickets as $ticket) {
1082
-                $TKT_ID     = $ticket->get('TKT_ID');
1083
-                $ticket_row = $ticket->get('TKT_row');
1084
-                // we only want unique tickets in our final display!!
1085
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1086
-                    $existing_ticket_ids[] = $TKT_ID;
1087
-                    $all_tickets[]         = $ticket;
1088
-                }
1089
-                // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1090
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1091
-                // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1092
-                if (
1093
-                    ! isset($ticket_datetimes[ $TKT_ID ])
1094
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1095
-                ) {
1096
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1097
-                }
1098
-            }
1099
-            $datetime_row++;
1100
-        }
1101
-        $main_template_args['total_ticket_rows']     = count($existing_ticket_ids);
1102
-        $main_template_args['existing_ticket_ids']   = implode(',', $existing_ticket_ids);
1103
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1104
-        // sort $all_tickets by order
1105
-        usort(
1106
-            $all_tickets,
1107
-            function (EE_Ticket $a, EE_Ticket $b) {
1108
-                $a_order = (int) $a->get('TKT_order');
1109
-                $b_order = (int) $b->get('TKT_order');
1110
-                if ($a_order === $b_order) {
1111
-                    return 0;
1112
-                }
1113
-                return ($a_order < $b_order)
1114
-                    ? -1
1115
-                    : 1;
1116
-            }
1117
-        );
1118
-        // k NOW we have all the data we need for setting up the datetime rows
1119
-        // and ticket rows so we start our datetime loop again.
1120
-        $datetime_row = 1;
1121
-        foreach ($datetimes as $datetime) {
1122
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1123
-                $datetime_row,
1124
-                $datetime,
1125
-                $datetime_tickets,
1126
-                $all_tickets,
1127
-                false,
1128
-                $datetimes
1129
-            );
1130
-            $datetime_row++;
1131
-        }
1132
-        // then loop through all tickets for the ticket rows.
1133
-        $ticket_row = 1;
1134
-        foreach ($all_tickets as $ticket) {
1135
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1136
-                $ticket_row,
1137
-                $ticket,
1138
-                $ticket_datetimes,
1139
-                $datetimes,
1140
-                false,
1141
-                $all_tickets
1142
-            );
1143
-            $ticket_row++;
1144
-        }
1145
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1146
-
1147
-        $status_change_notice = LoaderFactory::getLoader()->getShared(
1148
-            'EventEspresso\core\domain\services\admin\notices\status_change\StatusChangeNotice'
1149
-        );
1150
-
1151
-        $main_template_args['status_change_notice'] = $status_change_notice->display(
1152
-            '__event-editor',
1153
-            'espresso-events'
1154
-        );
1155
-
1156
-        EEH_Template::display_template(
1157
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1158
-            $main_template_args
1159
-        );
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * @param int|string  $datetime_row
1165
-     * @param EE_Datetime $datetime
1166
-     * @param array       $datetime_tickets
1167
-     * @param array       $all_tickets
1168
-     * @param bool        $default
1169
-     * @param array       $all_datetimes
1170
-     * @return string
1171
-     * @throws DomainException
1172
-     * @throws EE_Error
1173
-     * @throws ReflectionException
1174
-     */
1175
-    protected function _get_datetime_row(
1176
-        $datetime_row,
1177
-        EE_Datetime $datetime,
1178
-        array $datetime_tickets = [],
1179
-        array $all_tickets = [],
1180
-        bool $default = false,
1181
-        array $all_datetimes = []
1182
-    ): string {
1183
-        return EEH_Template::display_template(
1184
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1185
-            [
1186
-                'dtt_edit_row'             => $this->_get_dtt_edit_row(
1187
-                    $datetime_row,
1188
-                    $datetime,
1189
-                    $default,
1190
-                    $all_datetimes
1191
-                ),
1192
-                'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1193
-                    $datetime_row,
1194
-                    $datetime,
1195
-                    $datetime_tickets,
1196
-                    $all_tickets,
1197
-                    $default
1198
-                ),
1199
-                'dtt_row'                  => $default
1200
-                    ? 'DTTNUM'
1201
-                    : $datetime_row,
1202
-            ],
1203
-            true
1204
-        );
1205
-    }
1206
-
1207
-
1208
-    /**
1209
-     * This method is used to generate a datetime fields  edit row.
1210
-     * The same row is used to generate a row with valid DTT objects
1211
-     * and the default row that is used as the skeleton by the js.
1212
-     *
1213
-     * @param int|string       $datetime_row  The row number for the row being generated.
1214
-     * @param EE_Datetime|null $datetime
1215
-     * @param bool             $default       Whether a default row is being generated or not.
1216
-     * @param EE_Datetime[]    $all_datetimes This is the array of all datetimes used in the editor.
1217
-     * @return string
1218
-     * @throws EE_Error
1219
-     * @throws ReflectionException
1220
-     */
1221
-    protected function _get_dtt_edit_row(
1222
-        $datetime_row,
1223
-        ?EE_Datetime $datetime,
1224
-        bool $default,
1225
-        array $all_datetimes
1226
-    ): string {
1227
-        // if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1228
-        $default                     = ! $datetime instanceof EE_Datetime
1229
-            ? true
1230
-            : $default;
1231
-        $template_args               = [
1232
-            'dtt_row'              => $default
1233
-                ? 'DTTNUM'
1234
-                : $datetime_row,
1235
-            'event_datetimes_name' => $default
1236
-                ? 'DTTNAMEATTR'
1237
-                : 'edit_event_datetimes',
1238
-            'edit_dtt_expanded'    => '',
1239
-            'DTT_ID'               => $default
1240
-                ? ''
1241
-                : $datetime->ID(),
1242
-            'DTT_name'             => $default
1243
-                ? ''
1244
-                : $datetime->get_f('DTT_name'),
1245
-            'DTT_description'      => $default
1246
-                ? ''
1247
-                : $datetime->get_raw('DTT_description'),
1248
-            'DTT_EVT_start'        => $default
1249
-                ? ''
1250
-                : $datetime->start_date($this->_date_time_format),
1251
-            'DTT_EVT_end'          => $default
1252
-                ? ''
1253
-                : $datetime->end_date($this->_date_time_format),
1254
-            'DTT_reg_limit'        => $default
1255
-                ? ''
1256
-                : $datetime->get_pretty(
1257
-                    'DTT_reg_limit',
1258
-                    'input'
1259
-                ),
1260
-            'DTT_order'            => $default
1261
-                ? 'DTTNUM'
1262
-                : $datetime_row,
1263
-            'dtt_sold'             => $default
1264
-                ? '0'
1265
-                : $datetime->get('DTT_sold'),
1266
-            'dtt_reserved'         => $default
1267
-                ? '0'
1268
-                : $datetime->reserved(),
1269
-            'can_clone'            => $datetime instanceof EE_Datetime,
1270
-            'can_trash'            => count($all_datetimes) > 1
1271
-                                      && $datetime instanceof EE_Datetime
1272
-                                      && ! $datetime->get('DTT_sold'),
1273
-            'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1274
-                ? 'trash-entity dashicons dashicons-lock'
1275
-                : 'trash-entity dashicons dashicons-post-trash clickable',
1276
-            'reg_list_url'         => $default || ! $datetime->event() instanceof EE_Event
1277
-                ? ''
1278
-                : EE_Admin_Page::add_query_args_and_nonce(
1279
-                    [
1280
-                        'event_id'    => $datetime->event()->ID(),
1281
-                        'datetime_id' => $datetime->ID(),
1282
-                        'use_filters' => true,
1283
-                    ],
1284
-                    REG_ADMIN_URL
1285
-                ),
1286
-        ];
1287
-        $template_args['show_trash'] = count($all_datetimes) === 1
1288
-                                       && $template_args['trash_icon'] !== 'dashicons dashicons-lock'
1289
-            ? 'display:none'
1290
-            : '';
1291
-        // allow filtering of template args at this point.
1292
-        $template_args = apply_filters(
1293
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1294
-            $template_args,
1295
-            $datetime_row,
1296
-            $datetime,
1297
-            $default,
1298
-            $all_datetimes,
1299
-            $this->_is_creating_event
1300
-        );
1301
-        return EEH_Template::display_template(
1302
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1303
-            $template_args,
1304
-            true
1305
-        );
1306
-    }
1307
-
1308
-
1309
-    /**
1310
-     * @param int|string       $datetime_row
1311
-     * @param EE_Datetime|null $datetime
1312
-     * @param array            $datetime_tickets
1313
-     * @param array            $all_tickets
1314
-     * @param bool             $default
1315
-     * @return string
1316
-     * @throws DomainException
1317
-     * @throws EE_Error
1318
-     * @throws ReflectionException
1319
-     */
1320
-    protected function _get_dtt_attached_tickets_row(
1321
-        $datetime_row,
1322
-        ?EE_Datetime $datetime,
1323
-        array $datetime_tickets = [],
1324
-        array $all_tickets = [],
1325
-        bool $default = false
1326
-    ): string {
1327
-        $template_args = [
1328
-            'dtt_row'                           => $default
1329
-                ? 'DTTNUM'
1330
-                : $datetime_row,
1331
-            'event_datetimes_name'              => $default
1332
-                ? 'DTTNAMEATTR'
1333
-                : 'edit_event_datetimes',
1334
-            'DTT_description'                   => $default
1335
-                ? ''
1336
-                : $datetime->get_raw('DTT_description'),
1337
-            'datetime_tickets_list'             => $default
1338
-                ? '<li class="hidden"></li>'
1339
-                : '',
1340
-            'show_tickets_row'                  => 'display:none;',
1341
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1342
-                'add_new_ticket_via_datetime',
1343
-                $this->_adminpage_obj->page_slug,
1344
-                $this->_adminpage_obj->get_req_action()
1345
-            ),
1346
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1347
-            'DTT_ID'                            => $default
1348
-                ? ''
1349
-                : $datetime->ID(),
1350
-        ];
1351
-        // need to setup the list items (but only if this isn't a default skeleton setup)
1352
-        if (! $default) {
1353
-            $ticket_row = 1;
1354
-            foreach ($all_tickets as $ticket) {
1355
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1356
-                    $datetime_row,
1357
-                    $ticket_row,
1358
-                    $datetime,
1359
-                    $ticket,
1360
-                    $datetime_tickets
1361
-                );
1362
-                $ticket_row++;
1363
-            }
1364
-        }
1365
-        // filter template args at this point
1366
-        $template_args = apply_filters(
1367
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1368
-            $template_args,
1369
-            $datetime_row,
1370
-            $datetime,
1371
-            $datetime_tickets,
1372
-            $all_tickets,
1373
-            $default,
1374
-            $this->_is_creating_event
1375
-        );
1376
-        return EEH_Template::display_template(
1377
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1378
-            $template_args,
1379
-            true
1380
-        );
1381
-    }
1382
-
1383
-
1384
-    /**
1385
-     * @param int|string       $datetime_row
1386
-     * @param int|string       $ticket_row
1387
-     * @param EE_Datetime|null $datetime
1388
-     * @param EE_Ticket|null   $ticket
1389
-     * @param array            $datetime_tickets
1390
-     * @param bool             $default
1391
-     * @return string
1392
-     * @throws EE_Error
1393
-     * @throws ReflectionException
1394
-     */
1395
-    protected function _get_datetime_tickets_list_item(
1396
-        $datetime_row,
1397
-        $ticket_row,
1398
-        ?EE_Datetime $datetime,
1399
-        ?EE_Ticket $ticket,
1400
-        array $datetime_tickets = [],
1401
-        bool $default = false
1402
-    ): string {
1403
-        $datetime_tickets = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1404
-            ? $datetime_tickets[ $datetime->ID() ]
1405
-            : [];
1406
-        $display_row      = $ticket instanceof EE_Ticket
1407
-            ? $ticket->get('TKT_row')
1408
-            : 0;
1409
-        $no_ticket        = $default && empty($ticket);
1410
-        $template_args    = [
1411
-            'dtt_row'                 => $default
1412
-                ? 'DTTNUM'
1413
-                : $datetime_row,
1414
-            'tkt_row'                 => $no_ticket
1415
-                ? 'TICKETNUM'
1416
-                : $ticket_row,
1417
-            'datetime_ticket_checked' => in_array($display_row, $datetime_tickets, true)
1418
-                ? ' checked'
1419
-                : '',
1420
-            'ticket_selected'         => in_array($display_row, $datetime_tickets, true)
1421
-                ? ' ticket-selected'
1422
-                : '',
1423
-            'TKT_name'                => $no_ticket
1424
-                ? 'TKTNAME'
1425
-                : $ticket->get('TKT_name'),
1426
-            'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1427
-                ? ' tkt-status-' . EE_Ticket::onsale
1428
-                : ' tkt-status-' . $ticket->ticket_status(),
1429
-        ];
1430
-        // filter template args
1431
-        $template_args = apply_filters(
1432
-            'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1433
-            $template_args,
1434
-            $datetime_row,
1435
-            $ticket_row,
1436
-            $datetime,
1437
-            $ticket,
1438
-            $datetime_tickets,
1439
-            $default,
1440
-            $this->_is_creating_event
1441
-        );
1442
-        return EEH_Template::display_template(
1443
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1444
-            $template_args,
1445
-            true
1446
-        );
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * This generates the ticket row for tickets.
1452
-     * This same method is used to generate both the actual rows and the js skeleton row
1453
-     * (when default === true)
1454
-     *
1455
-     * @param int|string     $ticket_row       Represents the row number being generated.
1456
-     * @param EE_Ticket|null $ticket
1457
-     * @param EE_Datetime[]  $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1458
-     *                                         or empty for default
1459
-     * @param EE_Datetime[]  $all_datetimes    All Datetimes on the event or empty for default.
1460
-     * @param bool           $default          Whether default row being generated or not.
1461
-     * @param EE_Ticket[]    $all_tickets      This is an array of all tickets attached to the event
1462
-     *                                         (or empty in the case of defaults)
1463
-     * @return string
1464
-     * @throws InvalidArgumentException
1465
-     * @throws InvalidInterfaceException
1466
-     * @throws InvalidDataTypeException
1467
-     * @throws DomainException
1468
-     * @throws EE_Error
1469
-     * @throws ReflectionException
1470
-     */
1471
-    protected function _get_ticket_row(
1472
-        $ticket_row,
1473
-        ?EE_Ticket $ticket,
1474
-        array $ticket_datetimes,
1475
-        array $all_datetimes,
1476
-        bool $default = false,
1477
-        array $all_tickets = []
1478
-    ): string {
1479
-        // if $ticket is not an instance of EE_Ticket then force default to true.
1480
-        $default = ! $ticket instanceof EE_Ticket
1481
-            ? true
1482
-            : $default;
1483
-        $prices  = ! empty($ticket) && ! $default
1484
-            ? $ticket->get_many_related(
1485
-                'Price',
1486
-                ['default_where_conditions' => 'none', 'order_by' => ['PRC_order' => 'ASC']]
1487
-            )
1488
-            : [];
1489
-        // if there is only one price (which would be the base price)
1490
-        // or NO prices and this ticket is a default ticket,
1491
-        // let's just make sure there are no cached default prices on the object.
1492
-        // This is done by not including any query_params.
1493
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1494
-            $prices = $ticket->prices();
1495
-        }
1496
-        // check if we're dealing with a default ticket in which case
1497
-        // we don't want any starting_ticket_datetime_row values set
1498
-        // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1499
-        // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1500
-        $default_datetime = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1501
-        $tkt_datetimes    = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1502
-            ? $ticket_datetimes[ $ticket->ID() ]
1503
-            : [];
1504
-        $ticket_subtotal  = $default
1505
-            ? 0
1506
-            : $ticket->get_ticket_subtotal();
1507
-        $base_price       = $default
1508
-            ? null
1509
-            : $ticket->base_price();
1510
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1511
-        // breaking out complicated condition for ticket_status
1512
-        if ($default) {
1513
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1514
-        } else {
1515
-            $ticket_status_class = $ticket->is_default()
1516
-                ? ' tkt-status-' . EE_Ticket::onsale
1517
-                : ' tkt-status-' . $ticket->ticket_status();
1518
-        }
1519
-        // breaking out complicated condition for TKT_taxable
1520
-        if ($default) {
1521
-            $TKT_taxable = '';
1522
-        } else {
1523
-            $TKT_taxable = $ticket->taxable()
1524
-                ? 'checked'
1525
-                : '';
1526
-        }
1527
-        if ($default) {
1528
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1529
-        } elseif ($ticket->is_default()) {
1530
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1531
-        } else {
1532
-            $TKT_status = $ticket->ticket_status(true);
1533
-        }
1534
-        if ($default) {
1535
-            $TKT_min = '';
1536
-        } else {
1537
-            $TKT_min = $ticket->min();
1538
-            if ($TKT_min === -1 || $TKT_min === 0) {
1539
-                $TKT_min = '';
1540
-            }
1541
-        }
1542
-        $template_args                 = [
1543
-            'tkt_row'                       => $default
1544
-                ? 'TICKETNUM'
1545
-                : $ticket_row,
1546
-            'TKT_order'                     => $default
1547
-                ? 'TICKETNUM'
1548
-                : $ticket_row,
1549
-            // on initial page load this will always be the correct order.
1550
-            'tkt_status_class'              => $ticket_status_class,
1551
-            'display_edit_tkt_row'          => 'display:none;',
1552
-            'edit_tkt_expanded'             => '',
1553
-            'edit_tickets_name'             => $default
1554
-                ? 'TICKETNAMEATTR'
1555
-                : 'edit_tickets',
1556
-            'TKT_name'                      => $default
1557
-                ? ''
1558
-                : $ticket->get_f('TKT_name'),
1559
-            'TKT_start_date'                => $default
1560
-                ? ''
1561
-                : $ticket->get_date('TKT_start_date', $this->_date_time_format),
1562
-            'TKT_end_date'                  => $default
1563
-                ? ''
1564
-                : $ticket->get_date('TKT_end_date', $this->_date_time_format),
1565
-            'TKT_status'                    => $TKT_status,
1566
-            'TKT_price'                     => $default
1567
-                ? ''
1568
-                : EEH_Template::format_currency(
1569
-                    $ticket->get_ticket_total_with_taxes(),
1570
-                    false,
1571
-                    false
1572
-                ),
1573
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1574
-            'TKT_price_amount'              => $default
1575
-                ? 0
1576
-                : $ticket_subtotal,
1577
-            'TKT_qty'                       => $default
1578
-                ? ''
1579
-                : $ticket->get_pretty('TKT_qty', 'symbol'),
1580
-            'TKT_qty_for_input'             => $default
1581
-                ? ''
1582
-                : $ticket->get_pretty('TKT_qty', 'input'),
1583
-            'TKT_uses'                      => $default
1584
-                ? ''
1585
-                : $ticket->get_pretty('TKT_uses', 'input'),
1586
-            'TKT_min'                       => $TKT_min,
1587
-            'TKT_max'                       => $default
1588
-                ? ''
1589
-                : $ticket->get_pretty('TKT_max', 'input'),
1590
-            'TKT_sold'                      => $default
1591
-                ? 0
1592
-                : $ticket->tickets_sold(),
1593
-            'TKT_reserved'                  => $default
1594
-                ? 0
1595
-                : $ticket->reserved(),
1596
-            'TKT_registrations'             => $default
1597
-                ? 0
1598
-                : $ticket->count_registrations(
1599
-                    [
1600
-                        [
1601
-                            'STS_ID' => [
1602
-                                '!=',
1603
-                                RegStatus::INCOMPLETE,
1604
-                            ],
1605
-                        ],
1606
-                    ]
1607
-                ),
1608
-            'TKT_ID'                        => $default
1609
-                ? 0
1610
-                : $ticket->ID(),
1611
-            'TKT_description'               => $default
1612
-                ? ''
1613
-                : $ticket->get_raw('TKT_description'),
1614
-            'TKT_is_default'                => $default
1615
-                ? 0
1616
-                : $ticket->is_default(),
1617
-            'TKT_required'                  => $default
1618
-                ? 0
1619
-                : $ticket->required(),
1620
-            'TKT_is_default_selector'       => '',
1621
-            'ticket_price_rows'             => '',
1622
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1623
-                ? ''
1624
-                : $base_price->get_pretty('PRC_amount', 'localized_float'),
1625
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price
1626
-                ? 0
1627
-                : $base_price->ID(),
1628
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1629
-                ? ''
1630
-                : 'display:none;',
1631
-            'show_price_mod_button'         => count($prices) > 1
1632
-                                               || ($default && $count_price_mods > 0)
1633
-                                               || (! $default && $ticket->deleted())
1634
-                ? 'display:none;'
1635
-                : '',
1636
-            'total_price_rows'              => count($prices) > 1
1637
-                ? count($prices)
1638
-                : 1,
1639
-            'ticket_datetimes_list'         => $default
1640
-                ? '<li class="hidden"></li>'
1641
-                : '',
1642
-            'starting_ticket_datetime_rows' => $default || $default_datetime
1643
-                ? ''
1644
-                : implode(',', $tkt_datetimes),
1645
-            'ticket_datetime_rows'          => $default
1646
-                ? ''
1647
-                : implode(',', $tkt_datetimes),
1648
-            'existing_ticket_price_ids'     => $default
1649
-                ? ''
1650
-                : implode(',', array_keys($prices)),
1651
-            'ticket_template_id'            => $default
1652
-                ? 0
1653
-                : $ticket->get('TTM_ID'),
1654
-            'TKT_taxable'                   => $TKT_taxable,
1655
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1656
-                ? ''
1657
-                : 'display:none;',
1658
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1659
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1660
-                $ticket_subtotal,
1661
-                false,
1662
-                false
1663
-            ),
1664
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1665
-            'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1666
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1667
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1668
-                ? ' ticket-archived'
1669
-                : '',
1670
-            'trash_icon'                    => $ticket instanceof EE_Ticket
1671
-                                               && $ticket->deleted()
1672
-                                               && ! $ticket->is_permanently_deleteable()
1673
-                ? 'dashicons dashicons-lock '
1674
-                : 'trash-entity dashicons dashicons-post-trash clickable',
1675
-
1676
-            'can_clone' => $ticket instanceof EE_Ticket && ! $ticket->deleted(),
1677
-            'can_trash' => $ticket instanceof EE_Ticket
1678
-                           && (! $ticket->deleted() && $ticket->is_permanently_deleteable()),
1679
-        ];
1680
-        $template_args['trash_hidden'] = count($all_tickets) === 1
1681
-                                         && $template_args['trash_icon'] !== 'dashicons dashicons-lock'
1682
-            ? 'display:none'
1683
-            : '';
1684
-        // handle rows that should NOT be empty
1685
-        if (empty($template_args['TKT_start_date'])) {
1686
-            // if empty then the start date will be now.
1687
-            $template_args['TKT_start_date']   = date(
1688
-                $this->_date_time_format,
1689
-                current_time('timestamp')
1690
-            );
1691
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1692
-        }
1693
-        if (empty($template_args['TKT_end_date'])) {
1694
-            // get the earliest datetime (if present);
1695
-            $earliest_datetime = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1696
-                ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1697
-                    'Datetime',
1698
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1699
-                )
1700
-                : null;
1701
-            if (! empty($earliest_datetime)) {
1702
-                $template_args['TKT_end_date'] = $earliest_datetime->get_datetime(
1703
-                    'DTT_EVT_start',
1704
-                    $this->_date_time_format
1705
-                );
1706
-            } else {
1707
-                // default so let's just use what's been set for the default date-time which is 30 days from now.
1708
-                $template_args['TKT_end_date'] = date(
1709
-                    $this->_date_time_format,
1710
-                    mktime(
1711
-                        24,
1712
-                        0,
1713
-                        0,
1714
-                        date('m'),
1715
-                        date('d') + 29,
1716
-                        date('Y')
1717
-                    )
1718
-                );
1719
-            }
1720
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1721
-        }
1722
-        // generate ticket_datetime items
1723
-        if (! $default) {
1724
-            $datetime_row = 1;
1725
-            foreach ($all_datetimes as $datetime) {
1726
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1727
-                    $datetime_row,
1728
-                    $ticket_row,
1729
-                    $datetime,
1730
-                    $ticket,
1731
-                    $ticket_datetimes,
1732
-                    $default
1733
-                );
1734
-                $datetime_row++;
1735
-            }
1736
-        }
1737
-        $price_row = 1;
1738
-        foreach ($prices as $price) {
1739
-            if (! $price instanceof EE_Price) {
1740
-                continue;
1741
-            }
1742
-            if ($price->is_base_price()) {
1743
-                $price_row++;
1744
-                continue;
1745
-            }
1746
-
1747
-            $show_trash  = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1748
-            $show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1749
-
1750
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1751
-                $ticket_row,
1752
-                $price_row,
1753
-                $price,
1754
-                $default,
1755
-                $ticket,
1756
-                $show_trash,
1757
-                $show_create
1758
-            );
1759
-            $price_row++;
1760
-        }
1761
-        // filter $template_args
1762
-        $template_args = apply_filters(
1763
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1764
-            $template_args,
1765
-            $ticket_row,
1766
-            $ticket,
1767
-            $ticket_datetimes,
1768
-            $all_datetimes,
1769
-            $default,
1770
-            $all_tickets,
1771
-            $this->_is_creating_event
1772
-        );
1773
-        return EEH_Template::display_template(
1774
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1775
-            $template_args,
1776
-            true
1777
-        );
1778
-    }
1779
-
1780
-
1781
-    /**
1782
-     * @param int|string     $ticket_row
1783
-     * @param EE_Ticket|null $ticket
1784
-     * @return string
1785
-     * @throws DomainException
1786
-     * @throws EE_Error
1787
-     * @throws ReflectionException
1788
-     */
1789
-    protected function _get_tax_rows($ticket_row, ?EE_Ticket $ticket): string
1790
-    {
1791
-        $tax_rows = '';
1792
-        /** @var EE_Price[] $taxes */
1793
-        $taxes = EE_Taxes::get_taxes_for_admin();
1794
-        foreach ($taxes as $tax) {
1795
-            $tax_added     = $this->_get_tax_added($tax, $ticket);
1796
-            $template_args = [
1797
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1798
-                    ? ''
1799
-                    : 'display:none;',
1800
-                'tax_id'            => $tax->ID(),
1801
-                'tkt_row'           => $ticket_row,
1802
-                'tax_label'         => $tax->get('PRC_name'),
1803
-                'tax_added'         => $tax_added,
1804
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1805
-                'tax_amount'        => $tax->get('PRC_amount'),
1806
-            ];
1807
-            $template_args = apply_filters(
1808
-                'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1809
-                $template_args,
1810
-                $ticket_row,
1811
-                $ticket,
1812
-                $this->_is_creating_event
1813
-            );
1814
-            $tax_rows      .= EEH_Template::display_template(
1815
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1816
-                $template_args,
1817
-                true
1818
-            );
1819
-        }
1820
-        return $tax_rows;
1821
-    }
1822
-
1823
-
1824
-    /**
1825
-     * @param EE_Price       $tax
1826
-     * @param EE_Ticket|null $ticket
1827
-     * @return float|int
1828
-     * @throws EE_Error
1829
-     * @throws ReflectionException
1830
-     */
1831
-    protected function _get_tax_added(EE_Price $tax, ?EE_Ticket $ticket)
1832
-    {
1833
-        $subtotal = empty($ticket)
1834
-            ? 0
1835
-            : $ticket->get_ticket_subtotal();
1836
-        return $subtotal * $tax->get('PRC_amount') / 100;
1837
-    }
1838
-
1839
-
1840
-    /**
1841
-     * @param int|string     $ticket_row
1842
-     * @param int|string     $price_row
1843
-     * @param EE_Price|null  $price
1844
-     * @param bool           $default
1845
-     * @param EE_Ticket|null $ticket
1846
-     * @param bool           $show_trash
1847
-     * @param bool           $show_create
1848
-     * @return string
1849
-     * @throws InvalidArgumentException
1850
-     * @throws InvalidInterfaceException
1851
-     * @throws InvalidDataTypeException
1852
-     * @throws DomainException
1853
-     * @throws EE_Error
1854
-     * @throws ReflectionException
1855
-     */
1856
-    protected function _get_ticket_price_row(
1857
-        $ticket_row,
1858
-        $price_row,
1859
-        ?EE_Price $price,
1860
-        bool $default,
1861
-        ?EE_Ticket $ticket,
1862
-        bool $show_trash = true,
1863
-        bool $show_create = true
1864
-    ): string {
1865
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1866
-        $template_args = [
1867
-            'tkt_row'               => $default && empty($ticket)
1868
-                ? 'TICKETNUM'
1869
-                : $ticket_row,
1870
-            'PRC_order'             => $default && empty($price)
1871
-                ? 'PRICENUM'
1872
-                : $price_row,
1873
-            'edit_prices_name'      => $default && empty($price)
1874
-                ? 'PRICENAMEATTR'
1875
-                : 'edit_prices',
1876
-            'price_type_selector'   => $this->_get_price_type_selector(
1877
-                    $ticket_row,
1878
-                    $price_row,
1879
-                    $price,
1880
-                    $default,
1881
-                    $send_disabled
1882
-                ),
1883
-            'PRC_ID'                => $default && empty($price)
1884
-                ? 0
1885
-                : $price->ID(),
1886
-            'PRC_is_default'        => $default && empty($price)
1887
-                ? 0
1888
-                : $price->get('PRC_is_default'),
1889
-            'PRC_name'              => $default && empty($price)
1890
-                ? ''
1891
-                : $price->get('PRC_name'),
1892
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1893
-            'show_plus_or_minus'    => $default && empty($price)
1894
-                ? ''
1895
-                : 'display:none;',
1896
-            'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1897
-                ? 'display:none;'
1898
-                : '',
1899
-            'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1900
-                ? 'display:none;'
1901
-                : '',
1902
-            'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1903
-                ? 'display:none'
1904
-                : '',
1905
-            'PRC_amount'            => $default && empty($price)
1906
-                ? 0
1907
-                : $price->get_pretty('PRC_amount', 'localized_float'),
1908
-            'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1909
-                ? 'display:none;'
1910
-                : '',
1911
-            'show_trash_icon'       => $show_trash
1912
-                ? ''
1913
-                : ' style="display:none;"',
1914
-            'show_create_button'    => $show_create
1915
-                ? ''
1916
-                : ' style="display:none;"',
1917
-            'PRC_desc'              => $default && empty($price)
1918
-                ? ''
1919
-                : $price->get('PRC_desc'),
1920
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1921
-        ];
1922
-        $template_args = apply_filters(
1923
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1924
-            $template_args,
1925
-            $ticket_row,
1926
-            $price_row,
1927
-            $price,
1928
-            $default,
1929
-            $ticket,
1930
-            $show_trash,
1931
-            $show_create,
1932
-            $this->_is_creating_event
1933
-        );
1934
-        return EEH_Template::display_template(
1935
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1936
-            $template_args,
1937
-            true
1938
-        );
1939
-    }
1940
-
1941
-
1942
-    /**
1943
-     * @param int|string    $ticket_row
1944
-     * @param int|string    $price_row
1945
-     * @param EE_Price|null $price
1946
-     * @param bool          $default
1947
-     * @param bool          $disabled
1948
-     * @return string
1949
-     * @throws ReflectionException
1950
-     * @throws InvalidArgumentException
1951
-     * @throws InvalidInterfaceException
1952
-     * @throws InvalidDataTypeException
1953
-     * @throws DomainException
1954
-     * @throws EE_Error
1955
-     */
1956
-    protected function _get_price_type_selector(
1957
-        $ticket_row,
1958
-        $price_row,
1959
-        ?EE_Price $price,
1960
-        bool $default,
1961
-        bool $disabled = false
1962
-    ): string {
1963
-        if (($price instanceof EE_Price && $price->is_base_price()) || (! $price instanceof EE_Price && $default)) {
1964
-            return $this->_get_base_price_template(
1965
-                $ticket_row,
1966
-                $price_row,
1967
-                $price,
1968
-                $default
1969
-            );
1970
-        }
1971
-        return $this->_get_price_modifier_template(
1972
-            $ticket_row,
1973
-            $price_row,
1974
-            $price,
1975
-            $default,
1976
-            $disabled
1977
-        );
1978
-    }
1979
-
1980
-
1981
-    /**
1982
-     * @param int|string    $ticket_row
1983
-     * @param int|string    $price_row
1984
-     * @param EE_Price|null $price
1985
-     * @param bool          $default
1986
-     * @return string
1987
-     * @throws DomainException
1988
-     * @throws EE_Error
1989
-     * @throws ReflectionException
1990
-     */
1991
-    protected function _get_base_price_template(
1992
-        $ticket_row,
1993
-        $price_row,
1994
-        ?EE_Price $price,
1995
-        bool $default
1996
-    ): string {
1997
-        $template_args = [
1998
-            'tkt_row'                   => $default
1999
-                ? 'TICKETNUM'
2000
-                : $ticket_row,
2001
-            'PRC_order'                 => $default && empty($price)
2002
-                ? 'PRICENUM'
2003
-                : $price_row,
2004
-            'PRT_ID'                    => $default && empty($price)
2005
-                ? 1
2006
-                : $price->get('PRT_ID'),
2007
-            'PRT_name'                  => esc_html__('Price', 'event_espresso'),
2008
-            'price_selected_operator'   => '+',
2009
-            'price_selected_is_percent' => 0,
2010
-        ];
2011
-        $template_args = apply_filters(
2012
-            'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
2013
-            $template_args,
2014
-            $ticket_row,
2015
-            $price_row,
2016
-            $price,
2017
-            $default,
2018
-            $this->_is_creating_event
2019
-        );
2020
-        return EEH_Template::display_template(
2021
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
2022
-            $template_args,
2023
-            true
2024
-        );
2025
-    }
2026
-
2027
-
2028
-    /**
2029
-     * @param int|string    $ticket_row
2030
-     * @param int|string    $price_row
2031
-     * @param EE_Price|null $price
2032
-     * @param bool          $default
2033
-     * @param bool          $disabled
2034
-     * @return string
2035
-     * @throws ReflectionException
2036
-     * @throws InvalidArgumentException
2037
-     * @throws InvalidInterfaceException
2038
-     * @throws InvalidDataTypeException
2039
-     * @throws DomainException
2040
-     * @throws EE_Error
2041
-     */
2042
-    protected function _get_price_modifier_template(
2043
-        $ticket_row,
2044
-        $price_row,
2045
-        ?EE_Price $price,
2046
-        bool $default,
2047
-        bool $disabled = false
2048
-    ): string {
2049
-        $use_default = $default && ! $price instanceof EE_Price;
2050
-        $selected_price_type_id =  $use_default ? 0 : $price->type();
2051
-
2052
-        $select_name = $use_default
2053
-            ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
2054
-            : 'edit_prices[' . esc_attr($ticket_row) . '][' . esc_attr($price_row) . '][PRT_ID]';
2055
-
2056
-        $price_type_model       = EEM_Price_Type::instance();
2057
-        $price_types = $price_type_model->get_all([['NOT' => ['PBT_ID' => '1']]]);
2058
-        $all_price_types        = $use_default
2059
-            ? [esc_html__('Select Modifier', 'event_espresso')]
2060
-            : [];
2061
-        $price_option_spans     = '';
2062
-        // setup price types for selector
2063
-        foreach ($price_types as $price_type) {
2064
-            if (! $price_type instanceof EE_Price_Type) {
2065
-                continue;
2066
-            }
2067
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
2068
-            // while we're in the loop lets set up the option spans used by js
2069
-            $span_args          = [
2070
-                'PRT_ID'         => $price_type->ID(),
2071
-                'PRT_operator'   => $price_type->is_discount()
2072
-                    ? '-'
2073
-                    : '+',
2074
-                'PRT_is_percent' => $price_type->get('PRT_is_percent')
2075
-                    ? 1
2076
-                    : 0,
2077
-            ];
2078
-            $price_option_spans .= EEH_Template::display_template(
2079
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
2080
-                $span_args,
2081
-                true
2082
-            );
2083
-        }
2084
-
2085
-        $select_name = $disabled
2086
-            ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
2087
-            : $select_name;
2088
-
2089
-        $select_input = new EE_Select_Input(
2090
-            $all_price_types,
2091
-            [
2092
-                'default'               => $selected_price_type_id,
2093
-                'html_name'             => $select_name,
2094
-                'html_class'            => 'edit-price-PRT_ID',
2095
-                'other_html_attributes' => $disabled
2096
-                    ? 'style="width:auto;" disabled'
2097
-                    : 'style="width:auto;"',
2098
-            ]
2099
-        );
2100
-
2101
-        $price_selected_operator   = $price instanceof EE_Price && $price->is_discount()
2102
-            ? '-'
2103
-            : '+';
2104
-        $price_selected_operator   = $use_default
2105
-            ? ''
2106
-            : $price_selected_operator;
2107
-        $price_selected_is_percent = $price instanceof EE_Price && $price->is_percent()
2108
-            ? 1
2109
-            : 0;
2110
-        $price_selected_is_percent = $use_default
2111
-            ? ''
2112
-            : $price_selected_is_percent;
2113
-        $template_args             = [
2114
-            'tkt_row'                   => $default
2115
-                ? 'TICKETNUM'
2116
-                : $ticket_row,
2117
-            'PRC_order'                 => $use_default
2118
-                ? 'PRICENUM'
2119
-                : $price_row,
2120
-            'price_modifier_selector'   => $select_input->get_html_for_input(),
2121
-            'main_name'                 => $select_name,
2122
-            'selected_price_type_id'    => $selected_price_type_id,
2123
-            'price_option_spans'        => $price_option_spans,
2124
-            'price_selected_operator'   => $price_selected_operator,
2125
-            'price_selected_is_percent' => $price_selected_is_percent,
2126
-            'disabled'                  => $disabled,
2127
-        ];
2128
-        $template_args             = apply_filters(
2129
-            'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2130
-            $template_args,
2131
-            $ticket_row,
2132
-            $price_row,
2133
-            $price,
2134
-            $default,
2135
-            $disabled,
2136
-            $this->_is_creating_event
2137
-        );
2138
-        return EEH_Template::display_template(
2139
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2140
-            $template_args,
2141
-            true
2142
-        );
2143
-    }
2144
-
2145
-
2146
-    /**
2147
-     * @param int|string       $datetime_row
2148
-     * @param int|string       $ticket_row
2149
-     * @param EE_Datetime|null $datetime
2150
-     * @param EE_Ticket|null   $ticket
2151
-     * @param array            $ticket_datetimes
2152
-     * @param bool             $default
2153
-     * @return string
2154
-     * @throws DomainException
2155
-     * @throws EE_Error
2156
-     * @throws ReflectionException
2157
-     */
2158
-    protected function _get_ticket_datetime_list_item(
2159
-        $datetime_row,
2160
-        $ticket_row,
2161
-        ?EE_Datetime $datetime,
2162
-        ?EE_Ticket $ticket,
2163
-        array $ticket_datetimes = [],
2164
-        bool $default = false
2165
-    ): string {
2166
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2167
-            ? $ticket_datetimes[ $ticket->ID() ]
2168
-            : [];
2169
-        $template_args = [
2170
-            'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2171
-                ? 'DTTNUM'
2172
-                : $datetime_row,
2173
-            'tkt_row'                  => $default
2174
-                ? 'TICKETNUM'
2175
-                : $ticket_row,
2176
-            'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2177
-                ? ' ticket-selected'
2178
-                : '',
2179
-            'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2180
-                ? ' checked'
2181
-                : '',
2182
-            'DTT_name'                 => $default && empty($datetime)
2183
-                ? 'DTTNAME'
2184
-                : $datetime->get_dtt_display_name(true),
2185
-            'tkt_status_class'         => '',
2186
-        ];
2187
-        $template_args = apply_filters(
2188
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2189
-            $template_args,
2190
-            $datetime_row,
2191
-            $ticket_row,
2192
-            $datetime,
2193
-            $ticket,
2194
-            $ticket_datetimes,
2195
-            $default,
2196
-            $this->_is_creating_event
2197
-        );
2198
-        return EEH_Template::display_template(
2199
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2200
-            $template_args,
2201
-            true
2202
-        );
2203
-    }
2204
-
2205
-
2206
-    /**
2207
-     * @param array $all_datetimes
2208
-     * @param array $all_tickets
2209
-     * @return string
2210
-     * @throws ReflectionException
2211
-     * @throws InvalidArgumentException
2212
-     * @throws InvalidInterfaceException
2213
-     * @throws InvalidDataTypeException
2214
-     * @throws DomainException
2215
-     * @throws EE_Error
2216
-     */
2217
-    protected function _get_ticket_js_structure(array $all_datetimes = [], array $all_tickets = []): string
2218
-    {
2219
-        $template_args = [
2220
-            'default_datetime_edit_row' => $this->_get_dtt_edit_row(
2221
-                'DTTNUM',
2222
-                null,
2223
-                true,
2224
-                $all_datetimes
2225
-            ),
2226
-            'default_ticket_row'        => $this->_get_ticket_row(
2227
-                'TICKETNUM',
2228
-                null,
2229
-                [],
2230
-                [],
2231
-                true
2232
-            ),
2233
-            'default_price_row'         => $this->_get_ticket_price_row(
2234
-                'TICKETNUM',
2235
-                'PRICENUM',
2236
-                null,
2237
-                true,
2238
-                null
2239
-            ),
2240
-
2241
-            'default_price_rows'                       => '',
2242
-            'default_base_price_amount'                => 0,
2243
-            'default_base_price_name'                  => '',
2244
-            'default_base_price_description'           => '',
2245
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2246
-                'TICKETNUM',
2247
-                'PRICENUM',
2248
-                null,
2249
-                true
2250
-            ),
2251
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2252
-                'DTTNUM',
2253
-                null,
2254
-                [],
2255
-                [],
2256
-                true
2257
-            ),
2258
-            'existing_available_datetime_tickets_list' => '',
2259
-            'existing_available_ticket_datetimes_list' => '',
2260
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2261
-                'DTTNUM',
2262
-                'TICKETNUM',
2263
-                null,
2264
-                null,
2265
-                [],
2266
-                true
2267
-            ),
2268
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2269
-                'DTTNUM',
2270
-                'TICKETNUM',
2271
-                null,
2272
-                null,
2273
-                [],
2274
-                true
2275
-            ),
2276
-        ];
2277
-        $ticket_row    = 1;
2278
-        foreach ($all_tickets as $ticket) {
2279
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2280
-                'DTTNUM',
2281
-                $ticket_row,
2282
-                null,
2283
-                $ticket,
2284
-                [],
2285
-                true
2286
-            );
2287
-            $ticket_row++;
2288
-        }
2289
-        $datetime_row = 1;
2290
-        foreach ($all_datetimes as $datetime) {
2291
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2292
-                $datetime_row,
2293
-                'TICKETNUM',
2294
-                $datetime,
2295
-                null,
2296
-                [],
2297
-                true
2298
-            );
2299
-            $datetime_row++;
2300
-        }
2301
-        $price_model    = EEM_Price::instance();
2302
-        $default_prices = $price_model->get_all_default_prices();
2303
-        $price_row      = 1;
2304
-        foreach ($default_prices as $price) {
2305
-            if (! $price instanceof EE_Price) {
2306
-                continue;
2307
-            }
2308
-            if ($price->is_base_price()) {
2309
-                $template_args['default_base_price_amount']      = $price->get_pretty(
2310
-                    'PRC_amount',
2311
-                    'localized_float'
2312
-                );
2313
-                $template_args['default_base_price_name']        = $price->get('PRC_name');
2314
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
2315
-                $price_row++;
2316
-                continue;
2317
-            }
2318
-
2319
-            $show_trash  = ! ((count($default_prices) > 1 && $price_row === 1) || count($default_prices) === 1);
2320
-            $show_create = ! (count($default_prices) > 1 && count($default_prices) !== $price_row);
2321
-
2322
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2323
-                'TICKETNUM',
2324
-                $price_row,
2325
-                $price,
2326
-                true,
2327
-                null,
2328
-                $show_trash,
2329
-                $show_create
2330
-            );
2331
-            $price_row++;
2332
-        }
2333
-        $template_args = apply_filters(
2334
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2335
-            $template_args,
2336
-            $all_datetimes,
2337
-            $all_tickets,
2338
-            $this->_is_creating_event
2339
-        );
2340
-        return EEH_Template::display_template(
2341
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2342
-            $template_args,
2343
-            true
2344
-        );
2345
-    }
232
+					],
233
+					'DTT_OVERSELL_WARNING'  => [
234
+						'datetime_ticket' => esc_html__(
235
+							'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
236
+							'event_espresso'
237
+						),
238
+						'ticket_datetime' => esc_html__(
239
+							'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
240
+							'event_espresso'
241
+						),
242
+					],
243
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
244
+						$this->_date_format_strings['date'],
245
+						$this->_date_format_strings['time']
246
+					),
247
+					'DTT_START_OF_WEEK'     => ['dayValue' => (int) get_option('start_of_week')],
248
+				],
249
+			],
250
+		];
251
+	}
252
+
253
+
254
+	/**
255
+	 * @param array $update_callbacks
256
+	 * @return array
257
+	 */
258
+	public function caf_updates(array $update_callbacks): array
259
+	{
260
+		unset($update_callbacks['_default_tickets_update']);
261
+		$update_callbacks['datetime_and_tickets_caf_update'] = [$this, 'datetime_and_tickets_caf_update'];
262
+		return $update_callbacks;
263
+	}
264
+
265
+
266
+	/**
267
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
268
+	 *
269
+	 * @param EE_Event $event The Event object we're attaching data to
270
+	 * @param array    $data  The request data from the form
271
+	 * @throws ReflectionException
272
+	 * @throws Exception
273
+	 * @throws InvalidInterfaceException
274
+	 * @throws InvalidDataTypeException
275
+	 * @throws EE_Error
276
+	 * @throws InvalidArgumentException
277
+	 */
278
+	public function datetime_and_tickets_caf_update(EE_Event $event, array $data)
279
+	{
280
+		// first we need to start with datetimes cause they are the "root" items attached to events.
281
+		$saved_datetimes = $this->_update_datetimes($event, $data);
282
+		// next tackle the tickets (and prices?)
283
+		$this->_update_tickets($event, $saved_datetimes, $data);
284
+	}
285
+
286
+
287
+	/**
288
+	 * update event_datetimes
289
+	 *
290
+	 * @param EE_Event $event Event being updated
291
+	 * @param array    $data  the request data from the form
292
+	 * @return EE_Datetime[]
293
+	 * @throws Exception
294
+	 * @throws ReflectionException
295
+	 * @throws InvalidInterfaceException
296
+	 * @throws InvalidDataTypeException
297
+	 * @throws InvalidArgumentException
298
+	 * @throws EE_Error
299
+	 */
300
+	protected function _update_datetimes(EE_Event $event, array $data): array
301
+	{
302
+		$saved_datetime_ids  = [];
303
+		$saved_datetime_objs = [];
304
+		$timezone            = $data['timezone_string'] ?? null;
305
+		$datetime_model      = EEM_Datetime::instance($timezone);
306
+
307
+		if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
308
+			throw new InvalidArgumentException(
309
+				esc_html__(
310
+					'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
311
+					'event_espresso'
312
+				)
313
+			);
314
+		}
315
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
316
+			// trim all values to ensure any excess whitespace is removed.
317
+			$datetime_data = array_map(
318
+				function ($datetime_data) {
319
+					return is_array($datetime_data)
320
+						? $datetime_data
321
+						: trim($datetime_data);
322
+				},
323
+				$datetime_data
324
+			);
325
+
326
+			$datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
327
+											&& ! empty($datetime_data['DTT_EVT_end'])
328
+				? $datetime_data['DTT_EVT_end']
329
+				: $datetime_data['DTT_EVT_start'];
330
+			$datetime_values              = [
331
+				'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
332
+					? $datetime_data['DTT_ID']
333
+					: null,
334
+				'DTT_name'        => ! empty($datetime_data['DTT_name'])
335
+					? $datetime_data['DTT_name']
336
+					: '',
337
+				'DTT_description' => ! empty($datetime_data['DTT_description'])
338
+					? $datetime_data['DTT_description']
339
+					: '',
340
+				'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
341
+				'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
342
+				'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
343
+					? EE_INF
344
+					: $datetime_data['DTT_reg_limit'],
345
+				'DTT_order'       => ! isset($datetime_data['DTT_order'])
346
+					? $row
347
+					: $datetime_data['DTT_order'],
348
+			];
349
+
350
+			// if we have an id then let's get existing object first and then set the new values.
351
+			// Otherwise we instantiate a new object for save.
352
+			if (! empty($datetime_data['DTT_ID'])) {
353
+				$datetime = EE_Registry::instance()
354
+									   ->load_model('Datetime', [$timezone])
355
+									   ->get_one_by_ID($datetime_data['DTT_ID']);
356
+				// set date and time format according to what is set in this class.
357
+				$datetime->set_date_format($this->_date_format_strings['date']);
358
+				$datetime->set_time_format($this->_date_format_strings['time']);
359
+				foreach ($datetime_values as $field => $value) {
360
+					$datetime->set($field, $value);
361
+				}
362
+
363
+				// make sure the $datetime_id here is saved just in case
364
+				// after the add_relation_to() the autosave replaces it.
365
+				// We need to do this so we dont' TRASH the parent DTT.
366
+				// (save the ID for both key and value to avoid duplications)
367
+				$saved_datetime_ids[ $datetime->ID() ] = $datetime->ID();
368
+			} else {
369
+				$datetime = EE_Datetime::new_instance(
370
+					$datetime_values,
371
+					$timezone,
372
+					[$this->_date_format_strings['date'], $this->_date_format_strings['time']]
373
+				);
374
+				foreach ($datetime_values as $field => $value) {
375
+					$datetime->set($field, $value);
376
+				}
377
+			}
378
+			$datetime->save();
379
+			do_action(
380
+				'AHEE__espresso_events_Pricing_Hooks___update_datetimes_after_save',
381
+				$datetime,
382
+				$row,
383
+				$datetime_data,
384
+				$data
385
+			);
386
+			$datetime = $event->_add_relation_to($datetime, 'Datetime');
387
+			// before going any further make sure our dates are setup correctly
388
+			// so that the end date is always equal or greater than the start date.
389
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
390
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
391
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
392
+				$datetime->save();
393
+			}
394
+			// now we have to make sure we add the new DTT_ID to the $saved_datetime_ids array
395
+			// because it is possible there was a new one created for the autosave.
396
+			// (save the ID for both key and value to avoid duplications)
397
+			$DTT_ID                        = $datetime->ID();
398
+			$saved_datetime_ids[ $DTT_ID ] = $DTT_ID;
399
+			$saved_datetime_objs[ $row ]   = $datetime;
400
+			// @todo if ANY of these updates fail then we want the appropriate global error message.
401
+		}
402
+		$event->save();
403
+		// now we need to REMOVE any datetimes that got deleted.
404
+		// Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
405
+		// So its safe to permanently delete at this point.
406
+		$old_datetimes = explode(',', $data['datetime_IDs']);
407
+		$old_datetimes = $old_datetimes[0] === ''
408
+			? []
409
+			: $old_datetimes;
410
+		if (is_array($old_datetimes)) {
411
+			$datetimes_to_delete = array_diff($old_datetimes, $saved_datetime_ids);
412
+			foreach ($datetimes_to_delete as $id) {
413
+				$id = absint($id);
414
+				if (empty($id)) {
415
+					continue;
416
+				}
417
+				$dtt_to_remove = $datetime_model->get_one_by_ID($id);
418
+				// remove tkt relationships.
419
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
420
+				foreach ($related_tickets as $ticket) {
421
+					$dtt_to_remove->_remove_relation_to($ticket, 'Ticket');
422
+				}
423
+				$event->_remove_relation_to($id, 'Datetime');
424
+				$dtt_to_remove->refresh_cache_of_related_objects();
425
+			}
426
+		}
427
+		return $saved_datetime_objs;
428
+	}
429
+
430
+
431
+	/**
432
+	 * update tickets
433
+	 *
434
+	 * @param EE_Event      $event           Event object being updated
435
+	 * @param EE_Datetime[] $saved_datetimes an array of datetime ids being updated
436
+	 * @param array         $data            incoming request data
437
+	 * @return EE_Ticket[]
438
+	 * @throws Exception
439
+	 * @throws ReflectionException
440
+	 * @throws InvalidInterfaceException
441
+	 * @throws InvalidDataTypeException
442
+	 * @throws InvalidArgumentException
443
+	 * @throws EE_Error
444
+	 */
445
+	protected function _update_tickets(EE_Event $event, array $saved_datetimes, array $data): array
446
+	{
447
+		$new_ticket = null;
448
+		// stripslashes because WP filtered the $_POST ($data) array to add slashes
449
+		$data         = stripslashes_deep($data);
450
+		$timezone     = $data['timezone_string'] ?? null;
451
+		$ticket_model = EEM_Ticket::instance($timezone);
452
+
453
+		$saved_tickets = [];
454
+		$old_tickets   = isset($data['ticket_IDs'])
455
+			? explode(',', $data['ticket_IDs'])
456
+			: [];
457
+		if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
458
+			throw new InvalidArgumentException(
459
+				esc_html__(
460
+					'The "edit_tickets" array is invalid therefore the event can not be updated.',
461
+					'event_espresso'
462
+				)
463
+			);
464
+		}
465
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
466
+			$update_prices = $create_new_TKT = false;
467
+			// figure out what datetimes were added to the ticket
468
+			// and what datetimes were removed from the ticket in the session.
469
+			$starting_ticket_datetime_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
470
+			$ticket_datetime_rows          = explode(',', $data['ticket_datetime_rows'][ $row ]);
471
+			$datetimes_added               = array_diff($ticket_datetime_rows, $starting_ticket_datetime_rows);
472
+			$datetimes_removed             = array_diff($starting_ticket_datetime_rows, $ticket_datetime_rows);
473
+			// trim inputs to ensure any excess whitespace is removed.
474
+			$ticket_data = array_map(
475
+				function ($ticket_data) {
476
+					return is_array($ticket_data)
477
+						? $ticket_data
478
+						: trim($ticket_data);
479
+				},
480
+				$ticket_data
481
+			);
482
+			// note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
483
+			// because we're doing calculations prior to using the models.
484
+			// note incoming ['TKT_price'] value is already in standard notation (via js).
485
+			$ticket_price = isset($ticket_data['TKT_price'])
486
+				? round((float) $ticket_data['TKT_price'], 3)
487
+				: 0;
488
+			// note incoming base price needs converted from localized value.
489
+			$base_price = isset($ticket_data['TKT_base_price'])
490
+				? EEH_Money::convert_to_float_from_localized_money($ticket_data['TKT_base_price'])
491
+				: 0;
492
+			// if ticket price == 0 and $base_price != 0 then ticket price == base_price
493
+			$ticket_price  = $ticket_price === 0 && $base_price !== 0
494
+				? $base_price
495
+				: $ticket_price;
496
+			$base_price_id = $ticket_data['TKT_base_price_ID'] ?? 0;
497
+			$price_rows    = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
498
+				? $data['edit_prices'][ $row ]
499
+				: [];
500
+			$now           = null;
501
+			if (empty($ticket_data['TKT_start_date'])) {
502
+				// lets' use now in the set timezone.
503
+				$now                           = new DateTime('now', new DateTimeZone($event->get_timezone()));
504
+				$ticket_data['TKT_start_date'] = $now->format($this->_date_time_format);
505
+			}
506
+			if (empty($ticket_data['TKT_end_date'])) {
507
+				/**
508
+				 * set the TKT_end_date to the first datetime attached to the ticket.
509
+				 */
510
+				$first_datetime              = $saved_datetimes[ reset($ticket_datetime_rows) ];
511
+				$ticket_data['TKT_end_date'] = $first_datetime->start_date_and_time($this->_date_time_format);
512
+			}
513
+			$TKT_values = [
514
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID'])
515
+					? $ticket_data['TKT_ID']
516
+					: null,
517
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID'])
518
+					? $ticket_data['TTM_ID']
519
+					: 0,
520
+				'TKT_name'        => ! empty($ticket_data['TKT_name'])
521
+					? $ticket_data['TKT_name']
522
+					: '',
523
+				'TKT_description' => ! empty($ticket_data['TKT_description'])
524
+									 && $ticket_data['TKT_description'] !== esc_html__(
525
+					'You can modify this description',
526
+					'event_espresso'
527
+				)
528
+					? $ticket_data['TKT_description']
529
+					: '',
530
+				'TKT_start_date'  => $ticket_data['TKT_start_date'],
531
+				'TKT_end_date'    => $ticket_data['TKT_end_date'],
532
+				'TKT_qty'         => ! isset($ticket_data['TKT_qty']) || $ticket_data['TKT_qty'] === ''
533
+					? EE_INF
534
+					: $ticket_data['TKT_qty'],
535
+				'TKT_uses'        => ! isset($ticket_data['TKT_uses']) || $ticket_data['TKT_uses'] === ''
536
+					? EE_INF
537
+					: $ticket_data['TKT_uses'],
538
+				'TKT_min'         => empty($ticket_data['TKT_min'])
539
+					? 0
540
+					: $ticket_data['TKT_min'],
541
+				'TKT_max'         => empty($ticket_data['TKT_max'])
542
+					? EE_INF
543
+					: $ticket_data['TKT_max'],
544
+				'TKT_row'         => $row,
545
+				'TKT_order'       => $ticket_data['TKT_order'] ?? 0,
546
+				'TKT_taxable'     => ! empty($ticket_data['TKT_taxable'])
547
+					? 1
548
+					: 0,
549
+				'TKT_required'    => ! empty($ticket_data['TKT_required'])
550
+					? 1
551
+					: 0,
552
+				'TKT_price'       => $ticket_price,
553
+			];
554
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
555
+			// which means in turn that the prices will become new prices as well.
556
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
557
+				$TKT_values['TKT_ID']         = 0;
558
+				$TKT_values['TKT_is_default'] = 0;
559
+				$update_prices                = true;
560
+			}
561
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
562
+			// we actually do our saves ahead of doing any add_relations to
563
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
564
+			// but DID have it's items modified.
565
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
566
+			// then we won't be updating the ticket but instead a new ticket will be created and the old one archived.
567
+			if (absint($TKT_values['TKT_ID'])) {
568
+				$ticket = EE_Registry::instance()
569
+									 ->load_model('Ticket', [$timezone])
570
+									 ->get_one_by_ID($TKT_values['TKT_ID']);
571
+				if ($ticket instanceof EE_Ticket) {
572
+					$ticket = $this->_update_ticket_datetimes(
573
+						$ticket,
574
+						$saved_datetimes,
575
+						$datetimes_added,
576
+						$datetimes_removed
577
+					);
578
+					// are there any registrations using this ticket ?
579
+					$tickets_sold = $ticket->count_related(
580
+						'Registration',
581
+						[
582
+							[
583
+								'STS_ID' => ['NOT IN', [RegStatus::INCOMPLETE]],
584
+							],
585
+						]
586
+					);
587
+					// set ticket formats
588
+					$ticket->set_date_format($this->_date_format_strings['date']);
589
+					$ticket->set_time_format($this->_date_format_strings['time']);
590
+					// let's just check the total price for the existing ticket
591
+					// and determine if it matches the new total price.
592
+					// if they are different then we create a new ticket (if tickets sold)
593
+					// if they aren't different then we go ahead and modify existing ticket.
594
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
595
+					// set new values
596
+					foreach ($TKT_values as $field => $value) {
597
+						if ($field === 'TKT_qty') {
598
+							$ticket->set_qty($value);
599
+						} else {
600
+							$ticket->set($field, $value);
601
+						}
602
+					}
603
+					// if $create_new_TKT is false then we can safely update the existing ticket.
604
+					// Otherwise we have to create a new ticket.
605
+					if ($create_new_TKT) {
606
+						$new_ticket = $this->_duplicate_ticket(
607
+							$ticket,
608
+							$price_rows,
609
+							$ticket_price,
610
+							$base_price,
611
+							$base_price_id
612
+						);
613
+					}
614
+				}
615
+			} else {
616
+				// no TKT_id so a new TKT
617
+				$ticket = EE_Ticket::new_instance(
618
+					$TKT_values,
619
+					$timezone,
620
+					[$this->_date_format_strings['date'], $this->_date_format_strings['time']]
621
+				);
622
+				if ($ticket instanceof EE_Ticket) {
623
+					// make sure ticket has an ID of setting relations won't work
624
+					$ticket->save();
625
+					$ticket        = $this->_update_ticket_datetimes(
626
+						$ticket,
627
+						$saved_datetimes,
628
+						$datetimes_added,
629
+						$datetimes_removed
630
+					);
631
+					$update_prices = true;
632
+				}
633
+			}
634
+			// make sure any current values have been saved.
635
+			// $ticket->save();
636
+			// before going any further make sure our dates are setup correctly
637
+			// so that the end date is always equal or greater than the start date.
638
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
639
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
640
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
641
+			}
642
+			// let's make sure the base price is handled
643
+			$ticket = ! $create_new_TKT
644
+				? $this->_add_prices_to_ticket(
645
+					[],
646
+					$ticket,
647
+					$update_prices,
648
+					$base_price,
649
+					$base_price_id
650
+				)
651
+				: $ticket;
652
+			// add/update price_modifiers
653
+			$ticket = ! $create_new_TKT
654
+				? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
655
+				: $ticket;
656
+			// need to make sue that the TKT_price is accurate after saving the prices.
657
+			$ticket->ensure_TKT_Price_correct();
658
+			// handle CREATING a default ticket from the incoming ticket but ONLY if this isn't an autosave.
659
+			if (! defined('DOING_AUTOSAVE') && ! empty($ticket_data['TKT_is_default_selector'])) {
660
+				$new_default = clone $ticket;
661
+				$new_default->set('TKT_ID', 0);
662
+				$new_default->set('TKT_is_default', 1);
663
+				$new_default->set('TKT_row', 1);
664
+				$new_default->set('TKT_price', $ticket_price);
665
+				// remove any datetime relations cause we DON'T want datetime relations attached
666
+				// (note this is just removing the cached relations in the object)
667
+				$new_default->_remove_relations('Datetime');
668
+				// @todo we need to add the current attached prices as new prices to the new default ticket.
669
+				$new_default = $this->_add_prices_to_ticket(
670
+					$price_rows,
671
+					$new_default,
672
+					true
673
+				);
674
+				// don't forget the base price!
675
+				$new_default = $this->_add_prices_to_ticket(
676
+					[],
677
+					$new_default,
678
+					true,
679
+					$base_price,
680
+					$base_price_id
681
+				);
682
+				$new_default->save();
683
+				do_action(
684
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
685
+					$new_default,
686
+					$row,
687
+					$ticket,
688
+					$data
689
+				);
690
+			}
691
+			// DO ALL datetime relationships for both current tickets and any archived tickets
692
+			// for the given datetime that are related to the current ticket.
693
+			// TODO... not sure exactly how we're going to do this considering we don't know
694
+			// what current ticket the archived tickets are related to
695
+			// (and TKT_parent is used for autosaves so that's not a field we can reliably use).
696
+			// let's assign any tickets that have been setup to the saved_tickets tracker
697
+			// save existing TKT
698
+			$ticket->save();
699
+			if ($create_new_TKT && $new_ticket instanceof EE_Ticket) {
700
+				// save new TKT
701
+				$new_ticket->save();
702
+				// add new ticket to array
703
+				$saved_tickets[ $new_ticket->ID() ] = $new_ticket;
704
+				do_action(
705
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
706
+					$new_ticket,
707
+					$row,
708
+					$ticket_data,
709
+					$data
710
+				);
711
+			} else {
712
+				// add ticket to saved tickets
713
+				$saved_tickets[ $ticket->ID() ] = $ticket;
714
+				do_action(
715
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
716
+					$ticket,
717
+					$row,
718
+					$ticket_data,
719
+					$data
720
+				);
721
+			}
722
+		}
723
+		// now we need to handle tickets actually "deleted permanently".
724
+		// There are cases where we'd want this to happen
725
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
726
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
727
+		// No sense in keeping all the related data in the db!
728
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === ''
729
+			? []
730
+			: $old_tickets;
731
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
732
+		foreach ($tickets_removed as $id) {
733
+			$id = absint($id);
734
+			// get the ticket for this id
735
+			$ticket_to_remove = $ticket_model->get_one_by_ID($id);
736
+			// if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
737
+			if ($ticket_to_remove->get('TKT_is_default')) {
738
+				continue;
739
+			}
740
+			// if this ticket has any registrations attached so then we just ARCHIVE
741
+			// because we don't actually permanently delete these tickets.
742
+			if ($ticket_to_remove->count_related('Registration') > 0) {
743
+				$ticket_to_remove->delete();
744
+				continue;
745
+			}
746
+			// need to get all the related datetimes on this ticket and remove from every single one of them
747
+			// (remember this process can ONLY kick off if there are NO tickets_sold)
748
+			$datetimes = $ticket_to_remove->get_many_related('Datetime');
749
+			foreach ($datetimes as $datetime) {
750
+				$ticket_to_remove->_remove_relation_to($datetime, 'Datetime');
751
+			}
752
+			// need to do the same for prices (except these prices can also be deleted because again,
753
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
754
+			$ticket_to_remove->delete_related('Price');
755
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $ticket_to_remove);
756
+			// finally let's delete this ticket
757
+			// (which should not be blocked at this point b/c we've removed all our relationships)
758
+			$ticket_to_remove->delete_or_restore();
759
+		}
760
+		return $saved_tickets;
761
+	}
762
+
763
+
764
+	/**
765
+	 * @access  protected
766
+	 * @param EE_Ticket     $ticket
767
+	 * @param EE_Datetime[] $saved_datetimes
768
+	 * @param int[]         $added_datetimes
769
+	 * @param int[]         $removed_datetimes
770
+	 * @return EE_Ticket
771
+	 * @throws EE_Error
772
+	 * @throws ReflectionException
773
+	 */
774
+	protected function _update_ticket_datetimes(
775
+		EE_Ticket $ticket,
776
+		array $saved_datetimes = [],
777
+		array $added_datetimes = [],
778
+		array $removed_datetimes = []
779
+	): EE_Ticket {
780
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
781
+		// and removing the ticket from datetimes it got removed from.
782
+		// first let's add datetimes
783
+		if (! empty($added_datetimes) && is_array($added_datetimes)) {
784
+			foreach ($added_datetimes as $row_id) {
785
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
786
+					$ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
787
+					// Is this an existing ticket (has an ID) and does it have any sold?
788
+					// If so, then we need to add that to the DTT sold because this DTT is getting added.
789
+					if ($ticket->ID() && $ticket->sold() > 0) {
790
+						$saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
791
+					}
792
+				}
793
+			}
794
+		}
795
+		// then remove datetimes
796
+		if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
797
+			foreach ($removed_datetimes as $row_id) {
798
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
799
+				// So make sure we skip over this if the datetime isn't in the $saved_datetimes array)
800
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
801
+					$ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
802
+				}
803
+			}
804
+		}
805
+		// cap ticket qty by datetime reg limits
806
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
807
+		return $ticket;
808
+	}
809
+
810
+
811
+	/**
812
+	 * @access  protected
813
+	 * @param EE_Ticket $ticket
814
+	 * @param array     $price_rows
815
+	 * @param int|float $ticket_price
816
+	 * @param int|float $base_price
817
+	 * @param int       $base_price_id
818
+	 * @return EE_Ticket
819
+	 * @throws ReflectionException
820
+	 * @throws InvalidArgumentException
821
+	 * @throws InvalidInterfaceException
822
+	 * @throws InvalidDataTypeException
823
+	 * @throws EE_Error
824
+	 */
825
+	protected function _duplicate_ticket(
826
+		EE_Ticket $ticket,
827
+		array $price_rows = [],
828
+		$ticket_price = 0,
829
+		$base_price = 0,
830
+		int $base_price_id = 0
831
+	): EE_Ticket {
832
+		// create new ticket that's a copy of the existing
833
+		// except a new id of course (and not archived)
834
+		// AND has the new TKT_price associated with it.
835
+		$new_ticket = clone $ticket;
836
+		$new_ticket->set('TKT_ID', 0);
837
+		$new_ticket->set_deleted(0);
838
+		$new_ticket->set_price($ticket_price);
839
+		$new_ticket->set_sold(0);
840
+		// let's get a new ID for this ticket
841
+		$new_ticket->save();
842
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
843
+		$datetimes_on_existing = $ticket->datetimes();
844
+		$new_ticket            = $this->_update_ticket_datetimes(
845
+			$new_ticket,
846
+			$datetimes_on_existing,
847
+			array_keys($datetimes_on_existing)
848
+		);
849
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
850
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
851
+		// available.
852
+		if ($ticket->sold() > 0) {
853
+			$new_qty = $ticket->qty() - $ticket->sold();
854
+			$new_ticket->set_qty($new_qty);
855
+		}
856
+		// now we update the prices just for this ticket
857
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
858
+		// and we update the base price
859
+		return $this->_add_prices_to_ticket(
860
+			[],
861
+			$new_ticket,
862
+			true,
863
+			$base_price,
864
+			$base_price_id
865
+		);
866
+	}
867
+
868
+
869
+	/**
870
+	 * This attaches a list of given prices to a ticket.
871
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
872
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
873
+	 * price info and prices are automatically "archived" via the ticket.
874
+	 *
875
+	 * @access  private
876
+	 * @param array     $prices        Array of prices from the form.
877
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
878
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
879
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
880
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
881
+	 * @return EE_Ticket
882
+	 * @throws ReflectionException
883
+	 * @throws InvalidArgumentException
884
+	 * @throws InvalidInterfaceException
885
+	 * @throws InvalidDataTypeException
886
+	 * @throws EE_Error
887
+	 */
888
+	protected function _add_prices_to_ticket(
889
+		array $prices,
890
+		EE_Ticket $ticket,
891
+		bool $new_prices = false,
892
+		$base_price = false,
893
+		$base_price_id = false
894
+	): EE_Ticket {
895
+		$price_model = EEM_Price::instance();
896
+		// let's just get any current prices that may exist on the given ticket
897
+		// so we can remove any prices that got trashed in this session.
898
+		$current_prices_on_ticket = $base_price !== false
899
+			? $ticket->base_price(true)
900
+			: $ticket->price_modifiers();
901
+		$updated_prices           = [];
902
+		// if $base_price ! FALSE then updating a base price.
903
+		if ($base_price !== false) {
904
+			$prices[1] = [
905
+				'PRC_ID'     => $new_prices || $base_price_id === 1
906
+					? null
907
+					: $base_price_id,
908
+				'PRT_ID'     => 1,
909
+				'PRC_amount' => $base_price,
910
+				'PRC_name'   => $ticket->get('TKT_name'),
911
+				'PRC_desc'   => $ticket->get('TKT_description'),
912
+			];
913
+		}
914
+		// possibly need to save ticket
915
+		if (! $ticket->ID()) {
916
+			$ticket->save();
917
+		}
918
+		foreach ($prices as $row => $prc) {
919
+			$prt_id = ! empty($prc['PRT_ID'])
920
+				? $prc['PRT_ID']
921
+				: null;
922
+			if (empty($prt_id)) {
923
+				continue;
924
+			} //prices MUST have a price type id.
925
+			$PRC_values = [
926
+				'PRC_ID'         => ! empty($prc['PRC_ID'])
927
+					? $prc['PRC_ID']
928
+					: null,
929
+				'PRT_ID'         => $prt_id,
930
+				'PRC_amount'     => ! empty($prc['PRC_amount'])
931
+					? $prc['PRC_amount']
932
+					: 0,
933
+				'PRC_name'       => ! empty($prc['PRC_name'])
934
+					? $prc['PRC_name']
935
+					: '',
936
+				'PRC_desc'       => ! empty($prc['PRC_desc'])
937
+					? $prc['PRC_desc']
938
+					: '',
939
+				'PRC_is_default' => false,
940
+				// make sure we set PRC_is_default to false for all ticket saves from event_editor
941
+				'PRC_order'      => $row,
942
+			];
943
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
944
+				$PRC_values['PRC_ID'] = 0;
945
+				$price                = EE_Registry::instance()->load_class(
946
+					'Price',
947
+					[$PRC_values],
948
+					false,
949
+					false
950
+				);
951
+			} else {
952
+				$price = $price_model->get_one_by_ID($prc['PRC_ID']);
953
+				// update this price with new values
954
+				foreach ($PRC_values as $field => $value) {
955
+					$price->set($field, $value);
956
+				}
957
+			}
958
+			$price->save();
959
+			$updated_prices[ $price->ID() ] = $price;
960
+			$ticket->_add_relation_to($price, 'Price');
961
+		}
962
+		// now let's remove any prices that got removed from the ticket
963
+		if (! empty($current_prices_on_ticket)) {
964
+			$current          = array_keys($current_prices_on_ticket);
965
+			$updated          = array_keys($updated_prices);
966
+			$prices_to_remove = array_diff($current, $updated);
967
+			if (! empty($prices_to_remove)) {
968
+				foreach ($prices_to_remove as $prc_id) {
969
+					$p = $current_prices_on_ticket[ $prc_id ];
970
+					$ticket->_remove_relation_to($p, 'Price');
971
+					// delete permanently the price
972
+					$p->delete_or_restore();
973
+				}
974
+			}
975
+		}
976
+		return $ticket;
977
+	}
978
+
979
+
980
+	/**
981
+	 * @throws ReflectionException
982
+	 * @throws InvalidArgumentException
983
+	 * @throws InvalidInterfaceException
984
+	 * @throws InvalidDataTypeException
985
+	 * @throws DomainException
986
+	 * @throws EE_Error
987
+	 */
988
+	public function pricing_metabox()
989
+	{
990
+		$event          = $this->_adminpage_obj->get_cpt_model_obj();
991
+		$timezone       = $event instanceof EE_Event
992
+			? $event->timezone_string()
993
+			: null;
994
+		$price_model    = EEM_Price::instance($timezone);
995
+		$ticket_model   = EEM_Ticket::instance($timezone);
996
+		$datetime_model = EEM_Datetime::instance($timezone);
997
+		$all_tickets    = [];
998
+
999
+		// set is_creating_event property.
1000
+		$EVT_ID                   = $event->ID();
1001
+		$this->_is_creating_event = empty($this->_req_data['post']);
1002
+		$existing_datetime_ids    = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = [];
1003
+
1004
+		// default main template args
1005
+		$main_template_args = [
1006
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link(
1007
+				'event_editor_event_datetimes_help_tab',
1008
+				$this->_adminpage_obj->page_slug,
1009
+				$this->_adminpage_obj->get_req_action()
1010
+			),
1011
+
1012
+			// todo need to add a filter to the template for the help text
1013
+			// in the Events_Admin_Page core file so we can add further help
1014
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1015
+				'add_new_dtt_info',
1016
+				$this->_adminpage_obj->page_slug,
1017
+				$this->_adminpage_obj->get_req_action()
1018
+			),
1019
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1020
+			'datetime_rows'            => '',
1021
+			'show_tickets_container'   => '',
1022
+			'ticket_rows'              => '',
1023
+			'ee_collapsible_status'    => ' ee-collapsible-open',
1024
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1025
+		];
1026
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1027
+
1028
+		/**
1029
+		 * 1. Start with retrieving Datetimes
1030
+		 * 2. For each datetime get related tickets
1031
+		 * 3. For each ticket get related prices
1032
+		 */
1033
+		$datetimes                            = $datetime_model->get_all_event_dates($EVT_ID);
1034
+		$main_template_args['total_dtt_rows'] = count($datetimes);
1035
+
1036
+		/**
1037
+		 * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1038
+		 * for why we are counting $datetime_row and then setting that on the Datetime object
1039
+		 */
1040
+		$datetime_row = 1;
1041
+		foreach ($datetimes as $datetime) {
1042
+			$DTT_ID = $datetime->get('DTT_ID');
1043
+			$datetime->set('DTT_order', $datetime_row);
1044
+			$existing_datetime_ids[] = $DTT_ID;
1045
+			// tickets attached
1046
+			$related_tickets = $datetime->ID() > 0
1047
+				? $datetime->get_many_related(
1048
+					'Ticket',
1049
+					[
1050
+						[
1051
+							'OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0],
1052
+						],
1053
+						'default_where_conditions' => 'none',
1054
+						'order_by'                 => ['TKT_order' => 'ASC'],
1055
+					]
1056
+				)
1057
+				: [];
1058
+			// if there are no related tickets this is likely a new event OR auto-draft
1059
+			// event so we need to generate the default tickets because datetimes
1060
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1061
+			// datetime on the event.
1062
+			if (empty($related_tickets) && count($datetimes) < 2) {
1063
+				$related_tickets = $ticket_model->get_all_default_tickets();
1064
+				// this should be ordered by TKT_ID, so let's grab the first default ticket
1065
+				// (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1066
+				$default_prices      = $price_model->get_all_default_prices();
1067
+				$main_default_ticket = reset($related_tickets);
1068
+				if ($main_default_ticket instanceof EE_Ticket) {
1069
+					foreach ($default_prices as $default_price) {
1070
+						if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1071
+							continue;
1072
+						}
1073
+						$main_default_ticket->cache('Price', $default_price);
1074
+					}
1075
+				}
1076
+			}
1077
+			// we can't actually setup rows in this loop yet cause we don't know all
1078
+			// the unique tickets for this event yet (tickets are linked through all datetimes).
1079
+			// So we're going to temporarily cache some of that information.
1080
+			// loop through and setup the ticket rows and make sure the order is set.
1081
+			foreach ($related_tickets as $ticket) {
1082
+				$TKT_ID     = $ticket->get('TKT_ID');
1083
+				$ticket_row = $ticket->get('TKT_row');
1084
+				// we only want unique tickets in our final display!!
1085
+				if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1086
+					$existing_ticket_ids[] = $TKT_ID;
1087
+					$all_tickets[]         = $ticket;
1088
+				}
1089
+				// temporary cache of this ticket info for this datetime for later processing of datetime rows.
1090
+				$datetime_tickets[ $DTT_ID ][] = $ticket_row;
1091
+				// temporary cache of this datetime info for this ticket for later processing of ticket rows.
1092
+				if (
1093
+					! isset($ticket_datetimes[ $TKT_ID ])
1094
+					|| ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1095
+				) {
1096
+					$ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1097
+				}
1098
+			}
1099
+			$datetime_row++;
1100
+		}
1101
+		$main_template_args['total_ticket_rows']     = count($existing_ticket_ids);
1102
+		$main_template_args['existing_ticket_ids']   = implode(',', $existing_ticket_ids);
1103
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1104
+		// sort $all_tickets by order
1105
+		usort(
1106
+			$all_tickets,
1107
+			function (EE_Ticket $a, EE_Ticket $b) {
1108
+				$a_order = (int) $a->get('TKT_order');
1109
+				$b_order = (int) $b->get('TKT_order');
1110
+				if ($a_order === $b_order) {
1111
+					return 0;
1112
+				}
1113
+				return ($a_order < $b_order)
1114
+					? -1
1115
+					: 1;
1116
+			}
1117
+		);
1118
+		// k NOW we have all the data we need for setting up the datetime rows
1119
+		// and ticket rows so we start our datetime loop again.
1120
+		$datetime_row = 1;
1121
+		foreach ($datetimes as $datetime) {
1122
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1123
+				$datetime_row,
1124
+				$datetime,
1125
+				$datetime_tickets,
1126
+				$all_tickets,
1127
+				false,
1128
+				$datetimes
1129
+			);
1130
+			$datetime_row++;
1131
+		}
1132
+		// then loop through all tickets for the ticket rows.
1133
+		$ticket_row = 1;
1134
+		foreach ($all_tickets as $ticket) {
1135
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1136
+				$ticket_row,
1137
+				$ticket,
1138
+				$ticket_datetimes,
1139
+				$datetimes,
1140
+				false,
1141
+				$all_tickets
1142
+			);
1143
+			$ticket_row++;
1144
+		}
1145
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1146
+
1147
+		$status_change_notice = LoaderFactory::getLoader()->getShared(
1148
+			'EventEspresso\core\domain\services\admin\notices\status_change\StatusChangeNotice'
1149
+		);
1150
+
1151
+		$main_template_args['status_change_notice'] = $status_change_notice->display(
1152
+			'__event-editor',
1153
+			'espresso-events'
1154
+		);
1155
+
1156
+		EEH_Template::display_template(
1157
+			PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1158
+			$main_template_args
1159
+		);
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * @param int|string  $datetime_row
1165
+	 * @param EE_Datetime $datetime
1166
+	 * @param array       $datetime_tickets
1167
+	 * @param array       $all_tickets
1168
+	 * @param bool        $default
1169
+	 * @param array       $all_datetimes
1170
+	 * @return string
1171
+	 * @throws DomainException
1172
+	 * @throws EE_Error
1173
+	 * @throws ReflectionException
1174
+	 */
1175
+	protected function _get_datetime_row(
1176
+		$datetime_row,
1177
+		EE_Datetime $datetime,
1178
+		array $datetime_tickets = [],
1179
+		array $all_tickets = [],
1180
+		bool $default = false,
1181
+		array $all_datetimes = []
1182
+	): string {
1183
+		return EEH_Template::display_template(
1184
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1185
+			[
1186
+				'dtt_edit_row'             => $this->_get_dtt_edit_row(
1187
+					$datetime_row,
1188
+					$datetime,
1189
+					$default,
1190
+					$all_datetimes
1191
+				),
1192
+				'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1193
+					$datetime_row,
1194
+					$datetime,
1195
+					$datetime_tickets,
1196
+					$all_tickets,
1197
+					$default
1198
+				),
1199
+				'dtt_row'                  => $default
1200
+					? 'DTTNUM'
1201
+					: $datetime_row,
1202
+			],
1203
+			true
1204
+		);
1205
+	}
1206
+
1207
+
1208
+	/**
1209
+	 * This method is used to generate a datetime fields  edit row.
1210
+	 * The same row is used to generate a row with valid DTT objects
1211
+	 * and the default row that is used as the skeleton by the js.
1212
+	 *
1213
+	 * @param int|string       $datetime_row  The row number for the row being generated.
1214
+	 * @param EE_Datetime|null $datetime
1215
+	 * @param bool             $default       Whether a default row is being generated or not.
1216
+	 * @param EE_Datetime[]    $all_datetimes This is the array of all datetimes used in the editor.
1217
+	 * @return string
1218
+	 * @throws EE_Error
1219
+	 * @throws ReflectionException
1220
+	 */
1221
+	protected function _get_dtt_edit_row(
1222
+		$datetime_row,
1223
+		?EE_Datetime $datetime,
1224
+		bool $default,
1225
+		array $all_datetimes
1226
+	): string {
1227
+		// if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1228
+		$default                     = ! $datetime instanceof EE_Datetime
1229
+			? true
1230
+			: $default;
1231
+		$template_args               = [
1232
+			'dtt_row'              => $default
1233
+				? 'DTTNUM'
1234
+				: $datetime_row,
1235
+			'event_datetimes_name' => $default
1236
+				? 'DTTNAMEATTR'
1237
+				: 'edit_event_datetimes',
1238
+			'edit_dtt_expanded'    => '',
1239
+			'DTT_ID'               => $default
1240
+				? ''
1241
+				: $datetime->ID(),
1242
+			'DTT_name'             => $default
1243
+				? ''
1244
+				: $datetime->get_f('DTT_name'),
1245
+			'DTT_description'      => $default
1246
+				? ''
1247
+				: $datetime->get_raw('DTT_description'),
1248
+			'DTT_EVT_start'        => $default
1249
+				? ''
1250
+				: $datetime->start_date($this->_date_time_format),
1251
+			'DTT_EVT_end'          => $default
1252
+				? ''
1253
+				: $datetime->end_date($this->_date_time_format),
1254
+			'DTT_reg_limit'        => $default
1255
+				? ''
1256
+				: $datetime->get_pretty(
1257
+					'DTT_reg_limit',
1258
+					'input'
1259
+				),
1260
+			'DTT_order'            => $default
1261
+				? 'DTTNUM'
1262
+				: $datetime_row,
1263
+			'dtt_sold'             => $default
1264
+				? '0'
1265
+				: $datetime->get('DTT_sold'),
1266
+			'dtt_reserved'         => $default
1267
+				? '0'
1268
+				: $datetime->reserved(),
1269
+			'can_clone'            => $datetime instanceof EE_Datetime,
1270
+			'can_trash'            => count($all_datetimes) > 1
1271
+									  && $datetime instanceof EE_Datetime
1272
+									  && ! $datetime->get('DTT_sold'),
1273
+			'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1274
+				? 'trash-entity dashicons dashicons-lock'
1275
+				: 'trash-entity dashicons dashicons-post-trash clickable',
1276
+			'reg_list_url'         => $default || ! $datetime->event() instanceof EE_Event
1277
+				? ''
1278
+				: EE_Admin_Page::add_query_args_and_nonce(
1279
+					[
1280
+						'event_id'    => $datetime->event()->ID(),
1281
+						'datetime_id' => $datetime->ID(),
1282
+						'use_filters' => true,
1283
+					],
1284
+					REG_ADMIN_URL
1285
+				),
1286
+		];
1287
+		$template_args['show_trash'] = count($all_datetimes) === 1
1288
+									   && $template_args['trash_icon'] !== 'dashicons dashicons-lock'
1289
+			? 'display:none'
1290
+			: '';
1291
+		// allow filtering of template args at this point.
1292
+		$template_args = apply_filters(
1293
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1294
+			$template_args,
1295
+			$datetime_row,
1296
+			$datetime,
1297
+			$default,
1298
+			$all_datetimes,
1299
+			$this->_is_creating_event
1300
+		);
1301
+		return EEH_Template::display_template(
1302
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1303
+			$template_args,
1304
+			true
1305
+		);
1306
+	}
1307
+
1308
+
1309
+	/**
1310
+	 * @param int|string       $datetime_row
1311
+	 * @param EE_Datetime|null $datetime
1312
+	 * @param array            $datetime_tickets
1313
+	 * @param array            $all_tickets
1314
+	 * @param bool             $default
1315
+	 * @return string
1316
+	 * @throws DomainException
1317
+	 * @throws EE_Error
1318
+	 * @throws ReflectionException
1319
+	 */
1320
+	protected function _get_dtt_attached_tickets_row(
1321
+		$datetime_row,
1322
+		?EE_Datetime $datetime,
1323
+		array $datetime_tickets = [],
1324
+		array $all_tickets = [],
1325
+		bool $default = false
1326
+	): string {
1327
+		$template_args = [
1328
+			'dtt_row'                           => $default
1329
+				? 'DTTNUM'
1330
+				: $datetime_row,
1331
+			'event_datetimes_name'              => $default
1332
+				? 'DTTNAMEATTR'
1333
+				: 'edit_event_datetimes',
1334
+			'DTT_description'                   => $default
1335
+				? ''
1336
+				: $datetime->get_raw('DTT_description'),
1337
+			'datetime_tickets_list'             => $default
1338
+				? '<li class="hidden"></li>'
1339
+				: '',
1340
+			'show_tickets_row'                  => 'display:none;',
1341
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1342
+				'add_new_ticket_via_datetime',
1343
+				$this->_adminpage_obj->page_slug,
1344
+				$this->_adminpage_obj->get_req_action()
1345
+			),
1346
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1347
+			'DTT_ID'                            => $default
1348
+				? ''
1349
+				: $datetime->ID(),
1350
+		];
1351
+		// need to setup the list items (but only if this isn't a default skeleton setup)
1352
+		if (! $default) {
1353
+			$ticket_row = 1;
1354
+			foreach ($all_tickets as $ticket) {
1355
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1356
+					$datetime_row,
1357
+					$ticket_row,
1358
+					$datetime,
1359
+					$ticket,
1360
+					$datetime_tickets
1361
+				);
1362
+				$ticket_row++;
1363
+			}
1364
+		}
1365
+		// filter template args at this point
1366
+		$template_args = apply_filters(
1367
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1368
+			$template_args,
1369
+			$datetime_row,
1370
+			$datetime,
1371
+			$datetime_tickets,
1372
+			$all_tickets,
1373
+			$default,
1374
+			$this->_is_creating_event
1375
+		);
1376
+		return EEH_Template::display_template(
1377
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1378
+			$template_args,
1379
+			true
1380
+		);
1381
+	}
1382
+
1383
+
1384
+	/**
1385
+	 * @param int|string       $datetime_row
1386
+	 * @param int|string       $ticket_row
1387
+	 * @param EE_Datetime|null $datetime
1388
+	 * @param EE_Ticket|null   $ticket
1389
+	 * @param array            $datetime_tickets
1390
+	 * @param bool             $default
1391
+	 * @return string
1392
+	 * @throws EE_Error
1393
+	 * @throws ReflectionException
1394
+	 */
1395
+	protected function _get_datetime_tickets_list_item(
1396
+		$datetime_row,
1397
+		$ticket_row,
1398
+		?EE_Datetime $datetime,
1399
+		?EE_Ticket $ticket,
1400
+		array $datetime_tickets = [],
1401
+		bool $default = false
1402
+	): string {
1403
+		$datetime_tickets = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1404
+			? $datetime_tickets[ $datetime->ID() ]
1405
+			: [];
1406
+		$display_row      = $ticket instanceof EE_Ticket
1407
+			? $ticket->get('TKT_row')
1408
+			: 0;
1409
+		$no_ticket        = $default && empty($ticket);
1410
+		$template_args    = [
1411
+			'dtt_row'                 => $default
1412
+				? 'DTTNUM'
1413
+				: $datetime_row,
1414
+			'tkt_row'                 => $no_ticket
1415
+				? 'TICKETNUM'
1416
+				: $ticket_row,
1417
+			'datetime_ticket_checked' => in_array($display_row, $datetime_tickets, true)
1418
+				? ' checked'
1419
+				: '',
1420
+			'ticket_selected'         => in_array($display_row, $datetime_tickets, true)
1421
+				? ' ticket-selected'
1422
+				: '',
1423
+			'TKT_name'                => $no_ticket
1424
+				? 'TKTNAME'
1425
+				: $ticket->get('TKT_name'),
1426
+			'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1427
+				? ' tkt-status-' . EE_Ticket::onsale
1428
+				: ' tkt-status-' . $ticket->ticket_status(),
1429
+		];
1430
+		// filter template args
1431
+		$template_args = apply_filters(
1432
+			'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1433
+			$template_args,
1434
+			$datetime_row,
1435
+			$ticket_row,
1436
+			$datetime,
1437
+			$ticket,
1438
+			$datetime_tickets,
1439
+			$default,
1440
+			$this->_is_creating_event
1441
+		);
1442
+		return EEH_Template::display_template(
1443
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1444
+			$template_args,
1445
+			true
1446
+		);
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * This generates the ticket row for tickets.
1452
+	 * This same method is used to generate both the actual rows and the js skeleton row
1453
+	 * (when default === true)
1454
+	 *
1455
+	 * @param int|string     $ticket_row       Represents the row number being generated.
1456
+	 * @param EE_Ticket|null $ticket
1457
+	 * @param EE_Datetime[]  $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1458
+	 *                                         or empty for default
1459
+	 * @param EE_Datetime[]  $all_datetimes    All Datetimes on the event or empty for default.
1460
+	 * @param bool           $default          Whether default row being generated or not.
1461
+	 * @param EE_Ticket[]    $all_tickets      This is an array of all tickets attached to the event
1462
+	 *                                         (or empty in the case of defaults)
1463
+	 * @return string
1464
+	 * @throws InvalidArgumentException
1465
+	 * @throws InvalidInterfaceException
1466
+	 * @throws InvalidDataTypeException
1467
+	 * @throws DomainException
1468
+	 * @throws EE_Error
1469
+	 * @throws ReflectionException
1470
+	 */
1471
+	protected function _get_ticket_row(
1472
+		$ticket_row,
1473
+		?EE_Ticket $ticket,
1474
+		array $ticket_datetimes,
1475
+		array $all_datetimes,
1476
+		bool $default = false,
1477
+		array $all_tickets = []
1478
+	): string {
1479
+		// if $ticket is not an instance of EE_Ticket then force default to true.
1480
+		$default = ! $ticket instanceof EE_Ticket
1481
+			? true
1482
+			: $default;
1483
+		$prices  = ! empty($ticket) && ! $default
1484
+			? $ticket->get_many_related(
1485
+				'Price',
1486
+				['default_where_conditions' => 'none', 'order_by' => ['PRC_order' => 'ASC']]
1487
+			)
1488
+			: [];
1489
+		// if there is only one price (which would be the base price)
1490
+		// or NO prices and this ticket is a default ticket,
1491
+		// let's just make sure there are no cached default prices on the object.
1492
+		// This is done by not including any query_params.
1493
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1494
+			$prices = $ticket->prices();
1495
+		}
1496
+		// check if we're dealing with a default ticket in which case
1497
+		// we don't want any starting_ticket_datetime_row values set
1498
+		// (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1499
+		// This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1500
+		$default_datetime = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1501
+		$tkt_datetimes    = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1502
+			? $ticket_datetimes[ $ticket->ID() ]
1503
+			: [];
1504
+		$ticket_subtotal  = $default
1505
+			? 0
1506
+			: $ticket->get_ticket_subtotal();
1507
+		$base_price       = $default
1508
+			? null
1509
+			: $ticket->base_price();
1510
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1511
+		// breaking out complicated condition for ticket_status
1512
+		if ($default) {
1513
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1514
+		} else {
1515
+			$ticket_status_class = $ticket->is_default()
1516
+				? ' tkt-status-' . EE_Ticket::onsale
1517
+				: ' tkt-status-' . $ticket->ticket_status();
1518
+		}
1519
+		// breaking out complicated condition for TKT_taxable
1520
+		if ($default) {
1521
+			$TKT_taxable = '';
1522
+		} else {
1523
+			$TKT_taxable = $ticket->taxable()
1524
+				? 'checked'
1525
+				: '';
1526
+		}
1527
+		if ($default) {
1528
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1529
+		} elseif ($ticket->is_default()) {
1530
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1531
+		} else {
1532
+			$TKT_status = $ticket->ticket_status(true);
1533
+		}
1534
+		if ($default) {
1535
+			$TKT_min = '';
1536
+		} else {
1537
+			$TKT_min = $ticket->min();
1538
+			if ($TKT_min === -1 || $TKT_min === 0) {
1539
+				$TKT_min = '';
1540
+			}
1541
+		}
1542
+		$template_args                 = [
1543
+			'tkt_row'                       => $default
1544
+				? 'TICKETNUM'
1545
+				: $ticket_row,
1546
+			'TKT_order'                     => $default
1547
+				? 'TICKETNUM'
1548
+				: $ticket_row,
1549
+			// on initial page load this will always be the correct order.
1550
+			'tkt_status_class'              => $ticket_status_class,
1551
+			'display_edit_tkt_row'          => 'display:none;',
1552
+			'edit_tkt_expanded'             => '',
1553
+			'edit_tickets_name'             => $default
1554
+				? 'TICKETNAMEATTR'
1555
+				: 'edit_tickets',
1556
+			'TKT_name'                      => $default
1557
+				? ''
1558
+				: $ticket->get_f('TKT_name'),
1559
+			'TKT_start_date'                => $default
1560
+				? ''
1561
+				: $ticket->get_date('TKT_start_date', $this->_date_time_format),
1562
+			'TKT_end_date'                  => $default
1563
+				? ''
1564
+				: $ticket->get_date('TKT_end_date', $this->_date_time_format),
1565
+			'TKT_status'                    => $TKT_status,
1566
+			'TKT_price'                     => $default
1567
+				? ''
1568
+				: EEH_Template::format_currency(
1569
+					$ticket->get_ticket_total_with_taxes(),
1570
+					false,
1571
+					false
1572
+				),
1573
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1574
+			'TKT_price_amount'              => $default
1575
+				? 0
1576
+				: $ticket_subtotal,
1577
+			'TKT_qty'                       => $default
1578
+				? ''
1579
+				: $ticket->get_pretty('TKT_qty', 'symbol'),
1580
+			'TKT_qty_for_input'             => $default
1581
+				? ''
1582
+				: $ticket->get_pretty('TKT_qty', 'input'),
1583
+			'TKT_uses'                      => $default
1584
+				? ''
1585
+				: $ticket->get_pretty('TKT_uses', 'input'),
1586
+			'TKT_min'                       => $TKT_min,
1587
+			'TKT_max'                       => $default
1588
+				? ''
1589
+				: $ticket->get_pretty('TKT_max', 'input'),
1590
+			'TKT_sold'                      => $default
1591
+				? 0
1592
+				: $ticket->tickets_sold(),
1593
+			'TKT_reserved'                  => $default
1594
+				? 0
1595
+				: $ticket->reserved(),
1596
+			'TKT_registrations'             => $default
1597
+				? 0
1598
+				: $ticket->count_registrations(
1599
+					[
1600
+						[
1601
+							'STS_ID' => [
1602
+								'!=',
1603
+								RegStatus::INCOMPLETE,
1604
+							],
1605
+						],
1606
+					]
1607
+				),
1608
+			'TKT_ID'                        => $default
1609
+				? 0
1610
+				: $ticket->ID(),
1611
+			'TKT_description'               => $default
1612
+				? ''
1613
+				: $ticket->get_raw('TKT_description'),
1614
+			'TKT_is_default'                => $default
1615
+				? 0
1616
+				: $ticket->is_default(),
1617
+			'TKT_required'                  => $default
1618
+				? 0
1619
+				: $ticket->required(),
1620
+			'TKT_is_default_selector'       => '',
1621
+			'ticket_price_rows'             => '',
1622
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1623
+				? ''
1624
+				: $base_price->get_pretty('PRC_amount', 'localized_float'),
1625
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price
1626
+				? 0
1627
+				: $base_price->ID(),
1628
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1629
+				? ''
1630
+				: 'display:none;',
1631
+			'show_price_mod_button'         => count($prices) > 1
1632
+											   || ($default && $count_price_mods > 0)
1633
+											   || (! $default && $ticket->deleted())
1634
+				? 'display:none;'
1635
+				: '',
1636
+			'total_price_rows'              => count($prices) > 1
1637
+				? count($prices)
1638
+				: 1,
1639
+			'ticket_datetimes_list'         => $default
1640
+				? '<li class="hidden"></li>'
1641
+				: '',
1642
+			'starting_ticket_datetime_rows' => $default || $default_datetime
1643
+				? ''
1644
+				: implode(',', $tkt_datetimes),
1645
+			'ticket_datetime_rows'          => $default
1646
+				? ''
1647
+				: implode(',', $tkt_datetimes),
1648
+			'existing_ticket_price_ids'     => $default
1649
+				? ''
1650
+				: implode(',', array_keys($prices)),
1651
+			'ticket_template_id'            => $default
1652
+				? 0
1653
+				: $ticket->get('TTM_ID'),
1654
+			'TKT_taxable'                   => $TKT_taxable,
1655
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1656
+				? ''
1657
+				: 'display:none;',
1658
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1659
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1660
+				$ticket_subtotal,
1661
+				false,
1662
+				false
1663
+			),
1664
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1665
+			'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1666
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1667
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1668
+				? ' ticket-archived'
1669
+				: '',
1670
+			'trash_icon'                    => $ticket instanceof EE_Ticket
1671
+											   && $ticket->deleted()
1672
+											   && ! $ticket->is_permanently_deleteable()
1673
+				? 'dashicons dashicons-lock '
1674
+				: 'trash-entity dashicons dashicons-post-trash clickable',
1675
+
1676
+			'can_clone' => $ticket instanceof EE_Ticket && ! $ticket->deleted(),
1677
+			'can_trash' => $ticket instanceof EE_Ticket
1678
+						   && (! $ticket->deleted() && $ticket->is_permanently_deleteable()),
1679
+		];
1680
+		$template_args['trash_hidden'] = count($all_tickets) === 1
1681
+										 && $template_args['trash_icon'] !== 'dashicons dashicons-lock'
1682
+			? 'display:none'
1683
+			: '';
1684
+		// handle rows that should NOT be empty
1685
+		if (empty($template_args['TKT_start_date'])) {
1686
+			// if empty then the start date will be now.
1687
+			$template_args['TKT_start_date']   = date(
1688
+				$this->_date_time_format,
1689
+				current_time('timestamp')
1690
+			);
1691
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1692
+		}
1693
+		if (empty($template_args['TKT_end_date'])) {
1694
+			// get the earliest datetime (if present);
1695
+			$earliest_datetime = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1696
+				? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1697
+					'Datetime',
1698
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1699
+				)
1700
+				: null;
1701
+			if (! empty($earliest_datetime)) {
1702
+				$template_args['TKT_end_date'] = $earliest_datetime->get_datetime(
1703
+					'DTT_EVT_start',
1704
+					$this->_date_time_format
1705
+				);
1706
+			} else {
1707
+				// default so let's just use what's been set for the default date-time which is 30 days from now.
1708
+				$template_args['TKT_end_date'] = date(
1709
+					$this->_date_time_format,
1710
+					mktime(
1711
+						24,
1712
+						0,
1713
+						0,
1714
+						date('m'),
1715
+						date('d') + 29,
1716
+						date('Y')
1717
+					)
1718
+				);
1719
+			}
1720
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1721
+		}
1722
+		// generate ticket_datetime items
1723
+		if (! $default) {
1724
+			$datetime_row = 1;
1725
+			foreach ($all_datetimes as $datetime) {
1726
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1727
+					$datetime_row,
1728
+					$ticket_row,
1729
+					$datetime,
1730
+					$ticket,
1731
+					$ticket_datetimes,
1732
+					$default
1733
+				);
1734
+				$datetime_row++;
1735
+			}
1736
+		}
1737
+		$price_row = 1;
1738
+		foreach ($prices as $price) {
1739
+			if (! $price instanceof EE_Price) {
1740
+				continue;
1741
+			}
1742
+			if ($price->is_base_price()) {
1743
+				$price_row++;
1744
+				continue;
1745
+			}
1746
+
1747
+			$show_trash  = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1748
+			$show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1749
+
1750
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1751
+				$ticket_row,
1752
+				$price_row,
1753
+				$price,
1754
+				$default,
1755
+				$ticket,
1756
+				$show_trash,
1757
+				$show_create
1758
+			);
1759
+			$price_row++;
1760
+		}
1761
+		// filter $template_args
1762
+		$template_args = apply_filters(
1763
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1764
+			$template_args,
1765
+			$ticket_row,
1766
+			$ticket,
1767
+			$ticket_datetimes,
1768
+			$all_datetimes,
1769
+			$default,
1770
+			$all_tickets,
1771
+			$this->_is_creating_event
1772
+		);
1773
+		return EEH_Template::display_template(
1774
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1775
+			$template_args,
1776
+			true
1777
+		);
1778
+	}
1779
+
1780
+
1781
+	/**
1782
+	 * @param int|string     $ticket_row
1783
+	 * @param EE_Ticket|null $ticket
1784
+	 * @return string
1785
+	 * @throws DomainException
1786
+	 * @throws EE_Error
1787
+	 * @throws ReflectionException
1788
+	 */
1789
+	protected function _get_tax_rows($ticket_row, ?EE_Ticket $ticket): string
1790
+	{
1791
+		$tax_rows = '';
1792
+		/** @var EE_Price[] $taxes */
1793
+		$taxes = EE_Taxes::get_taxes_for_admin();
1794
+		foreach ($taxes as $tax) {
1795
+			$tax_added     = $this->_get_tax_added($tax, $ticket);
1796
+			$template_args = [
1797
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1798
+					? ''
1799
+					: 'display:none;',
1800
+				'tax_id'            => $tax->ID(),
1801
+				'tkt_row'           => $ticket_row,
1802
+				'tax_label'         => $tax->get('PRC_name'),
1803
+				'tax_added'         => $tax_added,
1804
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1805
+				'tax_amount'        => $tax->get('PRC_amount'),
1806
+			];
1807
+			$template_args = apply_filters(
1808
+				'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1809
+				$template_args,
1810
+				$ticket_row,
1811
+				$ticket,
1812
+				$this->_is_creating_event
1813
+			);
1814
+			$tax_rows      .= EEH_Template::display_template(
1815
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1816
+				$template_args,
1817
+				true
1818
+			);
1819
+		}
1820
+		return $tax_rows;
1821
+	}
1822
+
1823
+
1824
+	/**
1825
+	 * @param EE_Price       $tax
1826
+	 * @param EE_Ticket|null $ticket
1827
+	 * @return float|int
1828
+	 * @throws EE_Error
1829
+	 * @throws ReflectionException
1830
+	 */
1831
+	protected function _get_tax_added(EE_Price $tax, ?EE_Ticket $ticket)
1832
+	{
1833
+		$subtotal = empty($ticket)
1834
+			? 0
1835
+			: $ticket->get_ticket_subtotal();
1836
+		return $subtotal * $tax->get('PRC_amount') / 100;
1837
+	}
1838
+
1839
+
1840
+	/**
1841
+	 * @param int|string     $ticket_row
1842
+	 * @param int|string     $price_row
1843
+	 * @param EE_Price|null  $price
1844
+	 * @param bool           $default
1845
+	 * @param EE_Ticket|null $ticket
1846
+	 * @param bool           $show_trash
1847
+	 * @param bool           $show_create
1848
+	 * @return string
1849
+	 * @throws InvalidArgumentException
1850
+	 * @throws InvalidInterfaceException
1851
+	 * @throws InvalidDataTypeException
1852
+	 * @throws DomainException
1853
+	 * @throws EE_Error
1854
+	 * @throws ReflectionException
1855
+	 */
1856
+	protected function _get_ticket_price_row(
1857
+		$ticket_row,
1858
+		$price_row,
1859
+		?EE_Price $price,
1860
+		bool $default,
1861
+		?EE_Ticket $ticket,
1862
+		bool $show_trash = true,
1863
+		bool $show_create = true
1864
+	): string {
1865
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1866
+		$template_args = [
1867
+			'tkt_row'               => $default && empty($ticket)
1868
+				? 'TICKETNUM'
1869
+				: $ticket_row,
1870
+			'PRC_order'             => $default && empty($price)
1871
+				? 'PRICENUM'
1872
+				: $price_row,
1873
+			'edit_prices_name'      => $default && empty($price)
1874
+				? 'PRICENAMEATTR'
1875
+				: 'edit_prices',
1876
+			'price_type_selector'   => $this->_get_price_type_selector(
1877
+					$ticket_row,
1878
+					$price_row,
1879
+					$price,
1880
+					$default,
1881
+					$send_disabled
1882
+				),
1883
+			'PRC_ID'                => $default && empty($price)
1884
+				? 0
1885
+				: $price->ID(),
1886
+			'PRC_is_default'        => $default && empty($price)
1887
+				? 0
1888
+				: $price->get('PRC_is_default'),
1889
+			'PRC_name'              => $default && empty($price)
1890
+				? ''
1891
+				: $price->get('PRC_name'),
1892
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1893
+			'show_plus_or_minus'    => $default && empty($price)
1894
+				? ''
1895
+				: 'display:none;',
1896
+			'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1897
+				? 'display:none;'
1898
+				: '',
1899
+			'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1900
+				? 'display:none;'
1901
+				: '',
1902
+			'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1903
+				? 'display:none'
1904
+				: '',
1905
+			'PRC_amount'            => $default && empty($price)
1906
+				? 0
1907
+				: $price->get_pretty('PRC_amount', 'localized_float'),
1908
+			'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1909
+				? 'display:none;'
1910
+				: '',
1911
+			'show_trash_icon'       => $show_trash
1912
+				? ''
1913
+				: ' style="display:none;"',
1914
+			'show_create_button'    => $show_create
1915
+				? ''
1916
+				: ' style="display:none;"',
1917
+			'PRC_desc'              => $default && empty($price)
1918
+				? ''
1919
+				: $price->get('PRC_desc'),
1920
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1921
+		];
1922
+		$template_args = apply_filters(
1923
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1924
+			$template_args,
1925
+			$ticket_row,
1926
+			$price_row,
1927
+			$price,
1928
+			$default,
1929
+			$ticket,
1930
+			$show_trash,
1931
+			$show_create,
1932
+			$this->_is_creating_event
1933
+		);
1934
+		return EEH_Template::display_template(
1935
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1936
+			$template_args,
1937
+			true
1938
+		);
1939
+	}
1940
+
1941
+
1942
+	/**
1943
+	 * @param int|string    $ticket_row
1944
+	 * @param int|string    $price_row
1945
+	 * @param EE_Price|null $price
1946
+	 * @param bool          $default
1947
+	 * @param bool          $disabled
1948
+	 * @return string
1949
+	 * @throws ReflectionException
1950
+	 * @throws InvalidArgumentException
1951
+	 * @throws InvalidInterfaceException
1952
+	 * @throws InvalidDataTypeException
1953
+	 * @throws DomainException
1954
+	 * @throws EE_Error
1955
+	 */
1956
+	protected function _get_price_type_selector(
1957
+		$ticket_row,
1958
+		$price_row,
1959
+		?EE_Price $price,
1960
+		bool $default,
1961
+		bool $disabled = false
1962
+	): string {
1963
+		if (($price instanceof EE_Price && $price->is_base_price()) || (! $price instanceof EE_Price && $default)) {
1964
+			return $this->_get_base_price_template(
1965
+				$ticket_row,
1966
+				$price_row,
1967
+				$price,
1968
+				$default
1969
+			);
1970
+		}
1971
+		return $this->_get_price_modifier_template(
1972
+			$ticket_row,
1973
+			$price_row,
1974
+			$price,
1975
+			$default,
1976
+			$disabled
1977
+		);
1978
+	}
1979
+
1980
+
1981
+	/**
1982
+	 * @param int|string    $ticket_row
1983
+	 * @param int|string    $price_row
1984
+	 * @param EE_Price|null $price
1985
+	 * @param bool          $default
1986
+	 * @return string
1987
+	 * @throws DomainException
1988
+	 * @throws EE_Error
1989
+	 * @throws ReflectionException
1990
+	 */
1991
+	protected function _get_base_price_template(
1992
+		$ticket_row,
1993
+		$price_row,
1994
+		?EE_Price $price,
1995
+		bool $default
1996
+	): string {
1997
+		$template_args = [
1998
+			'tkt_row'                   => $default
1999
+				? 'TICKETNUM'
2000
+				: $ticket_row,
2001
+			'PRC_order'                 => $default && empty($price)
2002
+				? 'PRICENUM'
2003
+				: $price_row,
2004
+			'PRT_ID'                    => $default && empty($price)
2005
+				? 1
2006
+				: $price->get('PRT_ID'),
2007
+			'PRT_name'                  => esc_html__('Price', 'event_espresso'),
2008
+			'price_selected_operator'   => '+',
2009
+			'price_selected_is_percent' => 0,
2010
+		];
2011
+		$template_args = apply_filters(
2012
+			'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
2013
+			$template_args,
2014
+			$ticket_row,
2015
+			$price_row,
2016
+			$price,
2017
+			$default,
2018
+			$this->_is_creating_event
2019
+		);
2020
+		return EEH_Template::display_template(
2021
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
2022
+			$template_args,
2023
+			true
2024
+		);
2025
+	}
2026
+
2027
+
2028
+	/**
2029
+	 * @param int|string    $ticket_row
2030
+	 * @param int|string    $price_row
2031
+	 * @param EE_Price|null $price
2032
+	 * @param bool          $default
2033
+	 * @param bool          $disabled
2034
+	 * @return string
2035
+	 * @throws ReflectionException
2036
+	 * @throws InvalidArgumentException
2037
+	 * @throws InvalidInterfaceException
2038
+	 * @throws InvalidDataTypeException
2039
+	 * @throws DomainException
2040
+	 * @throws EE_Error
2041
+	 */
2042
+	protected function _get_price_modifier_template(
2043
+		$ticket_row,
2044
+		$price_row,
2045
+		?EE_Price $price,
2046
+		bool $default,
2047
+		bool $disabled = false
2048
+	): string {
2049
+		$use_default = $default && ! $price instanceof EE_Price;
2050
+		$selected_price_type_id =  $use_default ? 0 : $price->type();
2051
+
2052
+		$select_name = $use_default
2053
+			? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
2054
+			: 'edit_prices[' . esc_attr($ticket_row) . '][' . esc_attr($price_row) . '][PRT_ID]';
2055
+
2056
+		$price_type_model       = EEM_Price_Type::instance();
2057
+		$price_types = $price_type_model->get_all([['NOT' => ['PBT_ID' => '1']]]);
2058
+		$all_price_types        = $use_default
2059
+			? [esc_html__('Select Modifier', 'event_espresso')]
2060
+			: [];
2061
+		$price_option_spans     = '';
2062
+		// setup price types for selector
2063
+		foreach ($price_types as $price_type) {
2064
+			if (! $price_type instanceof EE_Price_Type) {
2065
+				continue;
2066
+			}
2067
+			$all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
2068
+			// while we're in the loop lets set up the option spans used by js
2069
+			$span_args          = [
2070
+				'PRT_ID'         => $price_type->ID(),
2071
+				'PRT_operator'   => $price_type->is_discount()
2072
+					? '-'
2073
+					: '+',
2074
+				'PRT_is_percent' => $price_type->get('PRT_is_percent')
2075
+					? 1
2076
+					: 0,
2077
+			];
2078
+			$price_option_spans .= EEH_Template::display_template(
2079
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
2080
+				$span_args,
2081
+				true
2082
+			);
2083
+		}
2084
+
2085
+		$select_name = $disabled
2086
+			? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
2087
+			: $select_name;
2088
+
2089
+		$select_input = new EE_Select_Input(
2090
+			$all_price_types,
2091
+			[
2092
+				'default'               => $selected_price_type_id,
2093
+				'html_name'             => $select_name,
2094
+				'html_class'            => 'edit-price-PRT_ID',
2095
+				'other_html_attributes' => $disabled
2096
+					? 'style="width:auto;" disabled'
2097
+					: 'style="width:auto;"',
2098
+			]
2099
+		);
2100
+
2101
+		$price_selected_operator   = $price instanceof EE_Price && $price->is_discount()
2102
+			? '-'
2103
+			: '+';
2104
+		$price_selected_operator   = $use_default
2105
+			? ''
2106
+			: $price_selected_operator;
2107
+		$price_selected_is_percent = $price instanceof EE_Price && $price->is_percent()
2108
+			? 1
2109
+			: 0;
2110
+		$price_selected_is_percent = $use_default
2111
+			? ''
2112
+			: $price_selected_is_percent;
2113
+		$template_args             = [
2114
+			'tkt_row'                   => $default
2115
+				? 'TICKETNUM'
2116
+				: $ticket_row,
2117
+			'PRC_order'                 => $use_default
2118
+				? 'PRICENUM'
2119
+				: $price_row,
2120
+			'price_modifier_selector'   => $select_input->get_html_for_input(),
2121
+			'main_name'                 => $select_name,
2122
+			'selected_price_type_id'    => $selected_price_type_id,
2123
+			'price_option_spans'        => $price_option_spans,
2124
+			'price_selected_operator'   => $price_selected_operator,
2125
+			'price_selected_is_percent' => $price_selected_is_percent,
2126
+			'disabled'                  => $disabled,
2127
+		];
2128
+		$template_args             = apply_filters(
2129
+			'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2130
+			$template_args,
2131
+			$ticket_row,
2132
+			$price_row,
2133
+			$price,
2134
+			$default,
2135
+			$disabled,
2136
+			$this->_is_creating_event
2137
+		);
2138
+		return EEH_Template::display_template(
2139
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2140
+			$template_args,
2141
+			true
2142
+		);
2143
+	}
2144
+
2145
+
2146
+	/**
2147
+	 * @param int|string       $datetime_row
2148
+	 * @param int|string       $ticket_row
2149
+	 * @param EE_Datetime|null $datetime
2150
+	 * @param EE_Ticket|null   $ticket
2151
+	 * @param array            $ticket_datetimes
2152
+	 * @param bool             $default
2153
+	 * @return string
2154
+	 * @throws DomainException
2155
+	 * @throws EE_Error
2156
+	 * @throws ReflectionException
2157
+	 */
2158
+	protected function _get_ticket_datetime_list_item(
2159
+		$datetime_row,
2160
+		$ticket_row,
2161
+		?EE_Datetime $datetime,
2162
+		?EE_Ticket $ticket,
2163
+		array $ticket_datetimes = [],
2164
+		bool $default = false
2165
+	): string {
2166
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2167
+			? $ticket_datetimes[ $ticket->ID() ]
2168
+			: [];
2169
+		$template_args = [
2170
+			'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2171
+				? 'DTTNUM'
2172
+				: $datetime_row,
2173
+			'tkt_row'                  => $default
2174
+				? 'TICKETNUM'
2175
+				: $ticket_row,
2176
+			'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2177
+				? ' ticket-selected'
2178
+				: '',
2179
+			'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2180
+				? ' checked'
2181
+				: '',
2182
+			'DTT_name'                 => $default && empty($datetime)
2183
+				? 'DTTNAME'
2184
+				: $datetime->get_dtt_display_name(true),
2185
+			'tkt_status_class'         => '',
2186
+		];
2187
+		$template_args = apply_filters(
2188
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2189
+			$template_args,
2190
+			$datetime_row,
2191
+			$ticket_row,
2192
+			$datetime,
2193
+			$ticket,
2194
+			$ticket_datetimes,
2195
+			$default,
2196
+			$this->_is_creating_event
2197
+		);
2198
+		return EEH_Template::display_template(
2199
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2200
+			$template_args,
2201
+			true
2202
+		);
2203
+	}
2204
+
2205
+
2206
+	/**
2207
+	 * @param array $all_datetimes
2208
+	 * @param array $all_tickets
2209
+	 * @return string
2210
+	 * @throws ReflectionException
2211
+	 * @throws InvalidArgumentException
2212
+	 * @throws InvalidInterfaceException
2213
+	 * @throws InvalidDataTypeException
2214
+	 * @throws DomainException
2215
+	 * @throws EE_Error
2216
+	 */
2217
+	protected function _get_ticket_js_structure(array $all_datetimes = [], array $all_tickets = []): string
2218
+	{
2219
+		$template_args = [
2220
+			'default_datetime_edit_row' => $this->_get_dtt_edit_row(
2221
+				'DTTNUM',
2222
+				null,
2223
+				true,
2224
+				$all_datetimes
2225
+			),
2226
+			'default_ticket_row'        => $this->_get_ticket_row(
2227
+				'TICKETNUM',
2228
+				null,
2229
+				[],
2230
+				[],
2231
+				true
2232
+			),
2233
+			'default_price_row'         => $this->_get_ticket_price_row(
2234
+				'TICKETNUM',
2235
+				'PRICENUM',
2236
+				null,
2237
+				true,
2238
+				null
2239
+			),
2240
+
2241
+			'default_price_rows'                       => '',
2242
+			'default_base_price_amount'                => 0,
2243
+			'default_base_price_name'                  => '',
2244
+			'default_base_price_description'           => '',
2245
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2246
+				'TICKETNUM',
2247
+				'PRICENUM',
2248
+				null,
2249
+				true
2250
+			),
2251
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2252
+				'DTTNUM',
2253
+				null,
2254
+				[],
2255
+				[],
2256
+				true
2257
+			),
2258
+			'existing_available_datetime_tickets_list' => '',
2259
+			'existing_available_ticket_datetimes_list' => '',
2260
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2261
+				'DTTNUM',
2262
+				'TICKETNUM',
2263
+				null,
2264
+				null,
2265
+				[],
2266
+				true
2267
+			),
2268
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2269
+				'DTTNUM',
2270
+				'TICKETNUM',
2271
+				null,
2272
+				null,
2273
+				[],
2274
+				true
2275
+			),
2276
+		];
2277
+		$ticket_row    = 1;
2278
+		foreach ($all_tickets as $ticket) {
2279
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2280
+				'DTTNUM',
2281
+				$ticket_row,
2282
+				null,
2283
+				$ticket,
2284
+				[],
2285
+				true
2286
+			);
2287
+			$ticket_row++;
2288
+		}
2289
+		$datetime_row = 1;
2290
+		foreach ($all_datetimes as $datetime) {
2291
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2292
+				$datetime_row,
2293
+				'TICKETNUM',
2294
+				$datetime,
2295
+				null,
2296
+				[],
2297
+				true
2298
+			);
2299
+			$datetime_row++;
2300
+		}
2301
+		$price_model    = EEM_Price::instance();
2302
+		$default_prices = $price_model->get_all_default_prices();
2303
+		$price_row      = 1;
2304
+		foreach ($default_prices as $price) {
2305
+			if (! $price instanceof EE_Price) {
2306
+				continue;
2307
+			}
2308
+			if ($price->is_base_price()) {
2309
+				$template_args['default_base_price_amount']      = $price->get_pretty(
2310
+					'PRC_amount',
2311
+					'localized_float'
2312
+				);
2313
+				$template_args['default_base_price_name']        = $price->get('PRC_name');
2314
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
2315
+				$price_row++;
2316
+				continue;
2317
+			}
2318
+
2319
+			$show_trash  = ! ((count($default_prices) > 1 && $price_row === 1) || count($default_prices) === 1);
2320
+			$show_create = ! (count($default_prices) > 1 && count($default_prices) !== $price_row);
2321
+
2322
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2323
+				'TICKETNUM',
2324
+				$price_row,
2325
+				$price,
2326
+				true,
2327
+				null,
2328
+				$show_trash,
2329
+				$show_create
2330
+			);
2331
+			$price_row++;
2332
+		}
2333
+		$template_args = apply_filters(
2334
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2335
+			$template_args,
2336
+			$all_datetimes,
2337
+			$all_tickets,
2338
+			$this->_is_creating_event
2339
+		);
2340
+		return EEH_Template::display_template(
2341
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2342
+			$template_args,
2343
+			true
2344
+		);
2345
+	}
2346 2346
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_List_Table.class.php 1 patch
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -11,114 +11,114 @@
 block discarded – undo
11 11
  */
12 12
 class Extend_Events_Admin_List_Table extends Events_Admin_List_Table
13 13
 {
14
-    protected function _column_name_action_setup(EE_Event $event): array
15
-    {
16
-        $export_query_args = [
17
-            'action' => 'export_events',
18
-            'EVT_ID' => $event->ID(),
19
-        ];
20
-        $export_event_link = EE_Admin_Page::add_query_args_and_nonce($export_query_args, EVENTS_ADMIN_URL);
14
+	protected function _column_name_action_setup(EE_Event $event): array
15
+	{
16
+		$export_query_args = [
17
+			'action' => 'export_events',
18
+			'EVT_ID' => $event->ID(),
19
+		];
20
+		$export_event_link = EE_Admin_Page::add_query_args_and_nonce($export_query_args, EVENTS_ADMIN_URL);
21 21
 
22
-        return parent::_column_name_action_setup($event);
23
-    }
22
+		return parent::_column_name_action_setup($event);
23
+	}
24 24
 
25 25
 
26
-    /**
27
-     * hook into list table filters and provide filters for caffeinated list table
28
-     *
29
-     * @return array                  new filters
30
-     * @throws EE_Error
31
-     * @throws ReflectionException
32
-     */
33
-    protected function _get_table_filters()
34
-    {
35
-        // first month/year filters
36
-        $filters[] = $this->espresso_event_months_dropdown();
37
-        $status    = $this->_req_data['status'] ?? '';
38
-        // active status dropdown
39
-        if ($status !== 'draft') {
40
-            $filters[] = $this->active_status_dropdown($this->_req_data['active_status'] ?? '');
41
-            $filters[] = $this->venuesDropdown($this->_req_data['venue'] ?? '');
42
-        }
43
-        // category filter
44
-        $filters[] = $this->category_dropdown();
45
-        return $filters;
46
-    }
26
+	/**
27
+	 * hook into list table filters and provide filters for caffeinated list table
28
+	 *
29
+	 * @return array                  new filters
30
+	 * @throws EE_Error
31
+	 * @throws ReflectionException
32
+	 */
33
+	protected function _get_table_filters()
34
+	{
35
+		// first month/year filters
36
+		$filters[] = $this->espresso_event_months_dropdown();
37
+		$status    = $this->_req_data['status'] ?? '';
38
+		// active status dropdown
39
+		if ($status !== 'draft') {
40
+			$filters[] = $this->active_status_dropdown($this->_req_data['active_status'] ?? '');
41
+			$filters[] = $this->venuesDropdown($this->_req_data['venue'] ?? '');
42
+		}
43
+		// category filter
44
+		$filters[] = $this->category_dropdown();
45
+		return $filters;
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * espresso_event_months_dropdown
51
-     *
52
-     * @return string                dropdown listing month/year selections for events.
53
-     * @throws EE_Error
54
-     */
55
-    public function espresso_event_months_dropdown(): string
56
-    {
57
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
58
-        // Note we need to include any other filters that are set!
59
-        return EEH_Form_Fields::generate_event_months_dropdown(
60
-            $this->_req_data['month_range'] ?? '',
61
-            $this->_req_data['status'] ?? '',
62
-            $this->_req_data['EVT_CAT'] ?? 0,
63
-            $this->_req_data['active_status'] ?? ''
64
-        );
65
-    }
49
+	/**
50
+	 * espresso_event_months_dropdown
51
+	 *
52
+	 * @return string                dropdown listing month/year selections for events.
53
+	 * @throws EE_Error
54
+	 */
55
+	public function espresso_event_months_dropdown(): string
56
+	{
57
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
58
+		// Note we need to include any other filters that are set!
59
+		return EEH_Form_Fields::generate_event_months_dropdown(
60
+			$this->_req_data['month_range'] ?? '',
61
+			$this->_req_data['status'] ?? '',
62
+			$this->_req_data['EVT_CAT'] ?? 0,
63
+			$this->_req_data['active_status'] ?? ''
64
+		);
65
+	}
66 66
 
67 67
 
68
-    /**
69
-     * returns a list of "active" statuses on the event
70
-     *
71
-     * @param string $current_value whatever the current active status is
72
-     * @return string
73
-     */
74
-    public function active_status_dropdown(string $current_value = ''): string
75
-    {
76
-        $select_name = 'active_status';
77
-        $values      = [
78
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
79
-            'active'   => esc_html__('Active', 'event_espresso'),
80
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
81
-            'expired'  => esc_html__('Expired', 'event_espresso'),
82
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
83
-        ];
68
+	/**
69
+	 * returns a list of "active" statuses on the event
70
+	 *
71
+	 * @param string $current_value whatever the current active status is
72
+	 * @return string
73
+	 */
74
+	public function active_status_dropdown(string $current_value = ''): string
75
+	{
76
+		$select_name = 'active_status';
77
+		$values      = [
78
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
79
+			'active'   => esc_html__('Active', 'event_espresso'),
80
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
81
+			'expired'  => esc_html__('Expired', 'event_espresso'),
82
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
83
+		];
84 84
 
85
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value);
86
-    }
85
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value);
86
+	}
87 87
 
88 88
 
89
-    /**
90
-     * returns a list of "venues"
91
-     *
92
-     * @param string $current_value whatever the current active status is
93
-     * @return string
94
-     * @throws EE_Error
95
-     * @throws ReflectionException
96
-     */
97
-    protected function venuesDropdown(string $current_value = ''): string
98
-    {
99
-        $values = ['' => esc_html__('All Venues', 'event_espresso')];
100
-        // populate the list of venues.
101
-        $venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
89
+	/**
90
+	 * returns a list of "venues"
91
+	 *
92
+	 * @param string $current_value whatever the current active status is
93
+	 * @return string
94
+	 * @throws EE_Error
95
+	 * @throws ReflectionException
96
+	 */
97
+	protected function venuesDropdown(string $current_value = ''): string
98
+	{
99
+		$values = ['' => esc_html__('All Venues', 'event_espresso')];
100
+		// populate the list of venues.
101
+		$venues = EEM_Venue::instance()->get_all(['order_by' => ['VNU_name' => 'ASC']]);
102 102
 
103
-        foreach ($venues as $venue) {
104
-            $values[ $venue->ID() ] = $venue->name();
105
-        }
103
+		foreach ($venues as $venue) {
104
+			$values[ $venue->ID() ] = $venue->name();
105
+		}
106 106
 
107
-        return EEH_Form_Fields::select_input('venue', $values, $current_value);
108
-    }
107
+		return EEH_Form_Fields::select_input('venue', $values, $current_value);
108
+	}
109 109
 
110 110
 
111
-    /**
112
-     * output a dropdown of the categories for the category filter on the event admin list table
113
-     *
114
-     * @return string html
115
-     * @throws EE_Error
116
-     * @throws ReflectionException
117
-     */
118
-    public function category_dropdown(): string
119
-    {
120
-        return EEH_Form_Fields::generate_event_category_dropdown(
121
-            $this->_req_data['EVT_CAT'] ?? -1
122
-        );
123
-    }
111
+	/**
112
+	 * output a dropdown of the categories for the category filter on the event admin list table
113
+	 *
114
+	 * @return string html
115
+	 * @throws EE_Error
116
+	 * @throws ReflectionException
117
+	 */
118
+	public function category_dropdown(): string
119
+	{
120
+		return EEH_Form_Fields::generate_event_category_dropdown(
121
+			$this->_req_data['EVT_CAT'] ?? -1
122
+		);
123
+	}
124 124
 }
Please login to merge, or discard this patch.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +477 added lines, -477 removed lines patch added patch discarded remove patch
@@ -18,229 +18,229 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class EE_Event_Registrations_List_Table extends EE_Registrations_List_Table
20 20
 {
21
-    /**
22
-     * @var Extend_Registrations_Admin_Page
23
-     */
24
-    protected EE_Admin_Page $_admin_page;
25
-
26
-    /**
27
-     * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
-     */
29
-    protected DatetimesForEventCheckIn  $datetimes_for_event;
30
-
31
-    protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
32
-
33
-    /**
34
-     * The DTT_ID if the current view has a specified datetime.
35
-     */
36
-    protected int          $datetime_id = 0;
37
-
38
-    protected ?EE_Datetime $datetime    = null;
39
-
40
-    /**
41
-     * The event ID if one is specified in the request
42
-     */
43
-    protected int       $event_id      = 0;
44
-
45
-    protected ?EE_Event $event         = null;
46
-
47
-    protected bool      $hide_expired  = false;
48
-
49
-    protected bool      $hide_upcoming = false;
50
-
51
-    protected array     $_status       = [];
52
-
53
-
54
-    /**
55
-     * EE_Event_Registrations_List_Table constructor.
56
-     *
57
-     * @param Registrations_Admin_Page $admin_page
58
-     * @throws EE_Error
59
-     * @throws ReflectionException
60
-     */
61
-    public function __construct($admin_page)
62
-    {
63
-        $this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
64
-        $this->resolveRequestVars();
65
-        parent::__construct($admin_page);
66
-    }
67
-
68
-
69
-    /**
70
-     * @throws EE_Error
71
-     * @throws ReflectionException
72
-     * @since 5.0.0.p
73
-     */
74
-    private function resolveRequestVars()
75
-    {
76
-        $this->event_id            = $this->request->getRequestParam('event_id', 0, DataType::INTEGER);
77
-        $this->datetimes_for_event = DatetimesForEventCheckIn::fromEventID($this->event_id);
78
-        // if we're filtering for a specific event and it only has one datetime, then grab its ID
79
-        $this->datetime    = $this->datetimes_for_event->getOneDatetimeForEvent();
80
-        $this->datetime_id = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : 0;
81
-        // else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
82
-        $this->datetime_id = $this->request->getRequestParam(
83
-            'DTT_ID',
84
-            $this->datetime_id,
85
-            DataType::INTEGER
86
-        );
87
-    }
88
-
89
-
90
-    /**
91
-     * @throws EE_Error
92
-     * @throws ReflectionException
93
-     */
94
-    protected function _setup_data()
95
-    {
96
-        $this->_data = $this->_view !== 'trash'
97
-            ? $this->_admin_page->get_event_attendees($this->_per_page)
98
-            : $this->_admin_page->get_event_attendees($this->_per_page, false, true);
99
-
100
-        $this->_all_data_count = $this->_view !== 'trash'
101
-            ? $this->_admin_page->get_event_attendees($this->_per_page, true)
102
-            : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
103
-    }
104
-
105
-
106
-    /**
107
-     * @throws ReflectionException
108
-     * @throws EE_Error
109
-     */
110
-    protected function _set_properties()
111
-    {
112
-        $this->_wp_list_args = [
113
-            'singular' => esc_html__('registrant', 'event_espresso'),
114
-            'plural'   => esc_html__('registrants', 'event_espresso'),
115
-            'ajax'     => true,
116
-            'screen'   => $this->_admin_page->get_current_screen()->id,
117
-        ];
118
-        $columns             = [];
119
-
120
-        $this->_columns = [
121
-            '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
122
-            'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
123
-            'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
124
-            'Event'               => esc_html__('Event', 'event_espresso'),
125
-            'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
126
-            '_REG_final_price'    => esc_html__('Price', 'event_espresso'),
127
-            '_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
128
-            'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
129
-        ];
130
-        // Add/remove columns when an event has been selected
131
-        if (! empty($this->event_id)) {
132
-            // Render a checkbox column
133
-            $columns['cb']              = '<input type="checkbox" />';
134
-            $this->_has_checkbox_column = true;
135
-            // Remove the 'Event' column
136
-            unset($this->_columns['Event']);
137
-        }
138
-        $this->_columns        = array_merge($columns, $this->_columns);
139
-        $this->_primary_column = '_REG_att_checked_in';
140
-
141
-        $csv_report = RegistrationsCsvReportParams::getRequestParams(
142
-            $this->getReturnUrl(),
143
-            $this->_admin_page->get_request_data(),
144
-            $this->event_id,
145
-            $this->datetime_id
146
-        );
147
-        if (! empty($csv_report)) {
148
-            $this->_bottom_buttons['csv_reg_report'] = $csv_report;
149
-        }
150
-
151
-        $this->_sortable_columns = [
152
-            /**
153
-             * Allows users to change the default sort if they wish.
154
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
155
-             * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
156
-             * change the sorts on any list table involving registration contacts.  If you want to only change the filter
157
-             * for a specific list table you can use the provided reference to this object instance.
158
-             */
159
-            'ATT_name' => [
160
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
161
-                true,
162
-                $this,
163
-            ]
164
-                ? ['ATT_lname' => true]
165
-                : ['ATT_fname' => true],
166
-            'Event'    => ['Event.EVT_name' => false],
167
-        ];
168
-        $this->_hidden_columns   = [];
169
-        $this->event             = EEM_Event::instance()->get_one_by_ID($this->event_id);
170
-        if ($this->event instanceof EE_Event) {
171
-            $this->datetimes_for_event = DatetimesForEventCheckIn::fromEvent($this->event);
172
-        }
173
-    }
174
-
175
-
176
-    /**
177
-     * @param EE_Registration $item
178
-     * @return string
179
-     */
180
-    protected function _get_row_class($item): string
181
-    {
182
-        $class = parent::_get_row_class($item);
183
-        if ($this->_has_checkbox_column) {
184
-            $class .= ' has-checkbox-column';
185
-        }
186
-        return $class;
187
-    }
188
-
189
-
190
-    /**
191
-     * @return array
192
-     * @throws EE_Error
193
-     * @throws ReflectionException
194
-     */
195
-    protected function _get_table_filters()
196
-    {
197
-        $filters               = [];
198
-        $this->hide_expired    = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
199
-        $this->hide_upcoming   = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
200
-        $hide_expired_checked  = $this->hide_expired ? 'checked' : '';
201
-        $hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
202
-        // get datetimes for ALL active events (note possible capability restrictions)
203
-        $events          = $this->datetimes_for_event->getAllEvents();
204
-        $event_options[] = [
205
-            'id'   => 0,
206
-            'text' => esc_html__(' - select an event - ', 'event_espresso'),
207
-        ];
208
-        foreach ($events as $event) {
209
-            // any registrations for this event?
210
-            if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
211
-                continue;
212
-            }
213
-            $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
214
-            $upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
215
-
216
-            $event_options[] = [
217
-                'id'    => $event->ID(),
218
-                'text'  => apply_filters(
219
-                    'FHEE__EE_Event_Registrations___get_table_filters__event_name',
220
-                    $event->name(),
221
-                    $event
222
-                ),
223
-                'class' => $expired_class . $upcoming_class,
224
-            ];
225
-            if ($event->ID() === $this->event_id) {
226
-                $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
227
-                $hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
228
-                $this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
229
-                $hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
230
-            }
231
-        }
232
-
233
-        $select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
234
-        $select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
235
-        $select_input = EEH_Form_Fields::select_input(
236
-            'event_id',
237
-            $event_options,
238
-            $this->event_id,
239
-            '',
240
-            $select_class
241
-        );
242
-
243
-        $filters[] = '
21
+	/**
22
+	 * @var Extend_Registrations_Admin_Page
23
+	 */
24
+	protected EE_Admin_Page $_admin_page;
25
+
26
+	/**
27
+	 * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
+	 */
29
+	protected DatetimesForEventCheckIn  $datetimes_for_event;
30
+
31
+	protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
32
+
33
+	/**
34
+	 * The DTT_ID if the current view has a specified datetime.
35
+	 */
36
+	protected int          $datetime_id = 0;
37
+
38
+	protected ?EE_Datetime $datetime    = null;
39
+
40
+	/**
41
+	 * The event ID if one is specified in the request
42
+	 */
43
+	protected int       $event_id      = 0;
44
+
45
+	protected ?EE_Event $event         = null;
46
+
47
+	protected bool      $hide_expired  = false;
48
+
49
+	protected bool      $hide_upcoming = false;
50
+
51
+	protected array     $_status       = [];
52
+
53
+
54
+	/**
55
+	 * EE_Event_Registrations_List_Table constructor.
56
+	 *
57
+	 * @param Registrations_Admin_Page $admin_page
58
+	 * @throws EE_Error
59
+	 * @throws ReflectionException
60
+	 */
61
+	public function __construct($admin_page)
62
+	{
63
+		$this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
64
+		$this->resolveRequestVars();
65
+		parent::__construct($admin_page);
66
+	}
67
+
68
+
69
+	/**
70
+	 * @throws EE_Error
71
+	 * @throws ReflectionException
72
+	 * @since 5.0.0.p
73
+	 */
74
+	private function resolveRequestVars()
75
+	{
76
+		$this->event_id            = $this->request->getRequestParam('event_id', 0, DataType::INTEGER);
77
+		$this->datetimes_for_event = DatetimesForEventCheckIn::fromEventID($this->event_id);
78
+		// if we're filtering for a specific event and it only has one datetime, then grab its ID
79
+		$this->datetime    = $this->datetimes_for_event->getOneDatetimeForEvent();
80
+		$this->datetime_id = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : 0;
81
+		// else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
82
+		$this->datetime_id = $this->request->getRequestParam(
83
+			'DTT_ID',
84
+			$this->datetime_id,
85
+			DataType::INTEGER
86
+		);
87
+	}
88
+
89
+
90
+	/**
91
+	 * @throws EE_Error
92
+	 * @throws ReflectionException
93
+	 */
94
+	protected function _setup_data()
95
+	{
96
+		$this->_data = $this->_view !== 'trash'
97
+			? $this->_admin_page->get_event_attendees($this->_per_page)
98
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
99
+
100
+		$this->_all_data_count = $this->_view !== 'trash'
101
+			? $this->_admin_page->get_event_attendees($this->_per_page, true)
102
+			: $this->_admin_page->get_event_attendees($this->_per_page, true, true);
103
+	}
104
+
105
+
106
+	/**
107
+	 * @throws ReflectionException
108
+	 * @throws EE_Error
109
+	 */
110
+	protected function _set_properties()
111
+	{
112
+		$this->_wp_list_args = [
113
+			'singular' => esc_html__('registrant', 'event_espresso'),
114
+			'plural'   => esc_html__('registrants', 'event_espresso'),
115
+			'ajax'     => true,
116
+			'screen'   => $this->_admin_page->get_current_screen()->id,
117
+		];
118
+		$columns             = [];
119
+
120
+		$this->_columns = [
121
+			'_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
122
+			'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
123
+			'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
124
+			'Event'               => esc_html__('Event', 'event_espresso'),
125
+			'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
126
+			'_REG_final_price'    => esc_html__('Price', 'event_espresso'),
127
+			'_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
128
+			'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
129
+		];
130
+		// Add/remove columns when an event has been selected
131
+		if (! empty($this->event_id)) {
132
+			// Render a checkbox column
133
+			$columns['cb']              = '<input type="checkbox" />';
134
+			$this->_has_checkbox_column = true;
135
+			// Remove the 'Event' column
136
+			unset($this->_columns['Event']);
137
+		}
138
+		$this->_columns        = array_merge($columns, $this->_columns);
139
+		$this->_primary_column = '_REG_att_checked_in';
140
+
141
+		$csv_report = RegistrationsCsvReportParams::getRequestParams(
142
+			$this->getReturnUrl(),
143
+			$this->_admin_page->get_request_data(),
144
+			$this->event_id,
145
+			$this->datetime_id
146
+		);
147
+		if (! empty($csv_report)) {
148
+			$this->_bottom_buttons['csv_reg_report'] = $csv_report;
149
+		}
150
+
151
+		$this->_sortable_columns = [
152
+			/**
153
+			 * Allows users to change the default sort if they wish.
154
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
155
+			 * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
156
+			 * change the sorts on any list table involving registration contacts.  If you want to only change the filter
157
+			 * for a specific list table you can use the provided reference to this object instance.
158
+			 */
159
+			'ATT_name' => [
160
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
161
+				true,
162
+				$this,
163
+			]
164
+				? ['ATT_lname' => true]
165
+				: ['ATT_fname' => true],
166
+			'Event'    => ['Event.EVT_name' => false],
167
+		];
168
+		$this->_hidden_columns   = [];
169
+		$this->event             = EEM_Event::instance()->get_one_by_ID($this->event_id);
170
+		if ($this->event instanceof EE_Event) {
171
+			$this->datetimes_for_event = DatetimesForEventCheckIn::fromEvent($this->event);
172
+		}
173
+	}
174
+
175
+
176
+	/**
177
+	 * @param EE_Registration $item
178
+	 * @return string
179
+	 */
180
+	protected function _get_row_class($item): string
181
+	{
182
+		$class = parent::_get_row_class($item);
183
+		if ($this->_has_checkbox_column) {
184
+			$class .= ' has-checkbox-column';
185
+		}
186
+		return $class;
187
+	}
188
+
189
+
190
+	/**
191
+	 * @return array
192
+	 * @throws EE_Error
193
+	 * @throws ReflectionException
194
+	 */
195
+	protected function _get_table_filters()
196
+	{
197
+		$filters               = [];
198
+		$this->hide_expired    = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
199
+		$this->hide_upcoming   = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
200
+		$hide_expired_checked  = $this->hide_expired ? 'checked' : '';
201
+		$hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
202
+		// get datetimes for ALL active events (note possible capability restrictions)
203
+		$events          = $this->datetimes_for_event->getAllEvents();
204
+		$event_options[] = [
205
+			'id'   => 0,
206
+			'text' => esc_html__(' - select an event - ', 'event_espresso'),
207
+		];
208
+		foreach ($events as $event) {
209
+			// any registrations for this event?
210
+			if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
211
+				continue;
212
+			}
213
+			$expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
214
+			$upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
215
+
216
+			$event_options[] = [
217
+				'id'    => $event->ID(),
218
+				'text'  => apply_filters(
219
+					'FHEE__EE_Event_Registrations___get_table_filters__event_name',
220
+					$event->name(),
221
+					$event
222
+				),
223
+				'class' => $expired_class . $upcoming_class,
224
+			];
225
+			if ($event->ID() === $this->event_id) {
226
+				$this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
227
+				$hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
228
+				$this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
229
+				$hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
230
+			}
231
+		}
232
+
233
+		$select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
234
+		$select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
235
+		$select_input = EEH_Form_Fields::select_input(
236
+			'event_id',
237
+			$event_options,
238
+			$this->event_id,
239
+			'',
240
+			$select_class
241
+		);
242
+
243
+		$filters[] = '
244 244
         <div class="ee-event-filter__wrapper">
245 245
             <label class="ee-event-filter-main-label">
246 246
                 ' . esc_html__('Check-in Status for', 'event_espresso') . '
@@ -250,301 +250,301 @@  discard block
 block discarded – undo
250 250
                     <label for="event_id">' . esc_html__('Event', 'event_espresso') . '</label>
251 251
                     ' . $select_input . '
252 252
                 </span>';
253
-        // DTT datetimes filter
254
-        $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
255
-            $hide_upcoming_checked === 'checked'
256
-        );
257
-        if (count($datetimes_for_event) > 1) {
258
-            $datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
259
-            foreach ($datetimes_for_event as $datetime) {
260
-                if ($datetime instanceof EE_Datetime) {
261
-                    $datetime_string = $datetime->name();
262
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
263
-                    $datetime_string .= $datetime->date_and_time_range();
264
-                    $datetime_string .= $datetime->is_active() ? ' ∗' : '';
265
-                    $datetime_string .= $datetime->is_expired() ? ' «' : '';
266
-                    $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
267
-                    // now put it all together
268
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
269
-                }
270
-            }
271
-            $filters[] = '
253
+		// DTT datetimes filter
254
+		$datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
255
+			$hide_upcoming_checked === 'checked'
256
+		);
257
+		if (count($datetimes_for_event) > 1) {
258
+			$datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
259
+			foreach ($datetimes_for_event as $datetime) {
260
+				if ($datetime instanceof EE_Datetime) {
261
+					$datetime_string = $datetime->name();
262
+					$datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
263
+					$datetime_string .= $datetime->date_and_time_range();
264
+					$datetime_string .= $datetime->is_active() ? ' ∗' : '';
265
+					$datetime_string .= $datetime->is_expired() ? ' «' : '';
266
+					$datetime_string .= $datetime->is_upcoming() ? ' »' : '';
267
+					// now put it all together
268
+					$datetimes[ $datetime->ID() ] = $datetime_string;
269
+				}
270
+			}
271
+			$filters[] = '
272 272
                 <span class="ee-datetime-selector">
273 273
                     <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
274 274
                     ' . EEH_Form_Fields::select_input(
275
-                        'DTT_ID',
276
-                        $datetimes,
277
-                        $this->datetime_id
278
-                    ) . '
275
+						'DTT_ID',
276
+						$datetimes,
277
+						$this->datetime_id
278
+					) . '
279 279
                 </span>';
280
-        }
281
-        $filters[] = '
280
+		}
281
+		$filters[] = '
282 282
                 <span class="ee-hide-upcoming-check">
283 283
                     <label for="js-ee-hide-upcoming-events">
284 284
                         <input type="checkbox" id="js-ee-hide-upcoming-events" name="hide_upcoming" '
285
-                         . $hide_upcoming_checked
286
-                         . '>
285
+						 . $hide_upcoming_checked
286
+						 . '>
287 287
                             '
288
-                         . esc_html__('Hide Upcoming Events', 'event_espresso')
289
-                         . '
288
+						 . esc_html__('Hide Upcoming Events', 'event_espresso')
289
+						 . '
290 290
                     </label>
291 291
                     <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
292 292
                           aria-label="'
293
-                         . esc_html__(
294
-                             'Will not display events with start dates in the future (ie: have not yet begun)',
295
-                             'event_espresso'
296
-                         ) . '"
293
+						 . esc_html__(
294
+							 'Will not display events with start dates in the future (ie: have not yet begun)',
295
+							 'event_espresso'
296
+						 ) . '"
297 297
                     ></span>
298 298
                 </span>
299 299
                 <span class="ee-hide-expired-check">
300 300
                     <label for="js-ee-hide-expired-events">
301 301
                         <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
302
-                         . $hide_expired_checked
303
-                         . '>
302
+						 . $hide_expired_checked
303
+						 . '>
304 304
                             ' . esc_html__('Hide Expired Events', 'event_espresso') . '
305 305
                     </label>
306 306
                     <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
307 307
                           aria-label="'
308
-                         . esc_html__(
309
-                             'Will not display events with end dates in the past (ie: have already finished)',
310
-                             'event_espresso'
311
-                         )
312
-                         . '"
308
+						 . esc_html__(
309
+							 'Will not display events with end dates in the past (ie: have already finished)',
310
+							 'event_espresso'
311
+						 )
312
+						 . '"
313 313
                     ></span>
314 314
                 </span>
315 315
             </div>
316 316
         </div>';
317
-        return $filters;
318
-    }
319
-
320
-
321
-    /**
322
-     * @throws EE_Error
323
-     * @throws ReflectionException
324
-     */
325
-    protected function _add_view_counts()
326
-    {
327
-        $this->_views['all']['count'] = $this->_get_total_event_attendees();
328
-    }
329
-
330
-
331
-    /**
332
-     * @return int
333
-     * @throws EE_Error
334
-     * @throws ReflectionException
335
-     */
336
-    protected function _get_total_event_attendees(): int
337
-    {
338
-        $query_params = [];
339
-        if ($this->event_id) {
340
-            $query_params[0]['EVT_ID'] = $this->event_id;
341
-        }
342
-        // if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
343
-        if ($this->datetime_id) {
344
-            $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
345
-        }
346
-        $status_ids_array          = apply_filters(
347
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
348
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
349
-        );
350
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
351
-        return EEM_Registration::instance()->count($query_params);
352
-    }
353
-
354
-
355
-    /**
356
-     * @param EE_Registration $item
357
-     * @return string
358
-     * @throws EE_Error
359
-     * @throws ReflectionException
360
-     */
361
-    public function column_cb($item): string
362
-    {
363
-        return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
364
-    }
365
-
366
-
367
-    /**
368
-     * column_REG_att_checked_in
369
-     *
370
-     * @param EE_Registration $registration
371
-     * @return string
372
-     * @throws EE_Error
373
-     * @throws InvalidArgumentException
374
-     * @throws InvalidDataTypeException
375
-     * @throws InvalidInterfaceException
376
-     * @throws ReflectionException
377
-     */
378
-    public function column__REG_att_checked_in(EE_Registration $registration): string
379
-    {
380
-        // we need a local variable for the datetime for each row
381
-        // (so that we don't pollute state for the entire table)
382
-        // so let's try to get it from the registration's event
383
-        $DTT_ID = $this->datetime_id;
384
-        if (! $DTT_ID) {
385
-            $reg_ticket_datetimes = $registration->ticket()->datetimes();
386
-            if (count($reg_ticket_datetimes) === 1) {
387
-                $reg_ticket_datetime = reset($reg_ticket_datetimes);
388
-                $DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
389
-            }
390
-        }
391
-
392
-        if (! $DTT_ID) {
393
-            $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
394
-            $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
395
-            $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
396
-        }
397
-
398
-        $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
399
-            $registration,
400
-            $DTT_ID
401
-        );
402
-
403
-        $aria_label     = $checkin_status_dashicon->ariaLabel();
404
-        $dashicon_class = $checkin_status_dashicon->cssClasses();
405
-        $attributes     = ' onClick="return false"';
406
-        $button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
407
-
408
-        if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
409
-            // overwrite the disabled attribute with data attributes for performing checkin
410
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
411
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
412
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
413
-            $button_class .= ' clickable trigger-checkin';
414
-        }
415
-
416
-        $content = '
317
+		return $filters;
318
+	}
319
+
320
+
321
+	/**
322
+	 * @throws EE_Error
323
+	 * @throws ReflectionException
324
+	 */
325
+	protected function _add_view_counts()
326
+	{
327
+		$this->_views['all']['count'] = $this->_get_total_event_attendees();
328
+	}
329
+
330
+
331
+	/**
332
+	 * @return int
333
+	 * @throws EE_Error
334
+	 * @throws ReflectionException
335
+	 */
336
+	protected function _get_total_event_attendees(): int
337
+	{
338
+		$query_params = [];
339
+		if ($this->event_id) {
340
+			$query_params[0]['EVT_ID'] = $this->event_id;
341
+		}
342
+		// if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
343
+		if ($this->datetime_id) {
344
+			$query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
345
+		}
346
+		$status_ids_array          = apply_filters(
347
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
348
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
349
+		);
350
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
351
+		return EEM_Registration::instance()->count($query_params);
352
+	}
353
+
354
+
355
+	/**
356
+	 * @param EE_Registration $item
357
+	 * @return string
358
+	 * @throws EE_Error
359
+	 * @throws ReflectionException
360
+	 */
361
+	public function column_cb($item): string
362
+	{
363
+		return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
364
+	}
365
+
366
+
367
+	/**
368
+	 * column_REG_att_checked_in
369
+	 *
370
+	 * @param EE_Registration $registration
371
+	 * @return string
372
+	 * @throws EE_Error
373
+	 * @throws InvalidArgumentException
374
+	 * @throws InvalidDataTypeException
375
+	 * @throws InvalidInterfaceException
376
+	 * @throws ReflectionException
377
+	 */
378
+	public function column__REG_att_checked_in(EE_Registration $registration): string
379
+	{
380
+		// we need a local variable for the datetime for each row
381
+		// (so that we don't pollute state for the entire table)
382
+		// so let's try to get it from the registration's event
383
+		$DTT_ID = $this->datetime_id;
384
+		if (! $DTT_ID) {
385
+			$reg_ticket_datetimes = $registration->ticket()->datetimes();
386
+			if (count($reg_ticket_datetimes) === 1) {
387
+				$reg_ticket_datetime = reset($reg_ticket_datetimes);
388
+				$DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
389
+			}
390
+		}
391
+
392
+		if (! $DTT_ID) {
393
+			$this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
394
+			$datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
395
+			$DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
396
+		}
397
+
398
+		$checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
399
+			$registration,
400
+			$DTT_ID
401
+		);
402
+
403
+		$aria_label     = $checkin_status_dashicon->ariaLabel();
404
+		$dashicon_class = $checkin_status_dashicon->cssClasses();
405
+		$attributes     = ' onClick="return false"';
406
+		$button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
407
+
408
+		if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
409
+			// overwrite the disabled attribute with data attributes for performing checkin
410
+			$attributes   = 'data-_regid="' . $registration->ID() . '"';
411
+			$attributes   .= ' data-dttid="' . $DTT_ID . '"';
412
+			$attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
413
+			$button_class .= ' clickable trigger-checkin';
414
+		}
415
+
416
+		$content = '
417 417
         <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
418 418
             <span class="' . $dashicon_class . '" ></span>
419 419
         </button>
420 420
         <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
421
-        return $this->columnContent('_REG_att_checked_in', $content, 'center');
422
-    }
423
-
424
-
425
-    /**
426
-     * @param EE_Registration $registration
427
-     * @return string
428
-     * @throws EE_Error
429
-     * @throws ReflectionException
430
-     */
431
-    public function column_ATT_name(EE_Registration $registration): string
432
-    {
433
-        $attendee = $registration->attendee();
434
-        if (! $attendee instanceof EE_Attendee) {
435
-            return esc_html__('No contact record for this registration.', 'event_espresso');
436
-        }
437
-        // edit attendee link
438
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
439
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
440
-            REG_ADMIN_URL
441
-        );
442
-        $name_link    = '
421
+		return $this->columnContent('_REG_att_checked_in', $content, 'center');
422
+	}
423
+
424
+
425
+	/**
426
+	 * @param EE_Registration $registration
427
+	 * @return string
428
+	 * @throws EE_Error
429
+	 * @throws ReflectionException
430
+	 */
431
+	public function column_ATT_name(EE_Registration $registration): string
432
+	{
433
+		$attendee = $registration->attendee();
434
+		if (! $attendee instanceof EE_Attendee) {
435
+			return esc_html__('No contact record for this registration.', 'event_espresso');
436
+		}
437
+		// edit attendee link
438
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
439
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
440
+			REG_ADMIN_URL
441
+		);
442
+		$name_link    = '
443 443
             <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
444 444
             aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
445 445
             </span>';
446
-        $status        = esc_attr($registration->status_ID());
447
-        $name_link    .= $this->caps_handler->userCanEditContacts()
448
-            ? '
446
+		$status        = esc_attr($registration->status_ID());
447
+		$name_link    .= $this->caps_handler->userCanEditContacts()
448
+			? '
449 449
             <a class="ee-aria-tooltip ee-status-color--' . $status . '"
450 450
                href="' . $edit_lnk_url . '"
451 451
                aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
452 452
             >
453 453
                 ' . $registration->attendee()->full_name() . '
454 454
             </a>'
455
-            : $registration->attendee()->full_name();
456
-        $name_link    .= $registration->count() === 1
457
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
458
-            : '';
459
-        // add group details
460
-        $name_link .= '&nbsp;' . sprintf(
461
-            esc_html__('(%s of %s)', 'event_espresso'),
462
-            $registration->count(),
463
-            $registration->group_size()
464
-        );
465
-        // add regcode
466
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
467
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
468
-            REG_ADMIN_URL
469
-        );
470
-        $name_link .= '<br>';
471
-        $name_link .= $this->caps_handler->userCanReadRegistration($registration)
472
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
473
-                'View Registration Details',
474
-                'event_espresso'
475
-            ) . '">'
476
-              . $registration->reg_code()
477
-              . '</a>'
478
-            : $registration->reg_code();
479
-
480
-        $actions = [];
481
-        if ($this->datetime_id && $this->caps_handler->userCanReadRegistrationCheckins()) {
482
-            $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
483
-                ['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $this->datetime_id],
484
-                REG_ADMIN_URL
485
-            );
486
-            // get the timestamps for this registration's checkins, related to the selected datetime
487
-            /** @var EE_Checkin[] $checkins */
488
-            $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
489
-            if (! empty($checkins)) {
490
-                // get the last timestamp
491
-                $last_checkin = end($checkins);
492
-                // get timestamp string
493
-                $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
494
-                $actions['checkin'] = '
455
+			: $registration->attendee()->full_name();
456
+		$name_link    .= $registration->count() === 1
457
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
458
+			: '';
459
+		// add group details
460
+		$name_link .= '&nbsp;' . sprintf(
461
+			esc_html__('(%s of %s)', 'event_espresso'),
462
+			$registration->count(),
463
+			$registration->group_size()
464
+		);
465
+		// add regcode
466
+		$link      = EE_Admin_Page::add_query_args_and_nonce(
467
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
468
+			REG_ADMIN_URL
469
+		);
470
+		$name_link .= '<br>';
471
+		$name_link .= $this->caps_handler->userCanReadRegistration($registration)
472
+			? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
473
+				'View Registration Details',
474
+				'event_espresso'
475
+			) . '">'
476
+			  . $registration->reg_code()
477
+			  . '</a>'
478
+			: $registration->reg_code();
479
+
480
+		$actions = [];
481
+		if ($this->datetime_id && $this->caps_handler->userCanReadRegistrationCheckins()) {
482
+			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
483
+				['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $this->datetime_id],
484
+				REG_ADMIN_URL
485
+			);
486
+			// get the timestamps for this registration's checkins, related to the selected datetime
487
+			/** @var EE_Checkin[] $checkins */
488
+			$checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
489
+			if (! empty($checkins)) {
490
+				// get the last timestamp
491
+				$last_checkin = end($checkins);
492
+				// get timestamp string
493
+				$timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
494
+				$actions['checkin'] = '
495 495
                     <a  class="ee-aria-tooltip"
496 496
                         href="' . $checkin_list_url . '"
497 497
                         aria-label="' . esc_attr__(
498
-                            'View this registrant\'s check-ins/checkouts for the datetime',
499
-                            'event_espresso'
500
-                        ) . '"
498
+							'View this registrant\'s check-ins/checkouts for the datetime',
499
+							'event_espresso'
500
+						) . '"
501 501
                     >
502 502
                         ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
503 503
                     </a>';
504
-            }
505
-        }
506
-        $content = (! empty($this->datetime_id) && ! empty($checkins))
507
-            ? $name_link . $this->row_actions($actions, true)
508
-            : $name_link;
509
-        return $this->columnContent('ATT_name', $content);
510
-    }
511
-
512
-
513
-    /**
514
-     * @param EE_Registration $registration
515
-     * @return string
516
-     * @throws EE_Error
517
-     * @throws ReflectionException
518
-     */
519
-    public function column_Event(EE_Registration $registration): string
520
-    {
521
-        try {
522
-            $event            = $this->event instanceof EE_Event ? $this->event : $registration->event();
523
-            $checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
524
-                ['action' => 'event_registrations', 'event_id' => $event->ID()],
525
-                REG_ADMIN_URL
526
-            );
527
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
528
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
529
-                . esc_attr__(
530
-                    'View Check-ins for this Event',
531
-                    'event_espresso'
532
-                ) . '">' . $event->name() . '</a>' : $event->name();
533
-        } catch (EntityNotFoundException $e) {
534
-            $content = esc_html__('Unknown', 'event_espresso');
535
-        }
536
-        return $this->columnContent('Event', $content);
537
-    }
538
-
539
-
540
-    /**
541
-     * @param EE_Registration $registration
542
-     * @return string
543
-     * @throws EE_Error
544
-     * @throws ReflectionException
545
-     */
546
-    public function column_PRC_name(EE_Registration $registration): string
547
-    {
548
-        return $this->column_REG_ticket($registration);
549
-    }
504
+			}
505
+		}
506
+		$content = (! empty($this->datetime_id) && ! empty($checkins))
507
+			? $name_link . $this->row_actions($actions, true)
508
+			: $name_link;
509
+		return $this->columnContent('ATT_name', $content);
510
+	}
511
+
512
+
513
+	/**
514
+	 * @param EE_Registration $registration
515
+	 * @return string
516
+	 * @throws EE_Error
517
+	 * @throws ReflectionException
518
+	 */
519
+	public function column_Event(EE_Registration $registration): string
520
+	{
521
+		try {
522
+			$event            = $this->event instanceof EE_Event ? $this->event : $registration->event();
523
+			$checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
524
+				['action' => 'event_registrations', 'event_id' => $event->ID()],
525
+				REG_ADMIN_URL
526
+			);
527
+			$content          = $this->caps_handler->userCanReadRegistrationCheckins()
528
+				? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
529
+				. esc_attr__(
530
+					'View Check-ins for this Event',
531
+					'event_espresso'
532
+				) . '">' . $event->name() . '</a>' : $event->name();
533
+		} catch (EntityNotFoundException $e) {
534
+			$content = esc_html__('Unknown', 'event_espresso');
535
+		}
536
+		return $this->columnContent('Event', $content);
537
+	}
538
+
539
+
540
+	/**
541
+	 * @param EE_Registration $registration
542
+	 * @return string
543
+	 * @throws EE_Error
544
+	 * @throws ReflectionException
545
+	 */
546
+	public function column_PRC_name(EE_Registration $registration): string
547
+	{
548
+		return $this->column_REG_ticket($registration);
549
+	}
550 550
 }
Please login to merge, or discard this patch.
Spacing   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
             'ajax'     => true,
116 116
             'screen'   => $this->_admin_page->get_current_screen()->id,
117 117
         ];
118
-        $columns             = [];
118
+        $columns = [];
119 119
 
120 120
         $this->_columns = [
121 121
             '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
             'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
129 129
         ];
130 130
         // Add/remove columns when an event has been selected
131
-        if (! empty($this->event_id)) {
131
+        if ( ! empty($this->event_id)) {
132 132
             // Render a checkbox column
133 133
             $columns['cb']              = '<input type="checkbox" />';
134 134
             $this->_has_checkbox_column = true;
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
             $this->event_id,
145 145
             $this->datetime_id
146 146
         );
147
-        if (! empty($csv_report)) {
147
+        if ( ! empty($csv_report)) {
148 148
             $this->_bottom_buttons['csv_reg_report'] = $csv_report;
149 149
         }
150 150
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
         ];
208 208
         foreach ($events as $event) {
209 209
             // any registrations for this event?
210
-            if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
210
+            if ( ! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
211 211
                 continue;
212 212
             }
213 213
             $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
                     $event->name(),
221 221
                     $event
222 222
                 ),
223
-                'class' => $expired_class . $upcoming_class,
223
+                'class' => $expired_class.$upcoming_class,
224 224
             ];
225 225
             if ($event->ID() === $this->event_id) {
226 226
                 $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
@@ -243,12 +243,12 @@  discard block
 block discarded – undo
243 243
         $filters[] = '
244 244
         <div class="ee-event-filter__wrapper">
245 245
             <label class="ee-event-filter-main-label">
246
-                ' . esc_html__('Check-in Status for', 'event_espresso') . '
246
+                ' . esc_html__('Check-in Status for', 'event_espresso').'
247 247
             </label>
248 248
             <div class="ee-event-filter ee-status-outline ee-status-bg--info">
249 249
                 <span class="ee-event-selector">
250
-                    <label for="event_id">' . esc_html__('Event', 'event_espresso') . '</label>
251
-                    ' . $select_input . '
250
+                    <label for="event_id">' . esc_html__('Event', 'event_espresso').'</label>
251
+                    ' . $select_input.'
252 252
                 </span>';
253 253
         // DTT datetimes filter
254 254
         $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
@@ -259,23 +259,23 @@  discard block
 block discarded – undo
259 259
             foreach ($datetimes_for_event as $datetime) {
260 260
                 if ($datetime instanceof EE_Datetime) {
261 261
                     $datetime_string = $datetime->name();
262
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
262
+                    $datetime_string = ! empty($datetime_string) ? $datetime_string.': ' : '';
263 263
                     $datetime_string .= $datetime->date_and_time_range();
264 264
                     $datetime_string .= $datetime->is_active() ? ' ∗' : '';
265 265
                     $datetime_string .= $datetime->is_expired() ? ' «' : '';
266 266
                     $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
267 267
                     // now put it all together
268
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
268
+                    $datetimes[$datetime->ID()] = $datetime_string;
269 269
                 }
270 270
             }
271 271
             $filters[] = '
272 272
                 <span class="ee-datetime-selector">
273
-                    <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
273
+                    <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso').'</label>
274 274
                     ' . EEH_Form_Fields::select_input(
275 275
                         'DTT_ID',
276 276
                         $datetimes,
277 277
                         $this->datetime_id
278
-                    ) . '
278
+                    ).'
279 279
                 </span>';
280 280
         }
281 281
         $filters[] = '
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
                          . esc_html__(
294 294
                              'Will not display events with start dates in the future (ie: have not yet begun)',
295 295
                              'event_espresso'
296
-                         ) . '"
296
+                         ).'"
297 297
                     ></span>
298 298
                 </span>
299 299
                 <span class="ee-hide-expired-check">
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
                         <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
302 302
                          . $hide_expired_checked
303 303
                          . '>
304
-                            ' . esc_html__('Hide Expired Events', 'event_espresso') . '
304
+                            ' . esc_html__('Hide Expired Events', 'event_espresso').'
305 305
                     </label>
306 306
                     <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
307 307
                           aria-label="'
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
         if ($this->datetime_id) {
344 344
             $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
345 345
         }
346
-        $status_ids_array          = apply_filters(
346
+        $status_ids_array = apply_filters(
347 347
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
348 348
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
349 349
         );
@@ -381,7 +381,7 @@  discard block
 block discarded – undo
381 381
         // (so that we don't pollute state for the entire table)
382 382
         // so let's try to get it from the registration's event
383 383
         $DTT_ID = $this->datetime_id;
384
-        if (! $DTT_ID) {
384
+        if ( ! $DTT_ID) {
385 385
             $reg_ticket_datetimes = $registration->ticket()->datetimes();
386 386
             if (count($reg_ticket_datetimes) === 1) {
387 387
                 $reg_ticket_datetime = reset($reg_ticket_datetimes);
@@ -389,7 +389,7 @@  discard block
 block discarded – undo
389 389
             }
390 390
         }
391 391
 
392
-        if (! $DTT_ID) {
392
+        if ( ! $DTT_ID) {
393 393
             $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
394 394
             $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
395 395
             $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
@@ -407,17 +407,17 @@  discard block
 block discarded – undo
407 407
 
408 408
         if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
409 409
             // overwrite the disabled attribute with data attributes for performing checkin
410
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
411
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
412
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
410
+            $attributes = 'data-_regid="'.$registration->ID().'"';
411
+            $attributes   .= ' data-dttid="'.$DTT_ID.'"';
412
+            $attributes   .= ' data-nonce="'.wp_create_nonce('checkin_nonce').'"';
413 413
             $button_class .= ' clickable trigger-checkin';
414 414
         }
415 415
 
416 416
         $content = '
417
-        <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
418
-            <span class="' . $dashicon_class . '" ></span>
417
+        <button aria-label="' . $aria_label.'" class="'.$button_class.'" '.$attributes.'>
418
+            <span class="' . $dashicon_class.'" ></span>
419 419
         </button>
420
-        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
420
+        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration).'</span>';
421 421
         return $this->columnContent('_REG_att_checked_in', $content, 'center');
422 422
     }
423 423
 
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
     public function column_ATT_name(EE_Registration $registration): string
432 432
     {
433 433
         $attendee = $registration->attendee();
434
-        if (! $attendee instanceof EE_Attendee) {
434
+        if ( ! $attendee instanceof EE_Attendee) {
435 435
             return esc_html__('No contact record for this registration.', 'event_espresso');
436 436
         }
437 437
         // edit attendee link
@@ -439,40 +439,40 @@  discard block
 block discarded – undo
439 439
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
440 440
             REG_ADMIN_URL
441 441
         );
442
-        $name_link    = '
443
-            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
444
-            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
442
+        $name_link = '
443
+            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()).' ee-aria-tooltip"
444
+            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence').'">
445 445
             </span>';
446 446
         $status        = esc_attr($registration->status_ID());
447 447
         $name_link    .= $this->caps_handler->userCanEditContacts()
448 448
             ? '
449
-            <a class="ee-aria-tooltip ee-status-color--' . $status . '"
450
-               href="' . $edit_lnk_url . '"
451
-               aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
449
+            <a class="ee-aria-tooltip ee-status-color--' . $status.'"
450
+               href="' . $edit_lnk_url.'"
451
+               aria-label="' . esc_attr__('View Registration Details', 'event_espresso').'"
452 452
             >
453
-                ' . $registration->attendee()->full_name() . '
453
+                ' . $registration->attendee()->full_name().'
454 454
             </a>'
455 455
             : $registration->attendee()->full_name();
456
-        $name_link    .= $registration->count() === 1
456
+        $name_link .= $registration->count() === 1
457 457
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
458 458
             : '';
459 459
         // add group details
460
-        $name_link .= '&nbsp;' . sprintf(
460
+        $name_link .= '&nbsp;'.sprintf(
461 461
             esc_html__('(%s of %s)', 'event_espresso'),
462 462
             $registration->count(),
463 463
             $registration->group_size()
464 464
         );
465 465
         // add regcode
466
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
466
+        $link = EE_Admin_Page::add_query_args_and_nonce(
467 467
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
468 468
             REG_ADMIN_URL
469 469
         );
470 470
         $name_link .= '<br>';
471 471
         $name_link .= $this->caps_handler->userCanReadRegistration($registration)
472
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
472
+            ? '<a class="ee-aria-tooltip" href="'.$link.'" aria-label="'.esc_attr__(
473 473
                 'View Registration Details',
474 474
                 'event_espresso'
475
-            ) . '">'
475
+            ).'">'
476 476
               . $registration->reg_code()
477 477
               . '</a>'
478 478
             : $registration->reg_code();
@@ -486,25 +486,25 @@  discard block
 block discarded – undo
486 486
             // get the timestamps for this registration's checkins, related to the selected datetime
487 487
             /** @var EE_Checkin[] $checkins */
488 488
             $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
489
-            if (! empty($checkins)) {
489
+            if ( ! empty($checkins)) {
490 490
                 // get the last timestamp
491 491
                 $last_checkin = end($checkins);
492 492
                 // get timestamp string
493 493
                 $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
494 494
                 $actions['checkin'] = '
495 495
                     <a  class="ee-aria-tooltip"
496
-                        href="' . $checkin_list_url . '"
496
+                        href="' . $checkin_list_url.'"
497 497
                         aria-label="' . esc_attr__(
498 498
                             'View this registrant\'s check-ins/checkouts for the datetime',
499 499
                             'event_espresso'
500
-                        ) . '"
500
+                        ).'"
501 501
                     >
502
-                        ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
502
+                        ' . $last_checkin->getCheckInText().': '.$timestamp_string.'
503 503
                     </a>';
504 504
             }
505 505
         }
506
-        $content = (! empty($this->datetime_id) && ! empty($checkins))
507
-            ? $name_link . $this->row_actions($actions, true)
506
+        $content = ( ! empty($this->datetime_id) && ! empty($checkins))
507
+            ? $name_link.$this->row_actions($actions, true)
508 508
             : $name_link;
509 509
         return $this->columnContent('ATT_name', $content);
510 510
     }
@@ -524,12 +524,12 @@  discard block
 block discarded – undo
524 524
                 ['action' => 'event_registrations', 'event_id' => $event->ID()],
525 525
                 REG_ADMIN_URL
526 526
             );
527
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
528
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
527
+            $content = $this->caps_handler->userCanReadRegistrationCheckins()
528
+                ? '<a class="ee-aria-tooltip" href="'.$checkin_link_url.'" aria-label="'
529 529
                 . esc_attr__(
530 530
                     'View Check-ins for this Event',
531 531
                     'event_espresso'
532
-                ) . '">' . $event->name() . '</a>' : $event->name();
532
+                ).'">'.$event->name().'</a>' : $event->name();
533 533
         } catch (EntityNotFoundException $e) {
534 534
             $content = esc_html__('Unknown', 'event_espresso');
535 535
         }
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_Registrations_Admin_Page.core.php 2 patches
Indentation   +1242 added lines, -1242 removed lines patch added patch discarded remove patch
@@ -17,1313 +17,1313 @@
 block discarded – undo
17 17
  */
18 18
 class Extend_Registrations_Admin_Page extends Registrations_Admin_Page
19 19
 {
20
-    /**
21
-     * This is used to hold the reports template data which is setup early in the request.
22
-     *
23
-     * @type array
24
-     */
25
-    protected $_reports_template_data = [];
20
+	/**
21
+	 * This is used to hold the reports template data which is setup early in the request.
22
+	 *
23
+	 * @type array
24
+	 */
25
+	protected $_reports_template_data = [];
26 26
 
27 27
 
28
-    /**
29
-     * Extend_Registrations_Admin_Page constructor.
30
-     *
31
-     * @param bool $routing
32
-     * @throws EE_Error
33
-     * @throws ReflectionException
34
-     */
35
-    public function __construct($routing = true)
36
-    {
37
-        parent::__construct($routing);
38
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
39
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
40
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
41
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
42
-        }
43
-    }
28
+	/**
29
+	 * Extend_Registrations_Admin_Page constructor.
30
+	 *
31
+	 * @param bool $routing
32
+	 * @throws EE_Error
33
+	 * @throws ReflectionException
34
+	 */
35
+	public function __construct($routing = true)
36
+	{
37
+		parent::__construct($routing);
38
+		if (! defined('REG_CAF_TEMPLATE_PATH')) {
39
+			define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
40
+			define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
41
+			define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
42
+		}
43
+	}
44 44
 
45 45
 
46
-    protected function _set_page_config()
47
-    {
48
-        parent::_set_page_config();
46
+	protected function _set_page_config()
47
+	{
48
+		parent::_set_page_config();
49 49
 
50
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
51
-        $reg_id                                           =
52
-            ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
53
-                ? $this->_req_data['_REG_ID']
54
-                : 0;
55
-        $new_page_routes                                  = [
56
-            'reports'                      => [
57
-                'func'       => '_registration_reports',
58
-                'capability' => 'ee_read_registrations',
59
-            ],
60
-            'registration_checkins'        => [
61
-                'func'       => '_registration_checkin_list_table',
62
-                'capability' => 'ee_read_checkins',
63
-            ],
64
-            'newsletter_selected_send'     => [
65
-                'func'       => '_newsletter_selected_send',
66
-                'noheader'   => true,
67
-                'capability' => 'ee_send_message',
68
-            ],
69
-            'delete_checkin_rows'          => [
70
-                'func'       => '_delete_checkin_rows',
71
-                'noheader'   => true,
72
-                'capability' => 'ee_delete_checkins',
73
-            ],
74
-            'delete_checkin_row'           => [
75
-                'func'       => '_delete_checkin_row',
76
-                'noheader'   => true,
77
-                'capability' => 'ee_delete_checkin',
78
-                'obj_id'     => $reg_id,
79
-            ],
80
-            'toggle_checkin_status'        => [
81
-                'func'       => '_toggle_checkin_status',
82
-                'noheader'   => true,
83
-                'capability' => 'ee_edit_checkin',
84
-                'obj_id'     => $reg_id,
85
-            ],
86
-            'toggle_checkin_status_bulk'   => [
87
-                'func'       => '_toggle_checkin_status',
88
-                'noheader'   => true,
89
-                'capability' => 'ee_edit_checkins',
90
-            ],
91
-            'event_registrations'          => [
92
-                'func'       => '_event_registrations_list_table',
93
-                'capability' => 'ee_read_checkins',
94
-            ],
95
-            'registrations_checkin_report' => [
96
-                'func'       => '_registrations_checkin_report',
97
-                'noheader'   => true,
98
-                'capability' => 'ee_read_registrations',
99
-            ],
100
-        ];
101
-        $this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
102
-        $new_page_config                                  = [
103
-            'reports'               => [
104
-                'nav'           => [
105
-                    'label' => esc_html__('Reports', 'event_espresso'),
106
-                    'icon'  => 'dashicons-chart-bar',
107
-                    'order' => 30,
108
-                ],
109
-                'help_tabs'     => [
110
-                    'registrations_reports_help_tab' => [
111
-                        'title'    => esc_html__('Registration Reports', 'event_espresso'),
112
-                        'filename' => 'registrations_reports',
113
-                    ],
114
-                ],
115
-                'require_nonce' => false,
116
-            ],
117
-            'event_registrations'   => [
118
-                'nav'           => [
119
-                    'label'      => esc_html__('Event Check-In', 'event_espresso'),
120
-                    'icon'       => 'dashicons-yes-alt',
121
-                    'order'      => 10,
122
-                    'persistent' => true,
123
-                ],
124
-                'help_tabs'     => [
125
-                    'registrations_event_checkin_help_tab'                       => [
126
-                        'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
127
-                        'filename' => 'registrations_event_checkin',
128
-                    ],
129
-                    'registrations_event_checkin_table_column_headings_help_tab' => [
130
-                        'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
131
-                        'filename' => 'registrations_event_checkin_table_column_headings',
132
-                    ],
133
-                    'registrations_event_checkin_filters_help_tab'               => [
134
-                        'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
135
-                        'filename' => 'registrations_event_checkin_filters',
136
-                    ],
137
-                    'registrations_event_checkin_views_help_tab'                 => [
138
-                        'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
139
-                        'filename' => 'registrations_event_checkin_views',
140
-                    ],
141
-                    'registrations_event_checkin_other_help_tab'                 => [
142
-                        'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
143
-                        'filename' => 'registrations_event_checkin_other',
144
-                    ],
145
-                ],
146
-                'list_table'    => 'EE_Event_Registrations_List_Table',
147
-                'metaboxes'     => [],
148
-                'require_nonce' => false,
149
-            ],
150
-            'registration_checkins' => [
151
-                'nav'           => [
152
-                    'label'      => esc_html__('Check-In Records', 'event_espresso'),
153
-                    'icon'       => 'dashicons-list-view',
154
-                    'order'      => 15,
155
-                    'persistent' => false,
156
-                    'url'        => '',
157
-                ],
158
-                'list_table'    => 'EE_Registration_CheckIn_List_Table',
159
-                'metaboxes'     => [],
160
-                'require_nonce' => false,
161
-            ],
162
-        ];
163
-        $this->_page_config                               = array_merge($this->_page_config, $new_page_config);
164
-        $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
165
-        $this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
166
-    }
50
+		$this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
51
+		$reg_id                                           =
52
+			! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
53
+				? $this->_req_data['_REG_ID']
54
+				: 0;
55
+		$new_page_routes                                  = [
56
+			'reports'                      => [
57
+				'func'       => '_registration_reports',
58
+				'capability' => 'ee_read_registrations',
59
+			],
60
+			'registration_checkins'        => [
61
+				'func'       => '_registration_checkin_list_table',
62
+				'capability' => 'ee_read_checkins',
63
+			],
64
+			'newsletter_selected_send'     => [
65
+				'func'       => '_newsletter_selected_send',
66
+				'noheader'   => true,
67
+				'capability' => 'ee_send_message',
68
+			],
69
+			'delete_checkin_rows'          => [
70
+				'func'       => '_delete_checkin_rows',
71
+				'noheader'   => true,
72
+				'capability' => 'ee_delete_checkins',
73
+			],
74
+			'delete_checkin_row'           => [
75
+				'func'       => '_delete_checkin_row',
76
+				'noheader'   => true,
77
+				'capability' => 'ee_delete_checkin',
78
+				'obj_id'     => $reg_id,
79
+			],
80
+			'toggle_checkin_status'        => [
81
+				'func'       => '_toggle_checkin_status',
82
+				'noheader'   => true,
83
+				'capability' => 'ee_edit_checkin',
84
+				'obj_id'     => $reg_id,
85
+			],
86
+			'toggle_checkin_status_bulk'   => [
87
+				'func'       => '_toggle_checkin_status',
88
+				'noheader'   => true,
89
+				'capability' => 'ee_edit_checkins',
90
+			],
91
+			'event_registrations'          => [
92
+				'func'       => '_event_registrations_list_table',
93
+				'capability' => 'ee_read_checkins',
94
+			],
95
+			'registrations_checkin_report' => [
96
+				'func'       => '_registrations_checkin_report',
97
+				'noheader'   => true,
98
+				'capability' => 'ee_read_registrations',
99
+			],
100
+		];
101
+		$this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
102
+		$new_page_config                                  = [
103
+			'reports'               => [
104
+				'nav'           => [
105
+					'label' => esc_html__('Reports', 'event_espresso'),
106
+					'icon'  => 'dashicons-chart-bar',
107
+					'order' => 30,
108
+				],
109
+				'help_tabs'     => [
110
+					'registrations_reports_help_tab' => [
111
+						'title'    => esc_html__('Registration Reports', 'event_espresso'),
112
+						'filename' => 'registrations_reports',
113
+					],
114
+				],
115
+				'require_nonce' => false,
116
+			],
117
+			'event_registrations'   => [
118
+				'nav'           => [
119
+					'label'      => esc_html__('Event Check-In', 'event_espresso'),
120
+					'icon'       => 'dashicons-yes-alt',
121
+					'order'      => 10,
122
+					'persistent' => true,
123
+				],
124
+				'help_tabs'     => [
125
+					'registrations_event_checkin_help_tab'                       => [
126
+						'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
127
+						'filename' => 'registrations_event_checkin',
128
+					],
129
+					'registrations_event_checkin_table_column_headings_help_tab' => [
130
+						'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
131
+						'filename' => 'registrations_event_checkin_table_column_headings',
132
+					],
133
+					'registrations_event_checkin_filters_help_tab'               => [
134
+						'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
135
+						'filename' => 'registrations_event_checkin_filters',
136
+					],
137
+					'registrations_event_checkin_views_help_tab'                 => [
138
+						'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
139
+						'filename' => 'registrations_event_checkin_views',
140
+					],
141
+					'registrations_event_checkin_other_help_tab'                 => [
142
+						'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
143
+						'filename' => 'registrations_event_checkin_other',
144
+					],
145
+				],
146
+				'list_table'    => 'EE_Event_Registrations_List_Table',
147
+				'metaboxes'     => [],
148
+				'require_nonce' => false,
149
+			],
150
+			'registration_checkins' => [
151
+				'nav'           => [
152
+					'label'      => esc_html__('Check-In Records', 'event_espresso'),
153
+					'icon'       => 'dashicons-list-view',
154
+					'order'      => 15,
155
+					'persistent' => false,
156
+					'url'        => '',
157
+				],
158
+				'list_table'    => 'EE_Registration_CheckIn_List_Table',
159
+				'metaboxes'     => [],
160
+				'require_nonce' => false,
161
+			],
162
+		];
163
+		$this->_page_config                               = array_merge($this->_page_config, $new_page_config);
164
+		$this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
165
+		$this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
166
+	}
167 167
 
168 168
 
169
-    /**
170
-     * Ajax hooks for all routes in this page.
171
-     */
172
-    protected function _ajax_hooks()
173
-    {
174
-        parent::_ajax_hooks();
175
-        add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
176
-    }
169
+	/**
170
+	 * Ajax hooks for all routes in this page.
171
+	 */
172
+	protected function _ajax_hooks()
173
+	{
174
+		parent::_ajax_hooks();
175
+		add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
176
+	}
177 177
 
178 178
 
179
-    /**
180
-     * Global scripts for all routes in this page.
181
-     */
182
-    public function load_scripts_styles()
183
-    {
184
-        parent::load_scripts_styles();
185
-        // if newsletter message type is active then let's add filter and load js for it.
186
-        if (EEH_MSG_Template::is_mt_active('newsletter')) {
187
-            wp_enqueue_style(
188
-                'ee_message_shortcodes',
189
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
190
-                [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
191
-                EVENT_ESPRESSO_VERSION
192
-            );
193
-            // enqueue newsletter js
194
-            wp_enqueue_script(
195
-                'ee-newsletter-trigger',
196
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
197
-                ['ee-dialog'],
198
-                EVENT_ESPRESSO_VERSION,
199
-                true
200
-            );
201
-            // hook in buttons for newsletter message type trigger.
202
-            add_action(
203
-                'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
204
-                [$this, 'add_newsletter_action_buttons'],
205
-                10
206
-            );
207
-        }
208
-    }
179
+	/**
180
+	 * Global scripts for all routes in this page.
181
+	 */
182
+	public function load_scripts_styles()
183
+	{
184
+		parent::load_scripts_styles();
185
+		// if newsletter message type is active then let's add filter and load js for it.
186
+		if (EEH_MSG_Template::is_mt_active('newsletter')) {
187
+			wp_enqueue_style(
188
+				'ee_message_shortcodes',
189
+				EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
190
+				[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
191
+				EVENT_ESPRESSO_VERSION
192
+			);
193
+			// enqueue newsletter js
194
+			wp_enqueue_script(
195
+				'ee-newsletter-trigger',
196
+				REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
197
+				['ee-dialog'],
198
+				EVENT_ESPRESSO_VERSION,
199
+				true
200
+			);
201
+			// hook in buttons for newsletter message type trigger.
202
+			add_action(
203
+				'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
204
+				[$this, 'add_newsletter_action_buttons'],
205
+				10
206
+			);
207
+		}
208
+	}
209 209
 
210 210
 
211
-    /**
212
-     * Scripts and styles for just the reports route.
213
-     */
214
-    public function load_scripts_styles_reports()
215
-    {
216
-        wp_register_script(
217
-            'ee-reg-reports-js',
218
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
219
-            ['google-charts'],
220
-            EVENT_ESPRESSO_VERSION,
221
-            true
222
-        );
223
-        wp_enqueue_script('ee-reg-reports-js');
224
-        $this->_registration_reports_js_setup();
225
-    }
211
+	/**
212
+	 * Scripts and styles for just the reports route.
213
+	 */
214
+	public function load_scripts_styles_reports()
215
+	{
216
+		wp_register_script(
217
+			'ee-reg-reports-js',
218
+			REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
219
+			['google-charts'],
220
+			EVENT_ESPRESSO_VERSION,
221
+			true
222
+		);
223
+		wp_enqueue_script('ee-reg-reports-js');
224
+		$this->_registration_reports_js_setup();
225
+	}
226 226
 
227 227
 
228
-    /**
229
-     * Register screen options for event_registrations route.
230
-     */
231
-    protected function _add_screen_options_event_registrations()
232
-    {
233
-        $this->_per_page_screen_option();
234
-    }
228
+	/**
229
+	 * Register screen options for event_registrations route.
230
+	 */
231
+	protected function _add_screen_options_event_registrations()
232
+	{
233
+		$this->_per_page_screen_option();
234
+	}
235 235
 
236 236
 
237
-    /**
238
-     * Register screen options for registration_checkins route
239
-     */
240
-    protected function _add_screen_options_registration_checkins()
241
-    {
242
-        $page_title              = $this->_admin_page_title;
243
-        $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
244
-        $this->_per_page_screen_option();
245
-        $this->_admin_page_title = $page_title;
246
-    }
237
+	/**
238
+	 * Register screen options for registration_checkins route
239
+	 */
240
+	protected function _add_screen_options_registration_checkins()
241
+	{
242
+		$page_title              = $this->_admin_page_title;
243
+		$this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
244
+		$this->_per_page_screen_option();
245
+		$this->_admin_page_title = $page_title;
246
+	}
247 247
 
248 248
 
249
-    /**
250
-     * Set views property for event_registrations route.
251
-     */
252
-    protected function _set_list_table_views_event_registrations()
253
-    {
254
-        $this->_views = [
255
-            'all' => [
256
-                'slug'        => 'all',
257
-                'label'       => esc_html__('All', 'event_espresso'),
258
-                'count'       => 0,
259
-                'bulk_action' => ! isset($this->_req_data['event_id'])
260
-                    ? []
261
-                    : [
262
-                        'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'),
263
-                    ],
264
-            ],
265
-        ];
266
-    }
249
+	/**
250
+	 * Set views property for event_registrations route.
251
+	 */
252
+	protected function _set_list_table_views_event_registrations()
253
+	{
254
+		$this->_views = [
255
+			'all' => [
256
+				'slug'        => 'all',
257
+				'label'       => esc_html__('All', 'event_espresso'),
258
+				'count'       => 0,
259
+				'bulk_action' => ! isset($this->_req_data['event_id'])
260
+					? []
261
+					: [
262
+						'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'),
263
+					],
264
+			],
265
+		];
266
+	}
267 267
 
268 268
 
269
-    /**
270
-     * Set views property for registration_checkins route.
271
-     */
272
-    protected function _set_list_table_views_registration_checkins()
273
-    {
274
-        $this->_views = [
275
-            'all' => [
276
-                'slug'        => 'all',
277
-                'label'       => esc_html__('All', 'event_espresso'),
278
-                'count'       => 0,
279
-                'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
280
-            ],
281
-        ];
282
-    }
269
+	/**
270
+	 * Set views property for registration_checkins route.
271
+	 */
272
+	protected function _set_list_table_views_registration_checkins()
273
+	{
274
+		$this->_views = [
275
+			'all' => [
276
+				'slug'        => 'all',
277
+				'label'       => esc_html__('All', 'event_espresso'),
278
+				'count'       => 0,
279
+				'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
280
+			],
281
+		];
282
+	}
283 283
 
284 284
 
285
-    /**
286
-     * callback for ajax action.
287
-     *
288
-     * @return void (JSON)
289
-     * @throws EE_Error
290
-     * @throws InvalidArgumentException
291
-     * @throws InvalidDataTypeException
292
-     * @throws InvalidInterfaceException
293
-     * @throws ReflectionException
294
-     * @since 4.3.0
295
-     */
296
-    public function get_newsletter_form_content()
297
-    {
298
-        // do a nonce check cause we're not coming in from an normal route here.
299
-        $nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
300
-            $this->_req_data['get_newsletter_form_content_nonce']
301
-        ) : '';
302
-        $nonce_ref = 'get_newsletter_form_content_nonce';
303
-        $this->_verify_nonce($nonce, $nonce_ref);
304
-        // let's get the mtp for the incoming MTP_ ID
305
-        if (! isset($this->_req_data['GRP_ID'])) {
306
-            EE_Error::add_error(
307
-                esc_html__(
308
-                    'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
309
-                    'event_espresso'
310
-                ),
311
-                __FILE__,
312
-                __FUNCTION__,
313
-                __LINE__
314
-            );
315
-            $this->_template_args['success'] = false;
316
-            $this->_template_args['error']   = true;
317
-            $this->_return_json();
318
-        }
319
-        $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
320
-        if (! $MTPG instanceof EE_Message_Template_Group) {
321
-            EE_Error::add_error(
322
-                sprintf(
323
-                    esc_html__(
324
-                        'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
325
-                        'event_espresso'
326
-                    ),
327
-                    $this->_req_data['GRP_ID']
328
-                ),
329
-                __FILE__,
330
-                __FUNCTION__,
331
-                __LINE__
332
-            );
333
-            $this->_template_args['success'] = false;
334
-            $this->_template_args['error']   = true;
335
-            $this->_return_json();
336
-        }
337
-        $MTPs            = $MTPG->context_templates();
338
-        $MTPs            = $MTPs['attendee'];
339
-        $template_fields = [];
340
-        /** @var EE_Message_Template $MTP */
341
-        foreach ($MTPs as $MTP) {
342
-            $field = $MTP->get('MTP_template_field');
343
-            if ($field === 'content') {
344
-                $content = $MTP->get('MTP_content');
345
-                if (! empty($content['newsletter_content'])) {
346
-                    $template_fields['newsletter_content'] = $content['newsletter_content'];
347
-                }
348
-                continue;
349
-            }
350
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
351
-        }
352
-        $this->_template_args['success'] = true;
353
-        $this->_template_args['error']   = false;
354
-        $this->_template_args['data']    = [
355
-            'batch_message_from'    => $template_fields['from'] ?? '',
356
-            'batch_message_subject' => $template_fields['subject'] ?? '',
357
-            'batch_message_content' => $template_fields['newsletter_content'] ?? '',
358
-        ];
359
-        $this->_return_json();
360
-    }
285
+	/**
286
+	 * callback for ajax action.
287
+	 *
288
+	 * @return void (JSON)
289
+	 * @throws EE_Error
290
+	 * @throws InvalidArgumentException
291
+	 * @throws InvalidDataTypeException
292
+	 * @throws InvalidInterfaceException
293
+	 * @throws ReflectionException
294
+	 * @since 4.3.0
295
+	 */
296
+	public function get_newsletter_form_content()
297
+	{
298
+		// do a nonce check cause we're not coming in from an normal route here.
299
+		$nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
300
+			$this->_req_data['get_newsletter_form_content_nonce']
301
+		) : '';
302
+		$nonce_ref = 'get_newsletter_form_content_nonce';
303
+		$this->_verify_nonce($nonce, $nonce_ref);
304
+		// let's get the mtp for the incoming MTP_ ID
305
+		if (! isset($this->_req_data['GRP_ID'])) {
306
+			EE_Error::add_error(
307
+				esc_html__(
308
+					'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
309
+					'event_espresso'
310
+				),
311
+				__FILE__,
312
+				__FUNCTION__,
313
+				__LINE__
314
+			);
315
+			$this->_template_args['success'] = false;
316
+			$this->_template_args['error']   = true;
317
+			$this->_return_json();
318
+		}
319
+		$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
320
+		if (! $MTPG instanceof EE_Message_Template_Group) {
321
+			EE_Error::add_error(
322
+				sprintf(
323
+					esc_html__(
324
+						'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
325
+						'event_espresso'
326
+					),
327
+					$this->_req_data['GRP_ID']
328
+				),
329
+				__FILE__,
330
+				__FUNCTION__,
331
+				__LINE__
332
+			);
333
+			$this->_template_args['success'] = false;
334
+			$this->_template_args['error']   = true;
335
+			$this->_return_json();
336
+		}
337
+		$MTPs            = $MTPG->context_templates();
338
+		$MTPs            = $MTPs['attendee'];
339
+		$template_fields = [];
340
+		/** @var EE_Message_Template $MTP */
341
+		foreach ($MTPs as $MTP) {
342
+			$field = $MTP->get('MTP_template_field');
343
+			if ($field === 'content') {
344
+				$content = $MTP->get('MTP_content');
345
+				if (! empty($content['newsletter_content'])) {
346
+					$template_fields['newsletter_content'] = $content['newsletter_content'];
347
+				}
348
+				continue;
349
+			}
350
+			$template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
351
+		}
352
+		$this->_template_args['success'] = true;
353
+		$this->_template_args['error']   = false;
354
+		$this->_template_args['data']    = [
355
+			'batch_message_from'    => $template_fields['from'] ?? '',
356
+			'batch_message_subject' => $template_fields['subject'] ?? '',
357
+			'batch_message_content' => $template_fields['newsletter_content'] ?? '',
358
+		];
359
+		$this->_return_json();
360
+	}
361 361
 
362 362
 
363
-    /**
364
-     * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
365
-     *
366
-     * @param EE_Admin_List_Table $list_table
367
-     * @return void
368
-     * @throws InvalidArgumentException
369
-     * @throws InvalidDataTypeException
370
-     * @throws InvalidInterfaceException
371
-     * @since 4.3.0
372
-     */
373
-    public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
374
-    {
375
-        if (
376
-        ! EE_Registry::instance()->CAP->current_user_can(
377
-            'ee_send_message',
378
-            'espresso_registrations_newsletter_selected_send'
379
-        )
380
-        ) {
381
-            return;
382
-        }
383
-        $routes_to_add_to = [
384
-            'contact_list',
385
-            'event_registrations',
386
-            'default',
387
-        ];
388
-        if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
389
-            if (
390
-                ($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
391
-                || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
392
-            ) {
393
-                echo '';
394
-            } else {
395
-                $button_text = sprintf(
396
-                    esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
397
-                    '<span class="send-selected-newsletter-count">0</span>'
398
-                );
399
-                echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
400
-                     . '<span class="dashicons dashicons-email "></span>'
401
-                     . $button_text
402
-                     . '</button>';
403
-                add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
404
-            }
405
-        }
406
-    }
363
+	/**
364
+	 * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
365
+	 *
366
+	 * @param EE_Admin_List_Table $list_table
367
+	 * @return void
368
+	 * @throws InvalidArgumentException
369
+	 * @throws InvalidDataTypeException
370
+	 * @throws InvalidInterfaceException
371
+	 * @since 4.3.0
372
+	 */
373
+	public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
374
+	{
375
+		if (
376
+		! EE_Registry::instance()->CAP->current_user_can(
377
+			'ee_send_message',
378
+			'espresso_registrations_newsletter_selected_send'
379
+		)
380
+		) {
381
+			return;
382
+		}
383
+		$routes_to_add_to = [
384
+			'contact_list',
385
+			'event_registrations',
386
+			'default',
387
+		];
388
+		if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
389
+			if (
390
+				($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
391
+				|| (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
392
+			) {
393
+				echo '';
394
+			} else {
395
+				$button_text = sprintf(
396
+					esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
397
+					'<span class="send-selected-newsletter-count">0</span>'
398
+				);
399
+				echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
400
+					 . '<span class="dashicons dashicons-email "></span>'
401
+					 . $button_text
402
+					 . '</button>';
403
+				add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
404
+			}
405
+		}
406
+	}
407 407
 
408 408
 
409
-    /**
410
-     * @throws DomainException
411
-     * @throws EE_Error
412
-     * @throws InvalidArgumentException
413
-     * @throws InvalidDataTypeException
414
-     * @throws InvalidInterfaceException
415
-     * @throws ReflectionException
416
-     */
417
-    public function newsletter_send_form_skeleton()
418
-    {
419
-        $list_table = $this->_list_table_object;
420
-        $codes      = [];
421
-        // need to templates for the newsletter message type for the template selector.
422
-        $values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
423
-        $mtps     = EEM_Message_Template_Group::instance()->get_all(
424
-            [['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
425
-        );
426
-        foreach ($mtps as $mtp) {
427
-            $name     = $mtp->name();
428
-            $values[] = [
429
-                'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
430
-                'id'   => $mtp->ID(),
431
-            ];
432
-        }
433
-        // need to get a list of shortcodes that are available for the newsletter message type.
434
-        $shortcodes = EEH_MSG_Template::get_shortcodes(
435
-            'newsletter',
436
-            'email',
437
-            [],
438
-            'attendee',
439
-            false
440
-        );
409
+	/**
410
+	 * @throws DomainException
411
+	 * @throws EE_Error
412
+	 * @throws InvalidArgumentException
413
+	 * @throws InvalidDataTypeException
414
+	 * @throws InvalidInterfaceException
415
+	 * @throws ReflectionException
416
+	 */
417
+	public function newsletter_send_form_skeleton()
418
+	{
419
+		$list_table = $this->_list_table_object;
420
+		$codes      = [];
421
+		// need to templates for the newsletter message type for the template selector.
422
+		$values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
423
+		$mtps     = EEM_Message_Template_Group::instance()->get_all(
424
+			[['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
425
+		);
426
+		foreach ($mtps as $mtp) {
427
+			$name     = $mtp->name();
428
+			$values[] = [
429
+				'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
430
+				'id'   => $mtp->ID(),
431
+			];
432
+		}
433
+		// need to get a list of shortcodes that are available for the newsletter message type.
434
+		$shortcodes = EEH_MSG_Template::get_shortcodes(
435
+			'newsletter',
436
+			'email',
437
+			[],
438
+			'attendee',
439
+			false
440
+		);
441 441
 
442
-        foreach ($shortcodes as $field => $shortcode_array) {
443
-            $available_shortcodes = [];
444
-            foreach ($shortcode_array as $shortcode => $shortcode_details) {
445
-                $field_id               = $field === '[NEWSLETTER_CONTENT]'
446
-                    ? 'content'
447
-                    : strtolower($field);
448
-                $field_id               = "batch-message-$field_id";
449
-                $available_shortcodes[] = '
442
+		foreach ($shortcodes as $field => $shortcode_array) {
443
+			$available_shortcodes = [];
444
+			foreach ($shortcode_array as $shortcode => $shortcode_details) {
445
+				$field_id               = $field === '[NEWSLETTER_CONTENT]'
446
+					? 'content'
447
+					: strtolower($field);
448
+				$field_id               = "batch-message-$field_id";
449
+				$available_shortcodes[] = '
450 450
                 <span class="js-shortcode-selection"
451 451
                       data-value="' . $shortcode . '"
452 452
                       data-linked-input-id="' . $field_id . '"
453 453
                 >' . $shortcode . '</span>';
454
-            }
455
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
456
-        }
454
+			}
455
+			$codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
456
+		}
457 457
 
458
-        EEH_Template::display_template(
459
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
460
-            [
461
-                'form_action'       => admin_url('admin.php?page=espresso_registrations'),
462
-                'form_route'        => 'newsletter_selected_send',
463
-                'form_nonce_name'   => 'newsletter_selected_send_nonce',
464
-                'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
465
-                'redirect_back_to'  => $this->_req_action,
466
-                'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
467
-                'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
468
-                'shortcodes'        => $codes,
469
-                'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration',
470
-            ]
471
-        );
472
-    }
458
+		EEH_Template::display_template(
459
+			REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
460
+			[
461
+				'form_action'       => admin_url('admin.php?page=espresso_registrations'),
462
+				'form_route'        => 'newsletter_selected_send',
463
+				'form_nonce_name'   => 'newsletter_selected_send_nonce',
464
+				'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
465
+				'redirect_back_to'  => $this->_req_action,
466
+				'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
467
+				'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
468
+				'shortcodes'        => $codes,
469
+				'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration',
470
+			]
471
+		);
472
+	}
473 473
 
474 474
 
475
-    /**
476
-     * Handles sending selected registrations/contacts a newsletter.
477
-     *
478
-     * @return void
479
-     * @throws EE_Error
480
-     * @throws InvalidArgumentException
481
-     * @throws InvalidDataTypeException
482
-     * @throws InvalidInterfaceException
483
-     * @throws ReflectionException
484
-     * @since  4.3.0
485
-     */
486
-    protected function _newsletter_selected_send()
487
-    {
488
-        $success = true;
489
-        // first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
490
-        if (empty($this->_req_data['newsletter_mtp_selected'])) {
491
-            EE_Error::add_error(
492
-                esc_html__(
493
-                    'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
494
-                    'event_espresso'
495
-                ),
496
-                __FILE__,
497
-                __FUNCTION__,
498
-                __LINE__
499
-            );
500
-            $success = false;
501
-        }
502
-        if ($success) {
503
-            // update Message template in case there are any changes
504
-            $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
505
-                $this->_req_data['newsletter_mtp_selected']
506
-            );
507
-            $Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
508
-                ? $Message_Template_Group->context_templates()
509
-                : [];
510
-            if (empty($Message_Templates)) {
511
-                EE_Error::add_error(
512
-                    esc_html__(
513
-                        'Unable to retrieve message template fields from the db. Messages not sent.',
514
-                        'event_espresso'
515
-                    ),
516
-                    __FILE__,
517
-                    __FUNCTION__,
518
-                    __LINE__
519
-                );
520
-            }
521
-            // let's just update the specific fields
522
-            foreach ($Message_Templates['attendee'] as $Message_Template) {
523
-                if ($Message_Template instanceof EE_Message_Template) {
524
-                    $field       = $Message_Template->get('MTP_template_field');
525
-                    $content     = $Message_Template->get('MTP_content');
526
-                    $new_content = $content;
527
-                    switch ($field) {
528
-                        case 'from':
529
-                            $new_content = ! empty($this->_req_data['batch_message']['from'])
530
-                                ? $this->_req_data['batch_message']['from']
531
-                                : $content;
532
-                            break;
533
-                        case 'subject':
534
-                            $new_content = ! empty($this->_req_data['batch_message']['subject'])
535
-                                ? $this->_req_data['batch_message']['subject']
536
-                                : $content;
537
-                            break;
538
-                        case 'content':
539
-                            $new_content                       = $content;
540
-                            $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
541
-                                ? $this->_req_data['batch_message']['content']
542
-                                : $content['newsletter_content'];
543
-                            break;
544
-                        default:
545
-                            // continue the foreach loop, we don't want to set $new_content nor save.
546
-                            continue 2;
547
-                    }
548
-                    $Message_Template->set('MTP_content', $new_content);
549
-                    $Message_Template->save();
550
-                }
551
-            }
552
-            // great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
553
-            $id_type = ! empty($this->_req_data['batch_message']['id_type'])
554
-                ? $this->_req_data['batch_message']['id_type']
555
-                : 'registration';
556
-            // id_type will affect how we assemble the ids.
557
-            $ids                                 = ! empty($this->_req_data['batch_message']['ids'])
558
-                ? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
559
-                : [];
560
-            $registrations_used_for_contact_data = [];
561
-            // using switch because eventually we'll have other contexts that will be used for generating messages.
562
-            switch ($id_type) {
563
-                case 'registration':
564
-                    $registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
565
-                        [
566
-                            [
567
-                                'REG_ID' => ['IN', $ids],
568
-                            ],
569
-                        ]
570
-                    );
571
-                    break;
572
-                case 'contact':
573
-                    $registrations_used_for_contact_data = EEM_Registration::instance()
574
-                                                                           ->get_latest_registration_for_each_of_given_contacts(
575
-                                                                               $ids
576
-                                                                           );
577
-                    break;
578
-            }
579
-            do_action_ref_array(
580
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
581
-                [
582
-                    $registrations_used_for_contact_data,
583
-                    $Message_Template_Group->ID(),
584
-                ]
585
-            );
586
-            // kept for backward compat, internally we no longer use this action.
587
-            // @deprecated 4.8.36.rc.002
588
-            $contacts = $id_type === 'registration'
589
-                ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
590
-                : EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
591
-            do_action_ref_array(
592
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
593
-                [
594
-                    $contacts,
595
-                    $Message_Template_Group->ID(),
596
-                ]
597
-            );
598
-        }
599
-        $query_args = [
600
-            'action' => ! empty($this->_req_data['redirect_back_to'])
601
-                ? $this->_req_data['redirect_back_to']
602
-                : 'default',
603
-        ];
604
-        $this->_redirect_after_action(false, '', '', $query_args, true);
605
-    }
475
+	/**
476
+	 * Handles sending selected registrations/contacts a newsletter.
477
+	 *
478
+	 * @return void
479
+	 * @throws EE_Error
480
+	 * @throws InvalidArgumentException
481
+	 * @throws InvalidDataTypeException
482
+	 * @throws InvalidInterfaceException
483
+	 * @throws ReflectionException
484
+	 * @since  4.3.0
485
+	 */
486
+	protected function _newsletter_selected_send()
487
+	{
488
+		$success = true;
489
+		// first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
490
+		if (empty($this->_req_data['newsletter_mtp_selected'])) {
491
+			EE_Error::add_error(
492
+				esc_html__(
493
+					'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
494
+					'event_espresso'
495
+				),
496
+				__FILE__,
497
+				__FUNCTION__,
498
+				__LINE__
499
+			);
500
+			$success = false;
501
+		}
502
+		if ($success) {
503
+			// update Message template in case there are any changes
504
+			$Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
505
+				$this->_req_data['newsletter_mtp_selected']
506
+			);
507
+			$Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
508
+				? $Message_Template_Group->context_templates()
509
+				: [];
510
+			if (empty($Message_Templates)) {
511
+				EE_Error::add_error(
512
+					esc_html__(
513
+						'Unable to retrieve message template fields from the db. Messages not sent.',
514
+						'event_espresso'
515
+					),
516
+					__FILE__,
517
+					__FUNCTION__,
518
+					__LINE__
519
+				);
520
+			}
521
+			// let's just update the specific fields
522
+			foreach ($Message_Templates['attendee'] as $Message_Template) {
523
+				if ($Message_Template instanceof EE_Message_Template) {
524
+					$field       = $Message_Template->get('MTP_template_field');
525
+					$content     = $Message_Template->get('MTP_content');
526
+					$new_content = $content;
527
+					switch ($field) {
528
+						case 'from':
529
+							$new_content = ! empty($this->_req_data['batch_message']['from'])
530
+								? $this->_req_data['batch_message']['from']
531
+								: $content;
532
+							break;
533
+						case 'subject':
534
+							$new_content = ! empty($this->_req_data['batch_message']['subject'])
535
+								? $this->_req_data['batch_message']['subject']
536
+								: $content;
537
+							break;
538
+						case 'content':
539
+							$new_content                       = $content;
540
+							$new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
541
+								? $this->_req_data['batch_message']['content']
542
+								: $content['newsletter_content'];
543
+							break;
544
+						default:
545
+							// continue the foreach loop, we don't want to set $new_content nor save.
546
+							continue 2;
547
+					}
548
+					$Message_Template->set('MTP_content', $new_content);
549
+					$Message_Template->save();
550
+				}
551
+			}
552
+			// great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
553
+			$id_type = ! empty($this->_req_data['batch_message']['id_type'])
554
+				? $this->_req_data['batch_message']['id_type']
555
+				: 'registration';
556
+			// id_type will affect how we assemble the ids.
557
+			$ids                                 = ! empty($this->_req_data['batch_message']['ids'])
558
+				? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
559
+				: [];
560
+			$registrations_used_for_contact_data = [];
561
+			// using switch because eventually we'll have other contexts that will be used for generating messages.
562
+			switch ($id_type) {
563
+				case 'registration':
564
+					$registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
565
+						[
566
+							[
567
+								'REG_ID' => ['IN', $ids],
568
+							],
569
+						]
570
+					);
571
+					break;
572
+				case 'contact':
573
+					$registrations_used_for_contact_data = EEM_Registration::instance()
574
+																		   ->get_latest_registration_for_each_of_given_contacts(
575
+																			   $ids
576
+																		   );
577
+					break;
578
+			}
579
+			do_action_ref_array(
580
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
581
+				[
582
+					$registrations_used_for_contact_data,
583
+					$Message_Template_Group->ID(),
584
+				]
585
+			);
586
+			// kept for backward compat, internally we no longer use this action.
587
+			// @deprecated 4.8.36.rc.002
588
+			$contacts = $id_type === 'registration'
589
+				? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
590
+				: EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
591
+			do_action_ref_array(
592
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
593
+				[
594
+					$contacts,
595
+					$Message_Template_Group->ID(),
596
+				]
597
+			);
598
+		}
599
+		$query_args = [
600
+			'action' => ! empty($this->_req_data['redirect_back_to'])
601
+				? $this->_req_data['redirect_back_to']
602
+				: 'default',
603
+		];
604
+		$this->_redirect_after_action(false, '', '', $query_args, true);
605
+	}
606 606
 
607 607
 
608
-    /**
609
-     * This is called when javascript is being enqueued to setup the various data needed for the reports js.
610
-     * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
611
-     */
612
-    protected function _registration_reports_js_setup()
613
-    {
614
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
615
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
616
-    }
608
+	/**
609
+	 * This is called when javascript is being enqueued to setup the various data needed for the reports js.
610
+	 * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
611
+	 */
612
+	protected function _registration_reports_js_setup()
613
+	{
614
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
615
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
616
+	}
617 617
 
618 618
 
619
-    /**
620
-     *        generates Business Reports regarding Registrations
621
-     *
622
-     * @access protected
623
-     * @return void
624
-     * @throws DomainException
625
-     * @throws EE_Error
626
-     */
627
-    protected function _registration_reports()
628
-    {
629
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
630
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
631
-            $template_path,
632
-            $this->_reports_template_data,
633
-            true
634
-        );
635
-        // the final template wrapper
636
-        $this->display_admin_page_with_no_sidebar();
637
-    }
619
+	/**
620
+	 *        generates Business Reports regarding Registrations
621
+	 *
622
+	 * @access protected
623
+	 * @return void
624
+	 * @throws DomainException
625
+	 * @throws EE_Error
626
+	 */
627
+	protected function _registration_reports()
628
+	{
629
+		$template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
630
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
631
+			$template_path,
632
+			$this->_reports_template_data,
633
+			true
634
+		);
635
+		// the final template wrapper
636
+		$this->display_admin_page_with_no_sidebar();
637
+	}
638 638
 
639 639
 
640
-    /**
641
-     * Generates Business Report showing total registrations per day.
642
-     *
643
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
644
-     * @return string
645
-     * @throws EE_Error
646
-     * @throws InvalidArgumentException
647
-     * @throws InvalidDataTypeException
648
-     * @throws InvalidInterfaceException
649
-     * @throws ReflectionException
650
-     */
651
-    private function _registrations_per_day_report($period = '-1 month')
652
-    {
653
-        $report_ID = 'reg-admin-registrations-per-day-report-dv';
654
-        $results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
655
-        $results   = (array) $results;
656
-        $regs      = [];
657
-        $subtitle  = '';
658
-        if ($results) {
659
-            $column_titles = [];
660
-            $tracker       = 0;
661
-            foreach ($results as $result) {
662
-                $report_column_values = [];
663
-                foreach ($result as $property_name => $property_value) {
664
-                    $property_value         = $property_name === 'Registration_REG_date' ? $property_value
665
-                        : (int) $property_value;
666
-                    $report_column_values[] = $property_value;
667
-                    if ($tracker === 0) {
668
-                        if ($property_name === 'Registration_REG_date') {
669
-                            $column_titles[] = esc_html__(
670
-                                'Date (only days with registrations are shown)',
671
-                                'event_espresso'
672
-                            );
673
-                        } else {
674
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
675
-                        }
676
-                    }
677
-                }
678
-                $tracker++;
679
-                $regs[] = $report_column_values;
680
-            }
681
-            // make sure the column_titles is pushed to the beginning of the array
682
-            array_unshift($regs, $column_titles);
683
-            // setup the date range.
684
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
685
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
686
-            $ending_date    = new DateTime("now", $DateTimeZone);
687
-            $subtitle       = sprintf(
688
-                wp_strip_all_tags(
689
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
690
-                ),
691
-                $beginning_date->format('Y-m-d'),
692
-                $ending_date->format('Y-m-d')
693
-            );
694
-        }
695
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
696
-        $report_params = [
697
-            'title'     => $report_title,
698
-            'subtitle'  => $subtitle,
699
-            'id'        => $report_ID,
700
-            'regs'      => $regs,
701
-            'noResults' => empty($regs),
702
-            'noRegsMsg' => sprintf(
703
-                wp_strip_all_tags(
704
-                    __(
705
-                        '%sThere are currently no registration records in the last month for this report.%s',
706
-                        'event_espresso'
707
-                    )
708
-                ),
709
-                '<h2>' . $report_title . '</h2><p>',
710
-                '</p>'
711
-            ),
712
-        ];
713
-        wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
714
-        return $report_ID;
715
-    }
640
+	/**
641
+	 * Generates Business Report showing total registrations per day.
642
+	 *
643
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
644
+	 * @return string
645
+	 * @throws EE_Error
646
+	 * @throws InvalidArgumentException
647
+	 * @throws InvalidDataTypeException
648
+	 * @throws InvalidInterfaceException
649
+	 * @throws ReflectionException
650
+	 */
651
+	private function _registrations_per_day_report($period = '-1 month')
652
+	{
653
+		$report_ID = 'reg-admin-registrations-per-day-report-dv';
654
+		$results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
655
+		$results   = (array) $results;
656
+		$regs      = [];
657
+		$subtitle  = '';
658
+		if ($results) {
659
+			$column_titles = [];
660
+			$tracker       = 0;
661
+			foreach ($results as $result) {
662
+				$report_column_values = [];
663
+				foreach ($result as $property_name => $property_value) {
664
+					$property_value         = $property_name === 'Registration_REG_date' ? $property_value
665
+						: (int) $property_value;
666
+					$report_column_values[] = $property_value;
667
+					if ($tracker === 0) {
668
+						if ($property_name === 'Registration_REG_date') {
669
+							$column_titles[] = esc_html__(
670
+								'Date (only days with registrations are shown)',
671
+								'event_espresso'
672
+							);
673
+						} else {
674
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
675
+						}
676
+					}
677
+				}
678
+				$tracker++;
679
+				$regs[] = $report_column_values;
680
+			}
681
+			// make sure the column_titles is pushed to the beginning of the array
682
+			array_unshift($regs, $column_titles);
683
+			// setup the date range.
684
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
685
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
686
+			$ending_date    = new DateTime("now", $DateTimeZone);
687
+			$subtitle       = sprintf(
688
+				wp_strip_all_tags(
689
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
690
+				),
691
+				$beginning_date->format('Y-m-d'),
692
+				$ending_date->format('Y-m-d')
693
+			);
694
+		}
695
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
696
+		$report_params = [
697
+			'title'     => $report_title,
698
+			'subtitle'  => $subtitle,
699
+			'id'        => $report_ID,
700
+			'regs'      => $regs,
701
+			'noResults' => empty($regs),
702
+			'noRegsMsg' => sprintf(
703
+				wp_strip_all_tags(
704
+					__(
705
+						'%sThere are currently no registration records in the last month for this report.%s',
706
+						'event_espresso'
707
+					)
708
+				),
709
+				'<h2>' . $report_title . '</h2><p>',
710
+				'</p>'
711
+			),
712
+		];
713
+		wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
714
+		return $report_ID;
715
+	}
716 716
 
717 717
 
718
-    /**
719
-     * Generates Business Report showing total registrations per event.
720
-     *
721
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
722
-     * @return string
723
-     * @throws EE_Error
724
-     * @throws InvalidArgumentException
725
-     * @throws InvalidDataTypeException
726
-     * @throws InvalidInterfaceException
727
-     * @throws ReflectionException
728
-     */
729
-    private function _registrations_per_event_report($period = '-1 month')
730
-    {
731
-        $report_ID = 'reg-admin-registrations-per-event-report-dv';
732
-        $results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
733
-        $results   = (array) $results;
734
-        $regs      = [];
735
-        $subtitle  = '';
736
-        if ($results) {
737
-            $column_titles = [];
738
-            $tracker       = 0;
739
-            foreach ($results as $result) {
740
-                $report_column_values = [];
741
-                foreach ($result as $property_name => $property_value) {
742
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
743
-                        $property_value,
744
-                        4,
745
-                        '...'
746
-                    ) : (int) $property_value;
747
-                    $report_column_values[] = $property_value;
748
-                    if ($tracker === 0) {
749
-                        if ($property_name === 'Registration_Event') {
750
-                            $column_titles[] = esc_html__('Event', 'event_espresso');
751
-                        } else {
752
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
753
-                        }
754
-                    }
755
-                }
756
-                $tracker++;
757
-                $regs[] = $report_column_values;
758
-            }
759
-            // make sure the column_titles is pushed to the beginning of the array
760
-            array_unshift($regs, $column_titles);
761
-            // setup the date range.
762
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
763
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
764
-            $ending_date    = new DateTime("now", $DateTimeZone);
765
-            $subtitle       = sprintf(
766
-                wp_strip_all_tags(
767
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
768
-                ),
769
-                $beginning_date->format('Y-m-d'),
770
-                $ending_date->format('Y-m-d')
771
-            );
772
-        }
773
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
774
-        $report_params = [
775
-            'title'     => $report_title,
776
-            'subtitle'  => $subtitle,
777
-            'id'        => $report_ID,
778
-            'regs'      => $regs,
779
-            'noResults' => empty($regs),
780
-            'noRegsMsg' => sprintf(
781
-                wp_strip_all_tags(
782
-                    __(
783
-                        '%sThere are currently no registration records in the last month for this report.%s',
784
-                        'event_espresso'
785
-                    )
786
-                ),
787
-                '<h2>' . $report_title . '</h2><p>',
788
-                '</p>'
789
-            ),
790
-        ];
791
-        wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
792
-        return $report_ID;
793
-    }
718
+	/**
719
+	 * Generates Business Report showing total registrations per event.
720
+	 *
721
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
722
+	 * @return string
723
+	 * @throws EE_Error
724
+	 * @throws InvalidArgumentException
725
+	 * @throws InvalidDataTypeException
726
+	 * @throws InvalidInterfaceException
727
+	 * @throws ReflectionException
728
+	 */
729
+	private function _registrations_per_event_report($period = '-1 month')
730
+	{
731
+		$report_ID = 'reg-admin-registrations-per-event-report-dv';
732
+		$results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
733
+		$results   = (array) $results;
734
+		$regs      = [];
735
+		$subtitle  = '';
736
+		if ($results) {
737
+			$column_titles = [];
738
+			$tracker       = 0;
739
+			foreach ($results as $result) {
740
+				$report_column_values = [];
741
+				foreach ($result as $property_name => $property_value) {
742
+					$property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
743
+						$property_value,
744
+						4,
745
+						'...'
746
+					) : (int) $property_value;
747
+					$report_column_values[] = $property_value;
748
+					if ($tracker === 0) {
749
+						if ($property_name === 'Registration_Event') {
750
+							$column_titles[] = esc_html__('Event', 'event_espresso');
751
+						} else {
752
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
753
+						}
754
+					}
755
+				}
756
+				$tracker++;
757
+				$regs[] = $report_column_values;
758
+			}
759
+			// make sure the column_titles is pushed to the beginning of the array
760
+			array_unshift($regs, $column_titles);
761
+			// setup the date range.
762
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
763
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
764
+			$ending_date    = new DateTime("now", $DateTimeZone);
765
+			$subtitle       = sprintf(
766
+				wp_strip_all_tags(
767
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
768
+				),
769
+				$beginning_date->format('Y-m-d'),
770
+				$ending_date->format('Y-m-d')
771
+			);
772
+		}
773
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
774
+		$report_params = [
775
+			'title'     => $report_title,
776
+			'subtitle'  => $subtitle,
777
+			'id'        => $report_ID,
778
+			'regs'      => $regs,
779
+			'noResults' => empty($regs),
780
+			'noRegsMsg' => sprintf(
781
+				wp_strip_all_tags(
782
+					__(
783
+						'%sThere are currently no registration records in the last month for this report.%s',
784
+						'event_espresso'
785
+					)
786
+				),
787
+				'<h2>' . $report_title . '</h2><p>',
788
+				'</p>'
789
+			),
790
+		];
791
+		wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
792
+		return $report_ID;
793
+	}
794 794
 
795 795
 
796
-    /**
797
-     * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
798
-     *
799
-     * @access protected
800
-     * @return void
801
-     * @throws EE_Error
802
-     * @throws InvalidArgumentException
803
-     * @throws InvalidDataTypeException
804
-     * @throws InvalidInterfaceException
805
-     * @throws EntityNotFoundException
806
-     * @throws ReflectionException
807
-     */
808
-    protected function _registration_checkin_list_table()
809
-    {
810
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
811
-        $reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null;
812
-        /** @var EE_Registration $registration */
813
-        $registration = EEM_Registration::instance()->get_one_by_ID($reg_id);
814
-        if (! $registration instanceof EE_Registration) {
815
-            throw new EE_Error(
816
-                sprintf(
817
-                    esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
818
-                    $reg_id
819
-                )
820
-            );
821
-        }
822
-        $attendee                                 = $registration->attendee();
823
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
824
-            'new_registration',
825
-            'add-registrant',
826
-            ['event_id' => $registration->event_ID()],
827
-            'add-new-h2'
828
-        );
829
-        $checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
830
-        $checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
831
-        $legend_items                             = [
832
-            'checkin'  => [
833
-                'class' => $checked_in->cssClasses(),
834
-                'desc'  => $checked_in->legendLabel(),
835
-            ],
836
-            'checkout' => [
837
-                'class' => $checked_out->cssClasses(),
838
-                'desc'  => $checked_out->legendLabel(),
839
-            ],
840
-        ];
841
-        $this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
842
-        $dtt_id                                   =
843
-            isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null;
844
-        /** @var EE_Datetime $datetime */
845
-        $datetime       = EEM_Datetime::instance()->get_one_by_ID($dtt_id);
846
-        $datetime_label = '';
847
-        if ($datetime instanceof EE_Datetime) {
848
-            $datetime_label = $datetime->get_dtt_display_name(true);
849
-            $datetime_label .= ! empty($datetime_label)
850
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
851
-                : $datetime->get_dtt_display_name();
852
-        }
853
-        $datetime_link                                    = ! empty($dtt_id) && $registration instanceof EE_Registration
854
-            ? EE_Admin_Page::add_query_args_and_nonce(
855
-                [
856
-                    'action'   => 'event_registrations',
857
-                    'event_id' => $registration->event_ID(),
858
-                    'DTT_ID'   => $dtt_id,
859
-                ],
860
-                $this->_admin_base_url
861
-            )
862
-            : '';
863
-        $datetime_link                                    = ! empty($datetime_link)
864
-            ? '<a href="' . $datetime_link . '">'
865
-              . '<span id="checkin-dtt">'
866
-              . $datetime_label
867
-              . '</span></a>'
868
-            : $datetime_label;
869
-        $attendee_name                                    = $attendee instanceof EE_Attendee
870
-            ? $attendee->full_name()
871
-            : '';
872
-        $attendee_link                                    = $attendee instanceof EE_Attendee
873
-            ? $attendee->get_admin_details_link()
874
-            : '';
875
-        $attendee_link                                    = ! empty($attendee_link)
876
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
877
-              . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
878
-              . '<span id="checkin-attendee-name">'
879
-              . $attendee_name
880
-              . '</span></a>'
881
-            : '';
882
-        $event_link                                       = $registration->event() instanceof EE_Event
883
-            ? $registration->event()->get_admin_details_link()
884
-            : '';
885
-        $event_link                                       = ! empty($event_link)
886
-            ? '<a href="' . $event_link . '"'
887
-              . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
888
-              . '<span id="checkin-event-name">'
889
-              . $registration->event_name()
890
-              . '</span>'
891
-              . '</a>'
892
-            : '';
893
-        $this->_template_args['before_list_table']        = ! empty($reg_id) && ! empty($dtt_id)
894
-            ? '<h2>' . sprintf(
895
-                esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
896
-                $attendee_link,
897
-                $datetime_link,
898
-                $event_link
899
-            ) . '</h2>'
900
-            : '';
901
-        $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id)
902
-            ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : '';
903
-        $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id)
904
-            ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : '';
905
-        $this->display_admin_list_table_page_with_no_sidebar();
906
-    }
796
+	/**
797
+	 * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
798
+	 *
799
+	 * @access protected
800
+	 * @return void
801
+	 * @throws EE_Error
802
+	 * @throws InvalidArgumentException
803
+	 * @throws InvalidDataTypeException
804
+	 * @throws InvalidInterfaceException
805
+	 * @throws EntityNotFoundException
806
+	 * @throws ReflectionException
807
+	 */
808
+	protected function _registration_checkin_list_table()
809
+	{
810
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
811
+		$reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null;
812
+		/** @var EE_Registration $registration */
813
+		$registration = EEM_Registration::instance()->get_one_by_ID($reg_id);
814
+		if (! $registration instanceof EE_Registration) {
815
+			throw new EE_Error(
816
+				sprintf(
817
+					esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
818
+					$reg_id
819
+				)
820
+			);
821
+		}
822
+		$attendee                                 = $registration->attendee();
823
+		$this->_admin_page_title                  .= $this->get_action_link_or_button(
824
+			'new_registration',
825
+			'add-registrant',
826
+			['event_id' => $registration->event_ID()],
827
+			'add-new-h2'
828
+		);
829
+		$checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
830
+		$checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
831
+		$legend_items                             = [
832
+			'checkin'  => [
833
+				'class' => $checked_in->cssClasses(),
834
+				'desc'  => $checked_in->legendLabel(),
835
+			],
836
+			'checkout' => [
837
+				'class' => $checked_out->cssClasses(),
838
+				'desc'  => $checked_out->legendLabel(),
839
+			],
840
+		];
841
+		$this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
842
+		$dtt_id                                   =
843
+			isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null;
844
+		/** @var EE_Datetime $datetime */
845
+		$datetime       = EEM_Datetime::instance()->get_one_by_ID($dtt_id);
846
+		$datetime_label = '';
847
+		if ($datetime instanceof EE_Datetime) {
848
+			$datetime_label = $datetime->get_dtt_display_name(true);
849
+			$datetime_label .= ! empty($datetime_label)
850
+				? ' (' . $datetime->get_dtt_display_name() . ')'
851
+				: $datetime->get_dtt_display_name();
852
+		}
853
+		$datetime_link                                    = ! empty($dtt_id) && $registration instanceof EE_Registration
854
+			? EE_Admin_Page::add_query_args_and_nonce(
855
+				[
856
+					'action'   => 'event_registrations',
857
+					'event_id' => $registration->event_ID(),
858
+					'DTT_ID'   => $dtt_id,
859
+				],
860
+				$this->_admin_base_url
861
+			)
862
+			: '';
863
+		$datetime_link                                    = ! empty($datetime_link)
864
+			? '<a href="' . $datetime_link . '">'
865
+			  . '<span id="checkin-dtt">'
866
+			  . $datetime_label
867
+			  . '</span></a>'
868
+			: $datetime_label;
869
+		$attendee_name                                    = $attendee instanceof EE_Attendee
870
+			? $attendee->full_name()
871
+			: '';
872
+		$attendee_link                                    = $attendee instanceof EE_Attendee
873
+			? $attendee->get_admin_details_link()
874
+			: '';
875
+		$attendee_link                                    = ! empty($attendee_link)
876
+			? '<a href="' . $attendee->get_admin_details_link() . '"'
877
+			  . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
878
+			  . '<span id="checkin-attendee-name">'
879
+			  . $attendee_name
880
+			  . '</span></a>'
881
+			: '';
882
+		$event_link                                       = $registration->event() instanceof EE_Event
883
+			? $registration->event()->get_admin_details_link()
884
+			: '';
885
+		$event_link                                       = ! empty($event_link)
886
+			? '<a href="' . $event_link . '"'
887
+			  . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
888
+			  . '<span id="checkin-event-name">'
889
+			  . $registration->event_name()
890
+			  . '</span>'
891
+			  . '</a>'
892
+			: '';
893
+		$this->_template_args['before_list_table']        = ! empty($reg_id) && ! empty($dtt_id)
894
+			? '<h2>' . sprintf(
895
+				esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
896
+				$attendee_link,
897
+				$datetime_link,
898
+				$event_link
899
+			) . '</h2>'
900
+			: '';
901
+		$this->_template_args['list_table_hidden_fields'] = ! empty($reg_id)
902
+			? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : '';
903
+		$this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id)
904
+			? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : '';
905
+		$this->display_admin_list_table_page_with_no_sidebar();
906
+	}
907 907
 
908 908
 
909
-    /**
910
-     * toggle the Check-in status for the given registration (coming from ajax)
911
-     *
912
-     * @return void (JSON)
913
-     * @throws EE_Error
914
-     * @throws InvalidArgumentException
915
-     * @throws InvalidDataTypeException
916
-     * @throws InvalidInterfaceException
917
-     * @throws ReflectionException
918
-     */
919
-    public function toggle_checkin_status()
920
-    {
921
-        // first make sure we have the necessary data
922
-        if (! isset($this->_req_data['_regid'])) {
923
-            EE_Error::add_error(
924
-                esc_html__(
925
-                    'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
926
-                    'event_espresso'
927
-                ),
928
-                __FILE__,
929
-                __FUNCTION__,
930
-                __LINE__
931
-            );
932
-            $this->_template_args['success'] = false;
933
-            $this->_template_args['error']   = true;
934
-            $this->_return_json();
935
-        };
936
-        // do a nonce check cause we're not coming in from an normal route here.
937
-        $nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
938
-            : '';
939
-        $nonce_ref = 'checkin_nonce';
940
-        $this->_verify_nonce($nonce, $nonce_ref);
941
-        // beautiful! Made it this far so let's get the status.
942
-        $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
943
-        // setup new class to return via ajax
944
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
945
-        $this->_template_args['success']            = true;
946
-        $this->_return_json();
947
-    }
909
+	/**
910
+	 * toggle the Check-in status for the given registration (coming from ajax)
911
+	 *
912
+	 * @return void (JSON)
913
+	 * @throws EE_Error
914
+	 * @throws InvalidArgumentException
915
+	 * @throws InvalidDataTypeException
916
+	 * @throws InvalidInterfaceException
917
+	 * @throws ReflectionException
918
+	 */
919
+	public function toggle_checkin_status()
920
+	{
921
+		// first make sure we have the necessary data
922
+		if (! isset($this->_req_data['_regid'])) {
923
+			EE_Error::add_error(
924
+				esc_html__(
925
+					'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
926
+					'event_espresso'
927
+				),
928
+				__FILE__,
929
+				__FUNCTION__,
930
+				__LINE__
931
+			);
932
+			$this->_template_args['success'] = false;
933
+			$this->_template_args['error']   = true;
934
+			$this->_return_json();
935
+		};
936
+		// do a nonce check cause we're not coming in from an normal route here.
937
+		$nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
938
+			: '';
939
+		$nonce_ref = 'checkin_nonce';
940
+		$this->_verify_nonce($nonce, $nonce_ref);
941
+		// beautiful! Made it this far so let's get the status.
942
+		$new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
943
+		// setup new class to return via ajax
944
+		$this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
945
+		$this->_template_args['success']            = true;
946
+		$this->_return_json();
947
+	}
948 948
 
949 949
 
950
-    /**
951
-     * handles toggling the checkin status for the registration,
952
-     *
953
-     * @access protected
954
-     * @return int|void
955
-     * @throws EE_Error
956
-     * @throws InvalidArgumentException
957
-     * @throws InvalidDataTypeException
958
-     * @throws InvalidInterfaceException
959
-     * @throws ReflectionException
960
-     */
961
-    protected function _toggle_checkin_status()
962
-    {
963
-        // first let's get the query args out of the way for the redirect
964
-        $query_args = [
965
-            'action'   => 'event_registrations',
966
-            'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null,
967
-            'DTT_ID'   => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null,
968
-        ];
969
-        $new_status = false;
970
-        // bulk action check in toggle
971
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
972
-            // cycle thru checkboxes
973
-            $checkboxes = $this->_req_data['checkbox'];
974
-            foreach (array_keys($checkboxes) as $REG_ID) {
975
-                $DTT_ID     = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null;
976
-                $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
977
-            }
978
-        } elseif (isset($this->_req_data['_regid'])) {
979
-            // coming from ajax request
980
-            $DTT_ID               = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null;
981
-            $query_args['DTT_ID'] = $DTT_ID;
982
-            $new_status           = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID);
983
-        } else {
984
-            EE_Error::add_error(
985
-                esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
986
-                __FILE__,
987
-                __FUNCTION__,
988
-                __LINE__
989
-            );
990
-        }
991
-        if (defined('DOING_AJAX')) {
992
-            return $new_status;
993
-        }
994
-        $this->_redirect_after_action(false, '', '', $query_args, true);
995
-    }
950
+	/**
951
+	 * handles toggling the checkin status for the registration,
952
+	 *
953
+	 * @access protected
954
+	 * @return int|void
955
+	 * @throws EE_Error
956
+	 * @throws InvalidArgumentException
957
+	 * @throws InvalidDataTypeException
958
+	 * @throws InvalidInterfaceException
959
+	 * @throws ReflectionException
960
+	 */
961
+	protected function _toggle_checkin_status()
962
+	{
963
+		// first let's get the query args out of the way for the redirect
964
+		$query_args = [
965
+			'action'   => 'event_registrations',
966
+			'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null,
967
+			'DTT_ID'   => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null,
968
+		];
969
+		$new_status = false;
970
+		// bulk action check in toggle
971
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
972
+			// cycle thru checkboxes
973
+			$checkboxes = $this->_req_data['checkbox'];
974
+			foreach (array_keys($checkboxes) as $REG_ID) {
975
+				$DTT_ID     = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null;
976
+				$new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
977
+			}
978
+		} elseif (isset($this->_req_data['_regid'])) {
979
+			// coming from ajax request
980
+			$DTT_ID               = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null;
981
+			$query_args['DTT_ID'] = $DTT_ID;
982
+			$new_status           = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID);
983
+		} else {
984
+			EE_Error::add_error(
985
+				esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
986
+				__FILE__,
987
+				__FUNCTION__,
988
+				__LINE__
989
+			);
990
+		}
991
+		if (defined('DOING_AJAX')) {
992
+			return $new_status;
993
+		}
994
+		$this->_redirect_after_action(false, '', '', $query_args, true);
995
+	}
996 996
 
997 997
 
998
-    /**
999
-     * This is toggles a single Check-in for the given registration and datetime.
1000
-     *
1001
-     * @param int $REG_ID The registration we're toggling
1002
-     * @param int $DTT_ID The datetime we're toggling
1003
-     * @return int The new status toggled to.
1004
-     * @throws EE_Error
1005
-     * @throws InvalidArgumentException
1006
-     * @throws InvalidDataTypeException
1007
-     * @throws InvalidInterfaceException
1008
-     * @throws ReflectionException
1009
-     */
1010
-    private function _toggle_checkin($REG_ID, $DTT_ID)
1011
-    {
1012
-        /** @var EE_Registration $REG */
1013
-        $REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1014
-        $new_status = $REG->toggle_checkin_status($DTT_ID);
1015
-        if ($new_status !== false) {
1016
-            EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1017
-        } else {
1018
-            EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1019
-            $new_status = false;
1020
-        }
1021
-        return $new_status;
1022
-    }
998
+	/**
999
+	 * This is toggles a single Check-in for the given registration and datetime.
1000
+	 *
1001
+	 * @param int $REG_ID The registration we're toggling
1002
+	 * @param int $DTT_ID The datetime we're toggling
1003
+	 * @return int The new status toggled to.
1004
+	 * @throws EE_Error
1005
+	 * @throws InvalidArgumentException
1006
+	 * @throws InvalidDataTypeException
1007
+	 * @throws InvalidInterfaceException
1008
+	 * @throws ReflectionException
1009
+	 */
1010
+	private function _toggle_checkin($REG_ID, $DTT_ID)
1011
+	{
1012
+		/** @var EE_Registration $REG */
1013
+		$REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1014
+		$new_status = $REG->toggle_checkin_status($DTT_ID);
1015
+		if ($new_status !== false) {
1016
+			EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1017
+		} else {
1018
+			EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1019
+			$new_status = false;
1020
+		}
1021
+		return $new_status;
1022
+	}
1023 1023
 
1024 1024
 
1025
-    /**
1026
-     * Takes care of deleting multiple EE_Checkin table rows
1027
-     *
1028
-     * @access protected
1029
-     * @return void
1030
-     * @throws EE_Error
1031
-     * @throws InvalidArgumentException
1032
-     * @throws InvalidDataTypeException
1033
-     * @throws InvalidInterfaceException
1034
-     * @throws ReflectionException
1035
-     */
1036
-    protected function _delete_checkin_rows()
1037
-    {
1038
-        $query_args = [
1039
-            'action'  => 'registration_checkins',
1040
-            'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1041
-            '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1042
-        ];
1043
-        $errors     = 0;
1044
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1045
-            $checkboxes = $this->_req_data['checkbox'];
1046
-            foreach (array_keys($checkboxes) as $CHK_ID) {
1047
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1048
-                    $errors++;
1049
-                }
1050
-            }
1051
-        } else {
1052
-            EE_Error::add_error(
1053
-                esc_html__(
1054
-                    'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1055
-                    'event_espresso'
1056
-                ),
1057
-                __FILE__,
1058
-                __FUNCTION__,
1059
-                __LINE__
1060
-            );
1061
-            $this->_redirect_after_action(false, '', '', $query_args, true);
1062
-        }
1063
-        if ($errors > 0) {
1064
-            EE_Error::add_error(
1065
-                sprintf(
1066
-                    esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1067
-                    $errors
1068
-                ),
1069
-                __FILE__,
1070
-                __FUNCTION__,
1071
-                __LINE__
1072
-            );
1073
-        } else {
1074
-            EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1075
-        }
1076
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1077
-    }
1025
+	/**
1026
+	 * Takes care of deleting multiple EE_Checkin table rows
1027
+	 *
1028
+	 * @access protected
1029
+	 * @return void
1030
+	 * @throws EE_Error
1031
+	 * @throws InvalidArgumentException
1032
+	 * @throws InvalidDataTypeException
1033
+	 * @throws InvalidInterfaceException
1034
+	 * @throws ReflectionException
1035
+	 */
1036
+	protected function _delete_checkin_rows()
1037
+	{
1038
+		$query_args = [
1039
+			'action'  => 'registration_checkins',
1040
+			'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1041
+			'_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1042
+		];
1043
+		$errors     = 0;
1044
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1045
+			$checkboxes = $this->_req_data['checkbox'];
1046
+			foreach (array_keys($checkboxes) as $CHK_ID) {
1047
+				if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1048
+					$errors++;
1049
+				}
1050
+			}
1051
+		} else {
1052
+			EE_Error::add_error(
1053
+				esc_html__(
1054
+					'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1055
+					'event_espresso'
1056
+				),
1057
+				__FILE__,
1058
+				__FUNCTION__,
1059
+				__LINE__
1060
+			);
1061
+			$this->_redirect_after_action(false, '', '', $query_args, true);
1062
+		}
1063
+		if ($errors > 0) {
1064
+			EE_Error::add_error(
1065
+				sprintf(
1066
+					esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1067
+					$errors
1068
+				),
1069
+				__FILE__,
1070
+				__FUNCTION__,
1071
+				__LINE__
1072
+			);
1073
+		} else {
1074
+			EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1075
+		}
1076
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1077
+	}
1078 1078
 
1079 1079
 
1080
-    /**
1081
-     * Deletes a single EE_Checkin row
1082
-     *
1083
-     * @return void
1084
-     * @throws EE_Error
1085
-     * @throws InvalidArgumentException
1086
-     * @throws InvalidDataTypeException
1087
-     * @throws InvalidInterfaceException
1088
-     * @throws ReflectionException
1089
-     */
1090
-    protected function _delete_checkin_row()
1091
-    {
1092
-        $query_args = [
1093
-            'action'  => 'registration_checkins',
1094
-            'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1095
-            '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1096
-        ];
1097
-        if (! empty($this->_req_data['CHK_ID'])) {
1098
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1099
-                EE_Error::add_error(
1100
-                    esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1101
-                    __FILE__,
1102
-                    __FUNCTION__,
1103
-                    __LINE__
1104
-                );
1105
-            } else {
1106
-                EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1107
-            }
1108
-        } else {
1109
-            EE_Error::add_error(
1110
-                esc_html__(
1111
-                    'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1112
-                    'event_espresso'
1113
-                ),
1114
-                __FILE__,
1115
-                __FUNCTION__,
1116
-                __LINE__
1117
-            );
1118
-        }
1119
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1120
-    }
1080
+	/**
1081
+	 * Deletes a single EE_Checkin row
1082
+	 *
1083
+	 * @return void
1084
+	 * @throws EE_Error
1085
+	 * @throws InvalidArgumentException
1086
+	 * @throws InvalidDataTypeException
1087
+	 * @throws InvalidInterfaceException
1088
+	 * @throws ReflectionException
1089
+	 */
1090
+	protected function _delete_checkin_row()
1091
+	{
1092
+		$query_args = [
1093
+			'action'  => 'registration_checkins',
1094
+			'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1095
+			'_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1096
+		];
1097
+		if (! empty($this->_req_data['CHK_ID'])) {
1098
+			if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1099
+				EE_Error::add_error(
1100
+					esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1101
+					__FILE__,
1102
+					__FUNCTION__,
1103
+					__LINE__
1104
+				);
1105
+			} else {
1106
+				EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1107
+			}
1108
+		} else {
1109
+			EE_Error::add_error(
1110
+				esc_html__(
1111
+					'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1112
+					'event_espresso'
1113
+				),
1114
+				__FILE__,
1115
+				__FUNCTION__,
1116
+				__LINE__
1117
+			);
1118
+		}
1119
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1120
+	}
1121 1121
 
1122 1122
 
1123
-    /**
1124
-     *        generates HTML for the Event Registrations List Table
1125
-     *
1126
-     * @access protected
1127
-     * @return void
1128
-     * @throws EE_Error
1129
-     * @throws InvalidArgumentException
1130
-     * @throws InvalidDataTypeException
1131
-     * @throws InvalidInterfaceException
1132
-     * @throws ReflectionException
1133
-     */
1134
-    protected function _event_registrations_list_table()
1135
-    {
1136
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1137
-        $this->_admin_page_title                  .= isset($this->_req_data['event_id'])
1138
-            ? $this->get_action_link_or_button(
1139
-                'new_registration',
1140
-                'add-registrant',
1141
-                ['event_id' => $this->_req_data['event_id']],
1142
-                'add-new-h2',
1143
-                '',
1144
-                false
1145
-            )
1146
-            : '';
1147
-        $checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1148
-        $checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1149
-        $checked_never                            = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1150
-        $checkin_invalid                          = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1151
-        $legend_items                             = [
1152
-            'star-icon'        => [
1153
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1154
-                'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1155
-            ],
1156
-            'checkin'          => [
1157
-                'class' => $checked_in->cssClasses(),
1158
-                'desc'  => $checked_in->legendLabel(),
1159
-            ],
1160
-            'checkout'         => [
1161
-                'class' => $checked_out->cssClasses(),
1162
-                'desc'  => $checked_out->legendLabel(),
1163
-            ],
1164
-            'nocheckinrecord'  => [
1165
-                'class' => $checked_never->cssClasses(),
1166
-                'desc'  => $checked_never->legendLabel(),
1167
-            ],
1168
-            'canNotCheckin'    => [
1169
-                'class' => $checkin_invalid->cssClasses(),
1170
-                'desc'  => $checkin_invalid->legendLabel(),
1171
-            ],
1172
-            'approved_status'  => [
1173
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1174
-                'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1175
-            ],
1176
-            'cancelled_status' => [
1177
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1178
-                'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1179
-            ],
1180
-            'declined_status'  => [
1181
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1182
-                'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1183
-            ],
1184
-            'not_approved'     => [
1185
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1186
-                'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1187
-            ],
1188
-            'pending_status'   => [
1189
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1190
-                'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1191
-            ],
1192
-            'wait_list'        => [
1193
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1194
-                'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1195
-            ],
1196
-        ];
1197
-        $this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
1198
-        $event_id                                 =
1199
-            isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : 0;
1200
-        /** @var EE_Event $event */
1201
-        $event                                     = EEM_Event::instance()->get_one_by_ID($event_id);
1202
-        $this->_template_args['before_list_table'] = $event instanceof EE_Event
1203
-            ? '<h2>
1123
+	/**
1124
+	 *        generates HTML for the Event Registrations List Table
1125
+	 *
1126
+	 * @access protected
1127
+	 * @return void
1128
+	 * @throws EE_Error
1129
+	 * @throws InvalidArgumentException
1130
+	 * @throws InvalidDataTypeException
1131
+	 * @throws InvalidInterfaceException
1132
+	 * @throws ReflectionException
1133
+	 */
1134
+	protected function _event_registrations_list_table()
1135
+	{
1136
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1137
+		$this->_admin_page_title                  .= isset($this->_req_data['event_id'])
1138
+			? $this->get_action_link_or_button(
1139
+				'new_registration',
1140
+				'add-registrant',
1141
+				['event_id' => $this->_req_data['event_id']],
1142
+				'add-new-h2',
1143
+				'',
1144
+				false
1145
+			)
1146
+			: '';
1147
+		$checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1148
+		$checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1149
+		$checked_never                            = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1150
+		$checkin_invalid                          = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1151
+		$legend_items                             = [
1152
+			'star-icon'        => [
1153
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1154
+				'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1155
+			],
1156
+			'checkin'          => [
1157
+				'class' => $checked_in->cssClasses(),
1158
+				'desc'  => $checked_in->legendLabel(),
1159
+			],
1160
+			'checkout'         => [
1161
+				'class' => $checked_out->cssClasses(),
1162
+				'desc'  => $checked_out->legendLabel(),
1163
+			],
1164
+			'nocheckinrecord'  => [
1165
+				'class' => $checked_never->cssClasses(),
1166
+				'desc'  => $checked_never->legendLabel(),
1167
+			],
1168
+			'canNotCheckin'    => [
1169
+				'class' => $checkin_invalid->cssClasses(),
1170
+				'desc'  => $checkin_invalid->legendLabel(),
1171
+			],
1172
+			'approved_status'  => [
1173
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1174
+				'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1175
+			],
1176
+			'cancelled_status' => [
1177
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1178
+				'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1179
+			],
1180
+			'declined_status'  => [
1181
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1182
+				'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1183
+			],
1184
+			'not_approved'     => [
1185
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1186
+				'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1187
+			],
1188
+			'pending_status'   => [
1189
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1190
+				'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1191
+			],
1192
+			'wait_list'        => [
1193
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1194
+				'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1195
+			],
1196
+		];
1197
+		$this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
1198
+		$event_id                                 =
1199
+			isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : 0;
1200
+		/** @var EE_Event $event */
1201
+		$event                                     = EEM_Event::instance()->get_one_by_ID($event_id);
1202
+		$this->_template_args['before_list_table'] = $event instanceof EE_Event
1203
+			? '<h2>
1204 1204
                 ' . sprintf(
1205
-                esc_html__('Viewing Registrations for Event: %s', 'event_espresso'),
1206
-                "<span class='ee-event-name'>{$event->name()}</span>"
1207
-            )
1208
-            : '';
1209
-        // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on
1210
-        // the event.
1211
-        $DTT_ID   = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0;
1212
-        $datetime = null;
1213
-        if ($event instanceof EE_Event) {
1214
-            $datetimes_on_event = $event->datetimes();
1215
-            if (count($datetimes_on_event) === 1) {
1216
-                $datetime = reset($datetimes_on_event);
1217
-            }
1218
-        }
1219
-        $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1220
-        if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') {
1221
-            $active_status                             = $datetime->get_active_status();
1222
-            $datetime_status                           =
1223
-                '<span class="ee-status ee-status-bg--' . esc_attr($active_status) . ' event-active-status-' .
1224
-                esc_attr($active_status) . '">'
1225
-                . EEH_Template::pretty_status($active_status, false, 'sentence')
1226
-                . '</span>';
1227
-            $this->_template_args['before_list_table'] .= '<span class="ee-event-datetime-name">';
1228
-            $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar-alt"></span>';
1229
-            $this->_template_args['before_list_table'] .= $datetime->name();
1230
-            $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )';
1231
-            $this->_template_args['before_list_table'] .= $datetime_status;
1232
-            $this->_template_args['before_list_table'] .= '</span>';
1233
-        }
1234
-        $this->_template_args['before_list_table'] .= '</h2>';
1235
-        // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status
1236
-        // column represents
1237
-        if (! $datetime instanceof EE_Datetime) {
1238
-            $this->_template_args['before_list_table'] .= '
1205
+				esc_html__('Viewing Registrations for Event: %s', 'event_espresso'),
1206
+				"<span class='ee-event-name'>{$event->name()}</span>"
1207
+			)
1208
+			: '';
1209
+		// need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on
1210
+		// the event.
1211
+		$DTT_ID   = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0;
1212
+		$datetime = null;
1213
+		if ($event instanceof EE_Event) {
1214
+			$datetimes_on_event = $event->datetimes();
1215
+			if (count($datetimes_on_event) === 1) {
1216
+				$datetime = reset($datetimes_on_event);
1217
+			}
1218
+		}
1219
+		$datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1220
+		if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') {
1221
+			$active_status                             = $datetime->get_active_status();
1222
+			$datetime_status                           =
1223
+				'<span class="ee-status ee-status-bg--' . esc_attr($active_status) . ' event-active-status-' .
1224
+				esc_attr($active_status) . '">'
1225
+				. EEH_Template::pretty_status($active_status, false, 'sentence')
1226
+				. '</span>';
1227
+			$this->_template_args['before_list_table'] .= '<span class="ee-event-datetime-name">';
1228
+			$this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar-alt"></span>';
1229
+			$this->_template_args['before_list_table'] .= $datetime->name();
1230
+			$this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )';
1231
+			$this->_template_args['before_list_table'] .= $datetime_status;
1232
+			$this->_template_args['before_list_table'] .= '</span>';
1233
+		}
1234
+		$this->_template_args['before_list_table'] .= '</h2>';
1235
+		// if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status
1236
+		// column represents
1237
+		if (! $datetime instanceof EE_Datetime) {
1238
+			$this->_template_args['before_list_table'] .= '
1239 1239
                 <div class="description ee-status-outline ee-status-bg--info" style="white-space: normal;">
1240 1240
                     <h2 style="margin: 1rem; padding: 0;">' . esc_html__(
1241
-                        'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1242
-                        'event_espresso'
1243
-                    ) . '</h2>
1241
+						'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1242
+						'event_espresso'
1243
+					) . '</h2>
1244 1244
                 </div>';
1245
-        }
1246
-        $this->display_admin_list_table_page_with_no_sidebar();
1247
-    }
1245
+		}
1246
+		$this->display_admin_list_table_page_with_no_sidebar();
1247
+	}
1248 1248
 
1249 1249
 
1250
-    /**
1251
-     * Download the registrations check-in report (same as the normal registration report, but with different where
1252
-     * conditions)
1253
-     *
1254
-     * @return void ends the request by a redirect or download
1255
-     */
1256
-    public function _registrations_checkin_report()
1257
-    {
1258
-        $this->_registrations_report_base('_get_checkin_query_params_from_request');
1259
-    }
1250
+	/**
1251
+	 * Download the registrations check-in report (same as the normal registration report, but with different where
1252
+	 * conditions)
1253
+	 *
1254
+	 * @return void ends the request by a redirect or download
1255
+	 */
1256
+	public function _registrations_checkin_report()
1257
+	{
1258
+		$this->_registrations_report_base('_get_checkin_query_params_from_request');
1259
+	}
1260 1260
 
1261 1261
 
1262
-    /**
1263
-     * Gets the query params from the request, plus adds a where condition for the registration status,
1264
-     * because on the checkin page we only ever want to see approved and pending-approval registrations
1265
-     *
1266
-     * @param array $request
1267
-     * @param int   $per_page
1268
-     * @param bool  $count
1269
-     * @return array
1270
-     * @throws EE_Error
1271
-     */
1272
-    protected function _get_checkin_query_params_from_request(
1273
-        $request,
1274
-        $per_page = 10,
1275
-        $count = false
1276
-    ) {
1277
-        $query_params = $this->_get_registration_query_parameters($request, $per_page, $count);
1278
-        // unlike the regular registrations list table,
1279
-        $status_ids_array          = apply_filters(
1280
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1281
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1282
-        );
1283
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1284
-        return $query_params;
1285
-    }
1262
+	/**
1263
+	 * Gets the query params from the request, plus adds a where condition for the registration status,
1264
+	 * because on the checkin page we only ever want to see approved and pending-approval registrations
1265
+	 *
1266
+	 * @param array $request
1267
+	 * @param int   $per_page
1268
+	 * @param bool  $count
1269
+	 * @return array
1270
+	 * @throws EE_Error
1271
+	 */
1272
+	protected function _get_checkin_query_params_from_request(
1273
+		$request,
1274
+		$per_page = 10,
1275
+		$count = false
1276
+	) {
1277
+		$query_params = $this->_get_registration_query_parameters($request, $per_page, $count);
1278
+		// unlike the regular registrations list table,
1279
+		$status_ids_array          = apply_filters(
1280
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1281
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1282
+		);
1283
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1284
+		return $query_params;
1285
+	}
1286 1286
 
1287 1287
 
1288
-    /**
1289
-     * Gets registrations for an event
1290
-     *
1291
-     * @param int    $per_page
1292
-     * @param bool   $count whether to return count or data.
1293
-     * @param bool   $trash
1294
-     * @param string $orderby
1295
-     * @return EE_Registration[]|int
1296
-     * @throws EE_Error
1297
-     * @throws InvalidArgumentException
1298
-     * @throws InvalidDataTypeException
1299
-     * @throws InvalidInterfaceException
1300
-     * @throws ReflectionException
1301
-     */
1302
-    public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname')
1303
-    {
1304
-        // set some defaults, these will get overridden if included in the actual request parameters
1305
-        $defaults = [
1306
-            'orderby' => $orderby,
1307
-            'order'   => 'ASC',
1308
-        ];
1309
-        if ($trash) {
1310
-            $defaults['status'] = 'trash';
1311
-        }
1312
-        $query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1288
+	/**
1289
+	 * Gets registrations for an event
1290
+	 *
1291
+	 * @param int    $per_page
1292
+	 * @param bool   $count whether to return count or data.
1293
+	 * @param bool   $trash
1294
+	 * @param string $orderby
1295
+	 * @return EE_Registration[]|int
1296
+	 * @throws EE_Error
1297
+	 * @throws InvalidArgumentException
1298
+	 * @throws InvalidDataTypeException
1299
+	 * @throws InvalidInterfaceException
1300
+	 * @throws ReflectionException
1301
+	 */
1302
+	public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname')
1303
+	{
1304
+		// set some defaults, these will get overridden if included in the actual request parameters
1305
+		$defaults = [
1306
+			'orderby' => $orderby,
1307
+			'order'   => 'ASC',
1308
+		];
1309
+		if ($trash) {
1310
+			$defaults['status'] = 'trash';
1311
+		}
1312
+		$query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1313 1313
 
1314
-        /**
1315
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1316
-         *
1317
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1318
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1319
-         *                             or if you have the development copy of EE you can view this at the path:
1320
-         *                             /docs/G--Model-System/model-query-params.md
1321
-         */
1322
-        $query_params['group_by'] = '';
1314
+		/**
1315
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1316
+		 *
1317
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1318
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1319
+		 *                             or if you have the development copy of EE you can view this at the path:
1320
+		 *                             /docs/G--Model-System/model-query-params.md
1321
+		 */
1322
+		$query_params['group_by'] = '';
1323 1323
 
1324
-        return $count
1325
-            ? EEM_Registration::instance()->count($query_params)
1326
-            /** @type EE_Registration[] */
1327
-            : EEM_Registration::instance()->get_all($query_params);
1328
-    }
1324
+		return $count
1325
+			? EEM_Registration::instance()->count($query_params)
1326
+			/** @type EE_Registration[] */
1327
+			: EEM_Registration::instance()->get_all($query_params);
1328
+	}
1329 1329
 }
Please login to merge, or discard this patch.
Spacing   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -35,10 +35,10 @@  discard block
 block discarded – undo
35 35
     public function __construct($routing = true)
36 36
     {
37 37
         parent::__construct($routing);
38
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
39
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
40
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
41
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
38
+        if ( ! defined('REG_CAF_TEMPLATE_PATH')) {
39
+            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/');
40
+            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/');
41
+            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/');
42 42
         }
43 43
     }
44 44
 
@@ -47,12 +47,12 @@  discard block
 block discarded – undo
47 47
     {
48 48
         parent::_set_page_config();
49 49
 
50
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
50
+        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND.'registrations';
51 51
         $reg_id                                           =
52 52
             ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
53 53
                 ? $this->_req_data['_REG_ID']
54 54
                 : 0;
55
-        $new_page_routes                                  = [
55
+        $new_page_routes = [
56 56
             'reports'                      => [
57 57
                 'func'       => '_registration_reports',
58 58
                 'capability' => 'ee_read_registrations',
@@ -186,14 +186,14 @@  discard block
 block discarded – undo
186 186
         if (EEH_MSG_Template::is_mt_active('newsletter')) {
187 187
             wp_enqueue_style(
188 188
                 'ee_message_shortcodes',
189
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
189
+                EE_MSG_ASSETS_URL.'ee_message_shortcodes.css',
190 190
                 [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
191 191
                 EVENT_ESPRESSO_VERSION
192 192
             );
193 193
             // enqueue newsletter js
194 194
             wp_enqueue_script(
195 195
                 'ee-newsletter-trigger',
196
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
196
+                REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js',
197 197
                 ['ee-dialog'],
198 198
                 EVENT_ESPRESSO_VERSION,
199 199
                 true
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
     {
216 216
         wp_register_script(
217 217
             'ee-reg-reports-js',
218
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
218
+            REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js',
219 219
             ['google-charts'],
220 220
             EVENT_ESPRESSO_VERSION,
221 221
             true
@@ -302,7 +302,7 @@  discard block
 block discarded – undo
302 302
         $nonce_ref = 'get_newsletter_form_content_nonce';
303 303
         $this->_verify_nonce($nonce, $nonce_ref);
304 304
         // let's get the mtp for the incoming MTP_ ID
305
-        if (! isset($this->_req_data['GRP_ID'])) {
305
+        if ( ! isset($this->_req_data['GRP_ID'])) {
306 306
             EE_Error::add_error(
307 307
                 esc_html__(
308 308
                     'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
             $this->_return_json();
318 318
         }
319 319
         $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
320
-        if (! $MTPG instanceof EE_Message_Template_Group) {
320
+        if ( ! $MTPG instanceof EE_Message_Template_Group) {
321 321
             EE_Error::add_error(
322 322
                 sprintf(
323 323
                     esc_html__(
@@ -342,12 +342,12 @@  discard block
 block discarded – undo
342 342
             $field = $MTP->get('MTP_template_field');
343 343
             if ($field === 'content') {
344 344
                 $content = $MTP->get('MTP_content');
345
-                if (! empty($content['newsletter_content'])) {
345
+                if ( ! empty($content['newsletter_content'])) {
346 346
                     $template_fields['newsletter_content'] = $content['newsletter_content'];
347 347
                 }
348 348
                 continue;
349 349
             }
350
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
350
+            $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content');
351 351
         }
352 352
         $this->_template_args['success'] = true;
353 353
         $this->_template_args['error']   = false;
@@ -448,15 +448,15 @@  discard block
 block discarded – undo
448 448
                 $field_id               = "batch-message-$field_id";
449 449
                 $available_shortcodes[] = '
450 450
                 <span class="js-shortcode-selection"
451
-                      data-value="' . $shortcode . '"
452
-                      data-linked-input-id="' . $field_id . '"
453
-                >' . $shortcode . '</span>';
451
+                      data-value="' . $shortcode.'"
452
+                      data-linked-input-id="' . $field_id.'"
453
+                >' . $shortcode.'</span>';
454 454
             }
455
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
455
+            $codes[$field] = '<ul><li>'.implode('</li><li>', $available_shortcodes).'</li></ul>';
456 456
         }
457 457
 
458 458
         EEH_Template::display_template(
459
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
459
+            REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php',
460 460
             [
461 461
                 'form_action'       => admin_url('admin.php?page=espresso_registrations'),
462 462
                 'form_route'        => 'newsletter_selected_send',
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
      */
627 627
     protected function _registration_reports()
628 628
     {
629
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
629
+        $template_path                              = EE_ADMIN_TEMPLATE.'admin_reports.template.php';
630 630
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
631 631
             $template_path,
632 632
             $this->_reports_template_data,
@@ -682,7 +682,7 @@  discard block
 block discarded – undo
682 682
             array_unshift($regs, $column_titles);
683 683
             // setup the date range.
684 684
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
685
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
685
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
686 686
             $ending_date    = new DateTime("now", $DateTimeZone);
687 687
             $subtitle       = sprintf(
688 688
                 wp_strip_all_tags(
@@ -706,7 +706,7 @@  discard block
 block discarded – undo
706 706
                         'event_espresso'
707 707
                     )
708 708
                 ),
709
-                '<h2>' . $report_title . '</h2><p>',
709
+                '<h2>'.$report_title.'</h2><p>',
710 710
                 '</p>'
711 711
             ),
712 712
         ];
@@ -739,7 +739,7 @@  discard block
 block discarded – undo
739 739
             foreach ($results as $result) {
740 740
                 $report_column_values = [];
741 741
                 foreach ($result as $property_name => $property_value) {
742
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
742
+                    $property_value = $property_name === 'Registration_Event' ? wp_trim_words(
743 743
                         $property_value,
744 744
                         4,
745 745
                         '...'
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
             array_unshift($regs, $column_titles);
761 761
             // setup the date range.
762 762
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
763
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
763
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
764 764
             $ending_date    = new DateTime("now", $DateTimeZone);
765 765
             $subtitle       = sprintf(
766 766
                 wp_strip_all_tags(
@@ -784,7 +784,7 @@  discard block
 block discarded – undo
784 784
                         'event_espresso'
785 785
                     )
786 786
                 ),
787
-                '<h2>' . $report_title . '</h2><p>',
787
+                '<h2>'.$report_title.'</h2><p>',
788 788
                 '</p>'
789 789
             ),
790 790
         ];
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
         $reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null;
812 812
         /** @var EE_Registration $registration */
813 813
         $registration = EEM_Registration::instance()->get_one_by_ID($reg_id);
814
-        if (! $registration instanceof EE_Registration) {
814
+        if ( ! $registration instanceof EE_Registration) {
815 815
             throw new EE_Error(
816 816
                 sprintf(
817 817
                     esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
@@ -819,8 +819,8 @@  discard block
 block discarded – undo
819 819
                 )
820 820
             );
821 821
         }
822
-        $attendee                                 = $registration->attendee();
823
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
822
+        $attendee = $registration->attendee();
823
+        $this->_admin_page_title .= $this->get_action_link_or_button(
824 824
             'new_registration',
825 825
             'add-registrant',
826 826
             ['event_id' => $registration->event_ID()],
@@ -847,10 +847,10 @@  discard block
 block discarded – undo
847 847
         if ($datetime instanceof EE_Datetime) {
848 848
             $datetime_label = $datetime->get_dtt_display_name(true);
849 849
             $datetime_label .= ! empty($datetime_label)
850
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
850
+                ? ' ('.$datetime->get_dtt_display_name().')'
851 851
                 : $datetime->get_dtt_display_name();
852 852
         }
853
-        $datetime_link                                    = ! empty($dtt_id) && $registration instanceof EE_Registration
853
+        $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration
854 854
             ? EE_Admin_Page::add_query_args_and_nonce(
855 855
                 [
856 856
                     'action'   => 'event_registrations',
@@ -860,8 +860,8 @@  discard block
 block discarded – undo
860 860
                 $this->_admin_base_url
861 861
             )
862 862
             : '';
863
-        $datetime_link                                    = ! empty($datetime_link)
864
-            ? '<a href="' . $datetime_link . '">'
863
+        $datetime_link = ! empty($datetime_link)
864
+            ? '<a href="'.$datetime_link.'">'
865 865
               . '<span id="checkin-dtt">'
866 866
               . $datetime_label
867 867
               . '</span></a>'
@@ -873,8 +873,8 @@  discard block
 block discarded – undo
873 873
             ? $attendee->get_admin_details_link()
874 874
             : '';
875 875
         $attendee_link                                    = ! empty($attendee_link)
876
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
877
-              . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
876
+            ? '<a href="'.$attendee->get_admin_details_link().'"'
877
+              . ' aria-label="'.esc_html__('Click for attendee details', 'event_espresso').'">'
878 878
               . '<span id="checkin-attendee-name">'
879 879
               . $attendee_name
880 880
               . '</span></a>'
@@ -883,25 +883,25 @@  discard block
 block discarded – undo
883 883
             ? $registration->event()->get_admin_details_link()
884 884
             : '';
885 885
         $event_link                                       = ! empty($event_link)
886
-            ? '<a href="' . $event_link . '"'
887
-              . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
886
+            ? '<a href="'.$event_link.'"'
887
+              . ' aria-label="'.esc_html__('Click here to edit event.', 'event_espresso').'">'
888 888
               . '<span id="checkin-event-name">'
889 889
               . $registration->event_name()
890 890
               . '</span>'
891 891
               . '</a>'
892 892
             : '';
893
-        $this->_template_args['before_list_table']        = ! empty($reg_id) && ! empty($dtt_id)
894
-            ? '<h2>' . sprintf(
893
+        $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id)
894
+            ? '<h2>'.sprintf(
895 895
                 esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
896 896
                 $attendee_link,
897 897
                 $datetime_link,
898 898
                 $event_link
899
-            ) . '</h2>'
899
+            ).'</h2>'
900 900
             : '';
901 901
         $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id)
902
-            ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : '';
902
+            ? '<input type="hidden" name="_REG_ID" value="'.$reg_id.'">' : '';
903 903
         $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id)
904
-            ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : '';
904
+            ? '<input type="hidden" name="DTT_ID" value="'.$dtt_id.'">' : '';
905 905
         $this->display_admin_list_table_page_with_no_sidebar();
906 906
     }
907 907
 
@@ -919,7 +919,7 @@  discard block
 block discarded – undo
919 919
     public function toggle_checkin_status()
920 920
     {
921 921
         // first make sure we have the necessary data
922
-        if (! isset($this->_req_data['_regid'])) {
922
+        if ( ! isset($this->_req_data['_regid'])) {
923 923
             EE_Error::add_error(
924 924
                 esc_html__(
925 925
                     'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
@@ -941,7 +941,7 @@  discard block
 block discarded – undo
941 941
         // beautiful! Made it this far so let's get the status.
942 942
         $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
943 943
         // setup new class to return via ajax
944
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
944
+        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses();
945 945
         $this->_template_args['success']            = true;
946 946
         $this->_return_json();
947 947
     }
@@ -968,7 +968,7 @@  discard block
 block discarded – undo
968 968
         ];
969 969
         $new_status = false;
970 970
         // bulk action check in toggle
971
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
971
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
972 972
             // cycle thru checkboxes
973 973
             $checkboxes = $this->_req_data['checkbox'];
974 974
             foreach (array_keys($checkboxes) as $REG_ID) {
@@ -1040,11 +1040,11 @@  discard block
 block discarded – undo
1040 1040
             'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1041 1041
             '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1042 1042
         ];
1043
-        $errors     = 0;
1044
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1043
+        $errors = 0;
1044
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1045 1045
             $checkboxes = $this->_req_data['checkbox'];
1046 1046
             foreach (array_keys($checkboxes) as $CHK_ID) {
1047
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1047
+                if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1048 1048
                     $errors++;
1049 1049
                 }
1050 1050
             }
@@ -1094,8 +1094,8 @@  discard block
 block discarded – undo
1094 1094
             'DTT_ID'  => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0,
1095 1095
             '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0,
1096 1096
         ];
1097
-        if (! empty($this->_req_data['CHK_ID'])) {
1098
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1097
+        if ( ! empty($this->_req_data['CHK_ID'])) {
1098
+            if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1099 1099
                 EE_Error::add_error(
1100 1100
                     esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1101 1101
                     __FILE__,
@@ -1134,7 +1134,7 @@  discard block
 block discarded – undo
1134 1134
     protected function _event_registrations_list_table()
1135 1135
     {
1136 1136
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1137
-        $this->_admin_page_title                  .= isset($this->_req_data['event_id'])
1137
+        $this->_admin_page_title .= isset($this->_req_data['event_id'])
1138 1138
             ? $this->get_action_link_or_button(
1139 1139
                 'new_registration',
1140 1140
                 'add-registrant',
@@ -1170,27 +1170,27 @@  discard block
 block discarded – undo
1170 1170
                 'desc'  => $checkin_invalid->legendLabel(),
1171 1171
             ],
1172 1172
             'approved_status'  => [
1173
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1173
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::APPROVED,
1174 1174
                 'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1175 1175
             ],
1176 1176
             'cancelled_status' => [
1177
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1177
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::CANCELLED,
1178 1178
                 'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1179 1179
             ],
1180 1180
             'declined_status'  => [
1181
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1181
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::DECLINED,
1182 1182
                 'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1183 1183
             ],
1184 1184
             'not_approved'     => [
1185
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1185
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::AWAITING_REVIEW,
1186 1186
                 'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1187 1187
             ],
1188 1188
             'pending_status'   => [
1189
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1189
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::PENDING_PAYMENT,
1190 1190
                 'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1191 1191
             ],
1192 1192
             'wait_list'        => [
1193
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1193
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::WAIT_LIST,
1194 1194
                 'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1195 1195
             ],
1196 1196
         ];
@@ -1220,27 +1220,27 @@  discard block
 block discarded – undo
1220 1220
         if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') {
1221 1221
             $active_status                             = $datetime->get_active_status();
1222 1222
             $datetime_status                           =
1223
-                '<span class="ee-status ee-status-bg--' . esc_attr($active_status) . ' event-active-status-' .
1224
-                esc_attr($active_status) . '">'
1223
+                '<span class="ee-status ee-status-bg--'.esc_attr($active_status).' event-active-status-'.
1224
+                esc_attr($active_status).'">'
1225 1225
                 . EEH_Template::pretty_status($active_status, false, 'sentence')
1226 1226
                 . '</span>';
1227 1227
             $this->_template_args['before_list_table'] .= '<span class="ee-event-datetime-name">';
1228 1228
             $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar-alt"></span>';
1229 1229
             $this->_template_args['before_list_table'] .= $datetime->name();
1230
-            $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )';
1230
+            $this->_template_args['before_list_table'] .= ' ( '.$datetime->date_and_time_range().' )';
1231 1231
             $this->_template_args['before_list_table'] .= $datetime_status;
1232 1232
             $this->_template_args['before_list_table'] .= '</span>';
1233 1233
         }
1234 1234
         $this->_template_args['before_list_table'] .= '</h2>';
1235 1235
         // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status
1236 1236
         // column represents
1237
-        if (! $datetime instanceof EE_Datetime) {
1237
+        if ( ! $datetime instanceof EE_Datetime) {
1238 1238
             $this->_template_args['before_list_table'] .= '
1239 1239
                 <div class="description ee-status-outline ee-status-bg--info" style="white-space: normal;">
1240 1240
                     <h2 style="margin: 1rem; padding: 0;">' . esc_html__(
1241 1241
                         'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1242 1242
                         'event_espresso'
1243
-                    ) . '</h2>
1243
+                    ).'</h2>
1244 1244
                 </div>';
1245 1245
         }
1246 1246
         $this->display_admin_list_table_page_with_no_sidebar();
@@ -1276,7 +1276,7 @@  discard block
 block discarded – undo
1276 1276
     ) {
1277 1277
         $query_params = $this->_get_registration_query_parameters($request, $per_page, $count);
1278 1278
         // unlike the regular registrations list table,
1279
-        $status_ids_array          = apply_filters(
1279
+        $status_ids_array = apply_filters(
1280 1280
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1281 1281
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1282 1282
         );
Please login to merge, or discard this patch.
caffeinated/admin/new/license_keys/License_Keys_Admin_Page.core.php 2 patches
Indentation   +261 added lines, -261 removed lines patch added patch discarded remove patch
@@ -16,266 +16,266 @@
 block discarded – undo
16 16
  */
17 17
 class License_Keys_Admin_Page extends EE_Admin_Page
18 18
 {
19
-    protected function _init_page_props()
20
-    {
21
-        $this->page_slug        = LICENSE_KEYS_PG_SLUG;
22
-        $this->page_label       = LICENSE_KEYS_LABEL;
23
-        $this->_admin_base_url  = LICENSE_KEYS_ADMIN_URL;
24
-        $this->_admin_base_path = LICENSE_KEYS_ADMIN;
25
-    }
26
-
27
-
28
-    protected function _ajax_hooks()
29
-    {
30
-        add_action('wp_ajax_espresso_update_license', [$this, 'updateLicenseKey']);
31
-    }
32
-
33
-
34
-    protected function _define_page_props()
35
-    {
36
-        $this->_admin_page_title = LICENSE_KEYS_LABEL;
37
-    }
38
-
39
-
40
-    protected function _set_page_routes()
41
-    {
42
-        $this->_page_routes = [
43
-            'default'            => [
44
-                'func'       => [$this, 'licenseKeysAdminPage'],
45
-                'capability' => 'manage_options',
46
-            ],
47
-            'update_license_key' => [
48
-                'func'       => [$this, 'updateLicenseKey'],
49
-                'capability' => 'manage_options',
50
-                'noheader'   => true,
51
-            ],
52
-        ];
53
-    }
54
-
55
-
56
-    protected function _set_page_config()
57
-    {
58
-        $this->_page_config = [
59
-            'default' => [
60
-                'nav'           => [
61
-                    'label' => LICENSE_KEYS_LABEL,
62
-                    'icon'  => 'dashicons-admin-network',
63
-                    'order' => 10,
64
-                ],
65
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes),
66
-                'require_nonce' => false,
67
-            ],
68
-        ];
69
-    }
70
-
71
-
72
-    protected function _add_screen_options()
73
-    {
74
-        // TODO: Implement _add_screen_options() method.
75
-    }
76
-
77
-
78
-    protected function _add_feature_pointers()
79
-    {
80
-        // TODO: Implement _add_feature_pointers() method.
81
-    }
82
-
83
-
84
-    public function load_scripts_styles()
85
-    {
86
-        wp_enqueue_style(
87
-            'license_keys_admin_style',
88
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
89
-            [],
90
-            EVENT_ESPRESSO_VERSION
91
-        );
92
-
93
-        wp_enqueue_script(
94
-            'license_keys_admin_js',
95
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
96
-            ['jquery'],
97
-            EVENT_ESPRESSO_VERSION,
98
-            true
99
-        );
100
-        wp_localize_script(
101
-            'license_keys_admin_js',
102
-            'eeLicenseData',
103
-            [
104
-                'domain'              => home_url(),
105
-                'statusMessages'      => LicenseStatus::statusMessages(),
106
-                'confirmDeactivation' => esc_html__(
107
-                    'Are you sure you want to deactivate this license?',
108
-                    'event_espresso'
109
-                ),
110
-                'resetDeactivation'   => esc_html__(
111
-                    'Are you sure you want to reset this license?',
112
-                    'event_espresso'
113
-                ),
114
-            ]
115
-        );
116
-    }
117
-
118
-
119
-    public function admin_init()
120
-    {
121
-        // TODO: Implement admin_init() method.
122
-    }
123
-
124
-
125
-    public function admin_notices()
126
-    {
127
-        // TODO: Implement admin_notices() method.
128
-    }
129
-
130
-
131
-    public function admin_footer_scripts()
132
-    {
133
-        // TODO: Implement admin_footer_scripts() method.
134
-    }
135
-
136
-
137
-    public function _before_page_setup()
138
-    {
139
-        EE_Dependency_Map::instance()->registerDependencies(
140
-            LicenseManager::class,
141
-            [
142
-                LicenseAPI::class              => EE_Dependency_Map::load_from_cache,
143
-                LicenseKeyData::class          => EE_Dependency_Map::load_from_cache,
144
-                PluginLicenseCollection::class => EE_Dependency_Map::load_from_cache,
145
-            ]
146
-        );
147
-        EE_Dependency_Map::instance()->registerDependencies(
148
-            LicenseKeysAdminForm::class,
149
-            ['EE_Registry' => EE_Dependency_Map::load_from_cache]
150
-        );
151
-        parent::_before_page_setup();
152
-    }
153
-
154
-
155
-    private function getLicenseManager(): LicenseManager
156
-    {
157
-        return $this->loader->getShared(LicenseManager::class);
158
-    }
159
-
160
-
161
-    private function getPluginLicenseCollection(): PluginLicenseCollection
162
-    {
163
-        return $this->loader->getShared(PluginLicenseCollection::class);
164
-    }
165
-
166
-
167
-    /**
168
-     * @throws EE_Error
169
-     */
170
-    public function licenseKeysAdminPage()
171
-    {
172
-        $this->_template_args['admin_page_content'] = '';
173
-        try {
174
-            $license_keys_admin_form                    = $this->loader->getShared(LicenseKeysAdminForm::class);
175
-            $this->_template_args['admin_page_content'] = EEH_HTML::div(
176
-                $license_keys_admin_form->display(),
177
-                '',
178
-                'padding'
179
-            );
180
-        } catch (Exception $e) {
181
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
182
-        }
183
-        $this->_set_add_edit_form_tags('update_license_keys');
184
-        $this->_set_publish_post_box_vars();
185
-        $this->display_admin_page_with_sidebar();
186
-    }
187
-
188
-
189
-    /**
190
-     * @throws EE_Error
191
-     */
192
-    public function updateLicenseKey()
193
-    {
194
-        if (current_user_can('manage_options')) {
195
-            $licence_manager  = $this->getLicenseManager();
196
-            $license_action   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ACTION);
197
-            $license_key      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_LICENSE_KEY);
198
-            $item_id          = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_ID, 0, DataType::INT);
199
-            $item_name        = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_NAME);
200
-            $plugin_slug      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_SLUG);
201
-            $plugin_version   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_VER);
202
-            $min_core_version = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_MIN_CORE_VER);
203
-
204
-            $license_data = [];
205
-            switch ($license_action) {
206
-                case LicenseAPI::ACTION_ACTIVATE:
207
-                    $license_data = $licence_manager->activateLicense(
208
-                        $license_key,
209
-                        $item_id,
210
-                        $item_name,
211
-                        $plugin_slug,
212
-                        $plugin_version,
213
-                        $min_core_version
214
-                    );
215
-                    break;
216
-
217
-                case LicenseAPI::ACTION_DEACTIVATE:
218
-                    $license_data = $licence_manager->deactivateLicense(
219
-                        $license_key,
220
-                        $item_id,
221
-                        $item_name,
222
-                        $plugin_slug,
223
-                        $plugin_version,
224
-                        $min_core_version
225
-                    );
226
-                    break;
227
-
228
-                case LicenseAPI::ACTION_CHECK:
229
-                    $license_data = $licence_manager->checkLicense(
230
-                        $license_key,
231
-                        $item_id,
232
-                        $item_name,
233
-                        $plugin_slug,
234
-                        $plugin_version,
235
-                        $min_core_version
236
-                    );
237
-                    break;
238
-
239
-                case LicenseAPI::ACTION_GET_VERSION:
240
-                    $license_data = $licence_manager->getVersionInfo();
241
-                    break;
242
-
243
-                case LicenseAPI::ACTION_RESET:
244
-                    $license_data = $licence_manager->resetLicenseKey($plugin_slug);
245
-                    break;
246
-            }
247
-
248
-            $license_data = (object) $license_data;
249
-            $license_data->statusNotice = LicenseStatus::statusNotice($license_data->license);
250
-            $license_data->statusClass  = LicenseStatus::statusClass($license_data->license);
251
-            $notices = EE_Error::get_notices(false, false, false);
252
-        } else {
253
-            $license_data = new stdClass();
254
-            $notices = [
255
-                'success' => false,
256
-                'errors'  => [
257
-                    esc_html__('You do not have permission to perform this action.', 'event_espresso'),
258
-                ],
259
-            ];
260
-        }
261
-
262
-        if ($this->request->isAjax()) {
263
-            wp_send_json(
264
-                [
265
-                    'return_data' => $license_data,
266
-                    'success'     => $notices['success'],
267
-                    'errors'      => $notices['errors'],
268
-                ]
269
-            );
270
-        }
271
-
272
-        $this->_redirect_after_action(
273
-            empty($notices['errors']),
274
-            '',
275
-            '',
276
-            ['action' => 'default'],
277
-            true
278
-        );
279
-    }
19
+	protected function _init_page_props()
20
+	{
21
+		$this->page_slug        = LICENSE_KEYS_PG_SLUG;
22
+		$this->page_label       = LICENSE_KEYS_LABEL;
23
+		$this->_admin_base_url  = LICENSE_KEYS_ADMIN_URL;
24
+		$this->_admin_base_path = LICENSE_KEYS_ADMIN;
25
+	}
26
+
27
+
28
+	protected function _ajax_hooks()
29
+	{
30
+		add_action('wp_ajax_espresso_update_license', [$this, 'updateLicenseKey']);
31
+	}
32
+
33
+
34
+	protected function _define_page_props()
35
+	{
36
+		$this->_admin_page_title = LICENSE_KEYS_LABEL;
37
+	}
38
+
39
+
40
+	protected function _set_page_routes()
41
+	{
42
+		$this->_page_routes = [
43
+			'default'            => [
44
+				'func'       => [$this, 'licenseKeysAdminPage'],
45
+				'capability' => 'manage_options',
46
+			],
47
+			'update_license_key' => [
48
+				'func'       => [$this, 'updateLicenseKey'],
49
+				'capability' => 'manage_options',
50
+				'noheader'   => true,
51
+			],
52
+		];
53
+	}
54
+
55
+
56
+	protected function _set_page_config()
57
+	{
58
+		$this->_page_config = [
59
+			'default' => [
60
+				'nav'           => [
61
+					'label' => LICENSE_KEYS_LABEL,
62
+					'icon'  => 'dashicons-admin-network',
63
+					'order' => 10,
64
+				],
65
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes),
66
+				'require_nonce' => false,
67
+			],
68
+		];
69
+	}
70
+
71
+
72
+	protected function _add_screen_options()
73
+	{
74
+		// TODO: Implement _add_screen_options() method.
75
+	}
76
+
77
+
78
+	protected function _add_feature_pointers()
79
+	{
80
+		// TODO: Implement _add_feature_pointers() method.
81
+	}
82
+
83
+
84
+	public function load_scripts_styles()
85
+	{
86
+		wp_enqueue_style(
87
+			'license_keys_admin_style',
88
+			LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
89
+			[],
90
+			EVENT_ESPRESSO_VERSION
91
+		);
92
+
93
+		wp_enqueue_script(
94
+			'license_keys_admin_js',
95
+			LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
96
+			['jquery'],
97
+			EVENT_ESPRESSO_VERSION,
98
+			true
99
+		);
100
+		wp_localize_script(
101
+			'license_keys_admin_js',
102
+			'eeLicenseData',
103
+			[
104
+				'domain'              => home_url(),
105
+				'statusMessages'      => LicenseStatus::statusMessages(),
106
+				'confirmDeactivation' => esc_html__(
107
+					'Are you sure you want to deactivate this license?',
108
+					'event_espresso'
109
+				),
110
+				'resetDeactivation'   => esc_html__(
111
+					'Are you sure you want to reset this license?',
112
+					'event_espresso'
113
+				),
114
+			]
115
+		);
116
+	}
117
+
118
+
119
+	public function admin_init()
120
+	{
121
+		// TODO: Implement admin_init() method.
122
+	}
123
+
124
+
125
+	public function admin_notices()
126
+	{
127
+		// TODO: Implement admin_notices() method.
128
+	}
129
+
130
+
131
+	public function admin_footer_scripts()
132
+	{
133
+		// TODO: Implement admin_footer_scripts() method.
134
+	}
135
+
136
+
137
+	public function _before_page_setup()
138
+	{
139
+		EE_Dependency_Map::instance()->registerDependencies(
140
+			LicenseManager::class,
141
+			[
142
+				LicenseAPI::class              => EE_Dependency_Map::load_from_cache,
143
+				LicenseKeyData::class          => EE_Dependency_Map::load_from_cache,
144
+				PluginLicenseCollection::class => EE_Dependency_Map::load_from_cache,
145
+			]
146
+		);
147
+		EE_Dependency_Map::instance()->registerDependencies(
148
+			LicenseKeysAdminForm::class,
149
+			['EE_Registry' => EE_Dependency_Map::load_from_cache]
150
+		);
151
+		parent::_before_page_setup();
152
+	}
153
+
154
+
155
+	private function getLicenseManager(): LicenseManager
156
+	{
157
+		return $this->loader->getShared(LicenseManager::class);
158
+	}
159
+
160
+
161
+	private function getPluginLicenseCollection(): PluginLicenseCollection
162
+	{
163
+		return $this->loader->getShared(PluginLicenseCollection::class);
164
+	}
165
+
166
+
167
+	/**
168
+	 * @throws EE_Error
169
+	 */
170
+	public function licenseKeysAdminPage()
171
+	{
172
+		$this->_template_args['admin_page_content'] = '';
173
+		try {
174
+			$license_keys_admin_form                    = $this->loader->getShared(LicenseKeysAdminForm::class);
175
+			$this->_template_args['admin_page_content'] = EEH_HTML::div(
176
+				$license_keys_admin_form->display(),
177
+				'',
178
+				'padding'
179
+			);
180
+		} catch (Exception $e) {
181
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
182
+		}
183
+		$this->_set_add_edit_form_tags('update_license_keys');
184
+		$this->_set_publish_post_box_vars();
185
+		$this->display_admin_page_with_sidebar();
186
+	}
187
+
188
+
189
+	/**
190
+	 * @throws EE_Error
191
+	 */
192
+	public function updateLicenseKey()
193
+	{
194
+		if (current_user_can('manage_options')) {
195
+			$licence_manager  = $this->getLicenseManager();
196
+			$license_action   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ACTION);
197
+			$license_key      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_LICENSE_KEY);
198
+			$item_id          = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_ID, 0, DataType::INT);
199
+			$item_name        = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_NAME);
200
+			$plugin_slug      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_SLUG);
201
+			$plugin_version   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_VER);
202
+			$min_core_version = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_MIN_CORE_VER);
203
+
204
+			$license_data = [];
205
+			switch ($license_action) {
206
+				case LicenseAPI::ACTION_ACTIVATE:
207
+					$license_data = $licence_manager->activateLicense(
208
+						$license_key,
209
+						$item_id,
210
+						$item_name,
211
+						$plugin_slug,
212
+						$plugin_version,
213
+						$min_core_version
214
+					);
215
+					break;
216
+
217
+				case LicenseAPI::ACTION_DEACTIVATE:
218
+					$license_data = $licence_manager->deactivateLicense(
219
+						$license_key,
220
+						$item_id,
221
+						$item_name,
222
+						$plugin_slug,
223
+						$plugin_version,
224
+						$min_core_version
225
+					);
226
+					break;
227
+
228
+				case LicenseAPI::ACTION_CHECK:
229
+					$license_data = $licence_manager->checkLicense(
230
+						$license_key,
231
+						$item_id,
232
+						$item_name,
233
+						$plugin_slug,
234
+						$plugin_version,
235
+						$min_core_version
236
+					);
237
+					break;
238
+
239
+				case LicenseAPI::ACTION_GET_VERSION:
240
+					$license_data = $licence_manager->getVersionInfo();
241
+					break;
242
+
243
+				case LicenseAPI::ACTION_RESET:
244
+					$license_data = $licence_manager->resetLicenseKey($plugin_slug);
245
+					break;
246
+			}
247
+
248
+			$license_data = (object) $license_data;
249
+			$license_data->statusNotice = LicenseStatus::statusNotice($license_data->license);
250
+			$license_data->statusClass  = LicenseStatus::statusClass($license_data->license);
251
+			$notices = EE_Error::get_notices(false, false, false);
252
+		} else {
253
+			$license_data = new stdClass();
254
+			$notices = [
255
+				'success' => false,
256
+				'errors'  => [
257
+					esc_html__('You do not have permission to perform this action.', 'event_espresso'),
258
+				],
259
+			];
260
+		}
261
+
262
+		if ($this->request->isAjax()) {
263
+			wp_send_json(
264
+				[
265
+					'return_data' => $license_data,
266
+					'success'     => $notices['success'],
267
+					'errors'      => $notices['errors'],
268
+				]
269
+			);
270
+		}
271
+
272
+		$this->_redirect_after_action(
273
+			empty($notices['errors']),
274
+			'',
275
+			'',
276
+			['action' => 'default'],
277
+			true
278
+		);
279
+	}
280 280
 }
281 281
 
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -85,14 +85,14 @@
 block discarded – undo
85 85
     {
86 86
         wp_enqueue_style(
87 87
             'license_keys_admin_style',
88
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
88
+            LICENSE_KEYS_ASSETS_URL.'license_keys_admin.css',
89 89
             [],
90 90
             EVENT_ESPRESSO_VERSION
91 91
         );
92 92
 
93 93
         wp_enqueue_script(
94 94
             'license_keys_admin_js',
95
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
95
+            LICENSE_KEYS_ASSETS_URL.'license_keys_admin.js',
96 96
             ['jquery'],
97 97
             EVENT_ESPRESSO_VERSION,
98 98
             true
Please login to merge, or discard this patch.
caffeinated/admin/new/license_keys/License_Keys_Admin_Page_Init.core.php 2 patches
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -12,42 +12,42 @@
 block discarded – undo
12 12
  */
13 13
 class License_Keys_Admin_Page_Init extends EE_Admin_Page_Init
14 14
 {
15
-    public function __construct()
16
-    {
17
-        if (! defined('LICENSE_KEYS_PG_SLUG')) {
18
-            define('LICENSE_KEYS_PG_SLUG', 'espresso_license_keys');
19
-            define('LICENSE_KEYS_LABEL', esc_html__('License Keys', 'event_espresso'));
20
-            define('LICENSE_KEYS_ADMIN', EE_CORE_CAF_ADMIN . 'new/license_keys/');
21
-            define('LICENSE_KEYS_ADMIN_URL', admin_url('admin.php?page=' . LICENSE_KEYS_PG_SLUG));
22
-            define('LICENSE_KEYS_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/license_keys/assets/');
23
-        }
24
-        parent::__construct();
25
-        $this->_folder_path = EE_CORE_CAF_ADMIN . 'new/license_keys/';
26
-    }
15
+	public function __construct()
16
+	{
17
+		if (! defined('LICENSE_KEYS_PG_SLUG')) {
18
+			define('LICENSE_KEYS_PG_SLUG', 'espresso_license_keys');
19
+			define('LICENSE_KEYS_LABEL', esc_html__('License Keys', 'event_espresso'));
20
+			define('LICENSE_KEYS_ADMIN', EE_CORE_CAF_ADMIN . 'new/license_keys/');
21
+			define('LICENSE_KEYS_ADMIN_URL', admin_url('admin.php?page=' . LICENSE_KEYS_PG_SLUG));
22
+			define('LICENSE_KEYS_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/license_keys/assets/');
23
+		}
24
+		parent::__construct();
25
+		$this->_folder_path = EE_CORE_CAF_ADMIN . 'new/license_keys/';
26
+	}
27 27
 
28 28
 
29
-    protected function _set_init_properties()
30
-    {
31
-        $this->label = LICENSE_KEYS_LABEL;
32
-    }
29
+	protected function _set_init_properties()
30
+	{
31
+		$this->label = LICENSE_KEYS_LABEL;
32
+	}
33 33
 
34 34
 
35
-    protected function _set_menu_map()
36
-    {
37
-        $feature = $this->loader->getShared(FeatureFlags::class);
38
-        if (! $feature->allowed('use_edd_plugin_licensing') || ! is_main_site()) {
39
-            return;
40
-        }
41
-        $this->_menu_map = new AdminMenuSubItem([
42
-            'menu_type'     => AdminMenuItem::TYPE_MENU_SUB_ITEM,
43
-            'menu_group'    => 'settings',
44
-            'menu_order'    => 10,
45
-            'show_on_menu'  => AdminMenuItem::DISPLAY_BLOG_ONLY,
46
-            'parent_slug'   => 'espresso_events',
47
-            'menu_slug'     => LICENSE_KEYS_PG_SLUG,
48
-            'menu_label'    => LICENSE_KEYS_LABEL,
49
-            'capability'    => 'manage_options',
50
-            'admin_init_page' => $this,
51
-        ]);
52
-    }
35
+	protected function _set_menu_map()
36
+	{
37
+		$feature = $this->loader->getShared(FeatureFlags::class);
38
+		if (! $feature->allowed('use_edd_plugin_licensing') || ! is_main_site()) {
39
+			return;
40
+		}
41
+		$this->_menu_map = new AdminMenuSubItem([
42
+			'menu_type'     => AdminMenuItem::TYPE_MENU_SUB_ITEM,
43
+			'menu_group'    => 'settings',
44
+			'menu_order'    => 10,
45
+			'show_on_menu'  => AdminMenuItem::DISPLAY_BLOG_ONLY,
46
+			'parent_slug'   => 'espresso_events',
47
+			'menu_slug'     => LICENSE_KEYS_PG_SLUG,
48
+			'menu_label'    => LICENSE_KEYS_LABEL,
49
+			'capability'    => 'manage_options',
50
+			'admin_init_page' => $this,
51
+		]);
52
+	}
53 53
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -14,15 +14,15 @@  discard block
 block discarded – undo
14 14
 {
15 15
     public function __construct()
16 16
     {
17
-        if (! defined('LICENSE_KEYS_PG_SLUG')) {
17
+        if ( ! defined('LICENSE_KEYS_PG_SLUG')) {
18 18
             define('LICENSE_KEYS_PG_SLUG', 'espresso_license_keys');
19 19
             define('LICENSE_KEYS_LABEL', esc_html__('License Keys', 'event_espresso'));
20
-            define('LICENSE_KEYS_ADMIN', EE_CORE_CAF_ADMIN . 'new/license_keys/');
21
-            define('LICENSE_KEYS_ADMIN_URL', admin_url('admin.php?page=' . LICENSE_KEYS_PG_SLUG));
22
-            define('LICENSE_KEYS_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/license_keys/assets/');
20
+            define('LICENSE_KEYS_ADMIN', EE_CORE_CAF_ADMIN.'new/license_keys/');
21
+            define('LICENSE_KEYS_ADMIN_URL', admin_url('admin.php?page='.LICENSE_KEYS_PG_SLUG));
22
+            define('LICENSE_KEYS_ASSETS_URL', EE_CORE_CAF_ADMIN_URL.'new/license_keys/assets/');
23 23
         }
24 24
         parent::__construct();
25
-        $this->_folder_path = EE_CORE_CAF_ADMIN . 'new/license_keys/';
25
+        $this->_folder_path = EE_CORE_CAF_ADMIN.'new/license_keys/';
26 26
     }
27 27
 
28 28
 
@@ -35,7 +35,7 @@  discard block
 block discarded – undo
35 35
     protected function _set_menu_map()
36 36
     {
37 37
         $feature = $this->loader->getShared(FeatureFlags::class);
38
-        if (! $feature->allowed('use_edd_plugin_licensing') || ! is_main_site()) {
38
+        if ( ! $feature->allowed('use_edd_plugin_licensing') || ! is_main_site()) {
39 39
             return;
40 40
         }
41 41
         $this->_menu_map = new AdminMenuSubItem([
Please login to merge, or discard this patch.