Completed
Branch master (c63335)
by
unknown
17:58 queued 13:20
created
admin/extend/messages/espresso_events_Messages_Hooks_Extend.class.php 2 patches
Indentation   +305 added lines, -305 removed lines patch added patch discarded remove patch
@@ -16,315 +16,315 @@
 block discarded – undo
16 16
  */
17 17
 class espresso_events_Messages_Hooks_Extend extends espresso_events_Messages_Hooks
18 18
 {
19
-    /**
20
-     * espresso_events_Messages_Hooks_Extend constructor.
21
-     *
22
-     * @param EE_Admin_Page $admin_page
23
-     * @throws EE_Error
24
-     * @throws ReflectionException
25
-     */
26
-    public function __construct(EE_Admin_Page $admin_page)
27
-    {
28
-        /**
29
-         * Add cap restriction ... metaboxes should not show if user does not have the ability to edit_custom_messages
30
-         */
31
-        if (
32
-            ! EE_Registry::instance()->CAP->current_user_can(
33
-                'ee_edit_messages',
34
-                'messages_events_editor_metabox'
35
-            )
36
-        ) {
37
-            return;
38
-        }
39
-        add_filter(
40
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
41
-            [$this, 'caf_updates']
42
-        );
43
-        add_action(
44
-            'AHEE__Extend_Events_Admin_Page___duplicate_event__after',
45
-            [$this, 'duplicate_custom_message_settings'],
46
-            10,
47
-            2
48
-        );
49
-        parent::__construct($admin_page);
50
-    }
51
-
52
-
53
-    /**
54
-     * extending the properties set in espresso_events_Messages_Hooks
55
-     *
56
-     * @access protected
57
-     * @return void
58
-     */
59
-    protected function _extend_properties()
60
-    {
61
-        define('EE_MSGS_EXTEND_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'messages/assets/');
62
-        $this->_ajax_func = ['ee_msgs_create_new_custom' => 'create_new_custom'];
63
-        $this->_metaboxes = [
64
-            0 => [
65
-                'page_route' => ['edit', 'create_new'],
66
-                'func'       => 'messages_metabox',
67
-                'label'      => esc_html__('Notifications', 'event_espresso'),
68
-                'priority'   => 'high',
69
-            ],
70
-        ];
71
-
72
-        // see explanation for layout in EE_Admin_Hooks
73
-        $this->_scripts_styles = [
74
-            'registers' => [
75
-                'events_msg_admin'     => [
76
-                    'url'     => EE_MSGS_EXTEND_ASSETS_URL . 'events_messages_admin.js',
77
-                    'depends' => ['ee-dialog', 'ee-parse-uri', 'ee-serialize-full-array'],
78
-                ],
79
-                'events_msg_admin_css' => [
80
-                    'url'  => EE_MSGS_EXTEND_ASSETS_URL . 'ee_msg_events_admin.css',
81
-                    'type' => 'css',
82
-                ],
83
-            ],
84
-            'enqueues'  => [
85
-                'events_msg_admin'     => ['edit', 'create_new'],
86
-                'events_msg_admin_css' => ['edit', 'create_new'],
87
-            ],
88
-        ];
89
-    }
90
-
91
-
92
-    public function caf_updates($update_callbacks)
93
-    {
94
-        $update_callbacks[] = [$this, 'attach_evt_message_templates'];
95
-        return $update_callbacks;
96
-    }
97
-
98
-
99
-    /**
100
-     * Handles attaching Message Templates to the Event on save.
101
-     *
102
-     * @param EE_Event $event EE event object
103
-     * @param array    $data  The request data from the form
104
-     * @return bool success or fail
105
-     * @throws EE_Error
106
-     * @throws ReflectionException
107
-     */
108
-    public function attach_evt_message_templates(EE_Event $event, array $data): bool
109
-    {
110
-        $success = true;
111
-        if (isset($data['event_message_templates_relation'])) {
112
-            // first get all existing relations on the Event for message types.
113
-            $existing_templates = EEM_Event_Message_Template::instance()->messageTemplateGroupIDsForEvent($event);
114
-            $current_templates  = $data['event_message_templates_relation'];
115
-            // new templates are those in the $current_templates array that don't exist in $existing_templates
116
-            $templates_to_add = array_diff($current_templates, $existing_templates);
117
-            foreach ($templates_to_add as $template_to_add) {
118
-                $added_template = $event->_add_relation_to($template_to_add, 'Message_Template_Group');
119
-                // toggle success to false if we don't get back a template group object
120
-                $success = $added_template instanceof EE_Message_Template_Group ? $success : false;
121
-            }
122
-            // templates to remove are those in the $existing_templates array that don't exist in $current_templates
123
-            $templates_to_remove = array_diff($existing_templates, $current_templates);
124
-            foreach ($templates_to_remove as $template_to_remove) {
125
-                $removed_template = $event->_remove_relation_to($template_to_remove, 'Message_Template_Group');
126
-                // toggle success to false if we don't get back a template group object
127
-                $success = $removed_template instanceof EE_Message_Template_Group ? $success : false;
128
-            }
129
-        }
130
-        return $success;
131
-    }
132
-
133
-
134
-    /**
135
-     * @param $event
136
-     * @param $callback_args
137
-     * @return string
138
-     * @throws EE_Error
139
-     * @throws ReflectionException
140
-     */
141
-    public function messages_metabox($event, $callback_args)
142
-    {
143
-        // convert 'evt_id' to 'EVT_ID'
144
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
145
-        $EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
146
-        $EVT_ID = $this->request->getRequestParam('evt_id', $EVT_ID, 'int');
147
-        $this->request->setRequestParam('EVT_ID', $EVT_ID);
148
-
149
-        // get the active messengers (b/c messenger objects have the active message templates)
150
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
151
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
152
-        $active_messengers        = $message_resource_manager->active_messengers();
153
-        $tabs                     = [];
154
-
155
-        // empty messengers?
156
-        // Note message types will always have at least one available because every messenger has a default message type
157
-        // associated with it (payment) if no other message types are selected.
158
-        if (empty($active_messengers)) {
159
-            $msg_activate_url = EE_Admin_Page::add_query_args_and_nonce(
160
-                ['action' => 'settings'],
161
-                EE_MSG_ADMIN_URL
162
-            );
163
-            $error_msg        = sprintf(
164
-                esc_html__(
165
-                    'There are no active messengers. So no notifications will go out for %1$sany%2$s events.  You will want to %3$sActivate a Messenger%4$s.',
166
-                    'event_espresso'
167
-                ),
168
-                '<strong>',
169
-                '</strong>',
170
-                '<a href="' . esc_url_raw($msg_activate_url) . '">',
171
-                '</a>'
172
-            );
173
-            $error_content    = '<div class="error"><p>' . $error_msg . '</p></div>';
174
-            $internal_content = '<div id="messages-error"><p>' . $error_msg . '</p></div>';
175
-
176
-            echo wp_kses($error_content, AllowedTags::getAllowedTags());
177
-            echo wp_kses($internal_content, AllowedTags::getAllowedTags());
178
-            return '';
179
-        }
180
-
181
-        // get content for active messengers
182
-        foreach ($active_messengers as $name => $messenger) {
183
-            // first check if there are any active message types for this messenger.
184
-            $active_mts = $message_resource_manager->get_active_message_types_for_messenger($name);
185
-            if (empty($active_mts)) {
186
-                continue;
187
-            }
188
-
189
-            $tab_content = $messenger->get_messenger_admin_page_content(
190
-                'events',
191
-                'edit',
192
-                ['event' => $EVT_ID]
193
-            );
194
-
195
-            if (! empty($tab_content)) {
196
-                $tabs[ $name ] = $tab_content;
197
-            }
198
-        }
199
-
200
-        // we want this to be tabbed content so let's use the EEH_Tabbed_Content::display helper.
201
-        $tabbed_content = EEH_Tabbed_Content::display($tabs);
202
-        if ($tabbed_content instanceof WP_Error) {
203
-            $tabbed_content = $tabbed_content->get_error_message();
204
-        }
205
-
206
-        $notices = '
19
+	/**
20
+	 * espresso_events_Messages_Hooks_Extend constructor.
21
+	 *
22
+	 * @param EE_Admin_Page $admin_page
23
+	 * @throws EE_Error
24
+	 * @throws ReflectionException
25
+	 */
26
+	public function __construct(EE_Admin_Page $admin_page)
27
+	{
28
+		/**
29
+		 * Add cap restriction ... metaboxes should not show if user does not have the ability to edit_custom_messages
30
+		 */
31
+		if (
32
+			! EE_Registry::instance()->CAP->current_user_can(
33
+				'ee_edit_messages',
34
+				'messages_events_editor_metabox'
35
+			)
36
+		) {
37
+			return;
38
+		}
39
+		add_filter(
40
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
41
+			[$this, 'caf_updates']
42
+		);
43
+		add_action(
44
+			'AHEE__Extend_Events_Admin_Page___duplicate_event__after',
45
+			[$this, 'duplicate_custom_message_settings'],
46
+			10,
47
+			2
48
+		);
49
+		parent::__construct($admin_page);
50
+	}
51
+
52
+
53
+	/**
54
+	 * extending the properties set in espresso_events_Messages_Hooks
55
+	 *
56
+	 * @access protected
57
+	 * @return void
58
+	 */
59
+	protected function _extend_properties()
60
+	{
61
+		define('EE_MSGS_EXTEND_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'messages/assets/');
62
+		$this->_ajax_func = ['ee_msgs_create_new_custom' => 'create_new_custom'];
63
+		$this->_metaboxes = [
64
+			0 => [
65
+				'page_route' => ['edit', 'create_new'],
66
+				'func'       => 'messages_metabox',
67
+				'label'      => esc_html__('Notifications', 'event_espresso'),
68
+				'priority'   => 'high',
69
+			],
70
+		];
71
+
72
+		// see explanation for layout in EE_Admin_Hooks
73
+		$this->_scripts_styles = [
74
+			'registers' => [
75
+				'events_msg_admin'     => [
76
+					'url'     => EE_MSGS_EXTEND_ASSETS_URL . 'events_messages_admin.js',
77
+					'depends' => ['ee-dialog', 'ee-parse-uri', 'ee-serialize-full-array'],
78
+				],
79
+				'events_msg_admin_css' => [
80
+					'url'  => EE_MSGS_EXTEND_ASSETS_URL . 'ee_msg_events_admin.css',
81
+					'type' => 'css',
82
+				],
83
+			],
84
+			'enqueues'  => [
85
+				'events_msg_admin'     => ['edit', 'create_new'],
86
+				'events_msg_admin_css' => ['edit', 'create_new'],
87
+			],
88
+		];
89
+	}
90
+
91
+
92
+	public function caf_updates($update_callbacks)
93
+	{
94
+		$update_callbacks[] = [$this, 'attach_evt_message_templates'];
95
+		return $update_callbacks;
96
+	}
97
+
98
+
99
+	/**
100
+	 * Handles attaching Message Templates to the Event on save.
101
+	 *
102
+	 * @param EE_Event $event EE event object
103
+	 * @param array    $data  The request data from the form
104
+	 * @return bool success or fail
105
+	 * @throws EE_Error
106
+	 * @throws ReflectionException
107
+	 */
108
+	public function attach_evt_message_templates(EE_Event $event, array $data): bool
109
+	{
110
+		$success = true;
111
+		if (isset($data['event_message_templates_relation'])) {
112
+			// first get all existing relations on the Event for message types.
113
+			$existing_templates = EEM_Event_Message_Template::instance()->messageTemplateGroupIDsForEvent($event);
114
+			$current_templates  = $data['event_message_templates_relation'];
115
+			// new templates are those in the $current_templates array that don't exist in $existing_templates
116
+			$templates_to_add = array_diff($current_templates, $existing_templates);
117
+			foreach ($templates_to_add as $template_to_add) {
118
+				$added_template = $event->_add_relation_to($template_to_add, 'Message_Template_Group');
119
+				// toggle success to false if we don't get back a template group object
120
+				$success = $added_template instanceof EE_Message_Template_Group ? $success : false;
121
+			}
122
+			// templates to remove are those in the $existing_templates array that don't exist in $current_templates
123
+			$templates_to_remove = array_diff($existing_templates, $current_templates);
124
+			foreach ($templates_to_remove as $template_to_remove) {
125
+				$removed_template = $event->_remove_relation_to($template_to_remove, 'Message_Template_Group');
126
+				// toggle success to false if we don't get back a template group object
127
+				$success = $removed_template instanceof EE_Message_Template_Group ? $success : false;
128
+			}
129
+		}
130
+		return $success;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param $event
136
+	 * @param $callback_args
137
+	 * @return string
138
+	 * @throws EE_Error
139
+	 * @throws ReflectionException
140
+	 */
141
+	public function messages_metabox($event, $callback_args)
142
+	{
143
+		// convert 'evt_id' to 'EVT_ID'
144
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
145
+		$EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
146
+		$EVT_ID = $this->request->getRequestParam('evt_id', $EVT_ID, 'int');
147
+		$this->request->setRequestParam('EVT_ID', $EVT_ID);
148
+
149
+		// get the active messengers (b/c messenger objects have the active message templates)
150
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
151
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
152
+		$active_messengers        = $message_resource_manager->active_messengers();
153
+		$tabs                     = [];
154
+
155
+		// empty messengers?
156
+		// Note message types will always have at least one available because every messenger has a default message type
157
+		// associated with it (payment) if no other message types are selected.
158
+		if (empty($active_messengers)) {
159
+			$msg_activate_url = EE_Admin_Page::add_query_args_and_nonce(
160
+				['action' => 'settings'],
161
+				EE_MSG_ADMIN_URL
162
+			);
163
+			$error_msg        = sprintf(
164
+				esc_html__(
165
+					'There are no active messengers. So no notifications will go out for %1$sany%2$s events.  You will want to %3$sActivate a Messenger%4$s.',
166
+					'event_espresso'
167
+				),
168
+				'<strong>',
169
+				'</strong>',
170
+				'<a href="' . esc_url_raw($msg_activate_url) . '">',
171
+				'</a>'
172
+			);
173
+			$error_content    = '<div class="error"><p>' . $error_msg . '</p></div>';
174
+			$internal_content = '<div id="messages-error"><p>' . $error_msg . '</p></div>';
175
+
176
+			echo wp_kses($error_content, AllowedTags::getAllowedTags());
177
+			echo wp_kses($internal_content, AllowedTags::getAllowedTags());
178
+			return '';
179
+		}
180
+
181
+		// get content for active messengers
182
+		foreach ($active_messengers as $name => $messenger) {
183
+			// first check if there are any active message types for this messenger.
184
+			$active_mts = $message_resource_manager->get_active_message_types_for_messenger($name);
185
+			if (empty($active_mts)) {
186
+				continue;
187
+			}
188
+
189
+			$tab_content = $messenger->get_messenger_admin_page_content(
190
+				'events',
191
+				'edit',
192
+				['event' => $EVT_ID]
193
+			);
194
+
195
+			if (! empty($tab_content)) {
196
+				$tabs[ $name ] = $tab_content;
197
+			}
198
+		}
199
+
200
+		// we want this to be tabbed content so let's use the EEH_Tabbed_Content::display helper.
201
+		$tabbed_content = EEH_Tabbed_Content::display($tabs);
202
+		if ($tabbed_content instanceof WP_Error) {
203
+			$tabbed_content = $tabbed_content->get_error_message();
204
+		}
205
+
206
+		$notices = '
207 207
         <div id="espresso-ajax-loading" class="ajax-loader-grey">
208 208
             <span class="ee-spinner ee-spin"></span>
209 209
             <span class="hidden">' . esc_html__('loading...', 'event_espresso') . '</span>
210 210
         </div>
211 211
         <div class="ee-notices"></div>';
212 212
 
213
-        if (defined('DOING_AJAX')) {
214
-            return $tabbed_content;
215
-        }
216
-
217
-        do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__before_content');
218
-        echo wp_kses(
219
-            $notices . '<div class="messages-tabs-content">' . $tabbed_content . '</div>',
220
-            AllowedTags::getWithFormTags()
221
-        );
222
-        do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__after_content');
223
-        return '';
224
-    }
225
-
226
-
227
-    /**
228
-     * Ajax callback for ee_msgs_create_new_custom ajax request.
229
-     * Takes incoming GRP_ID and name and description values from ajax request
230
-     * to create a new custom template based off of the incoming GRP_ID.
231
-     *
232
-     * @access public
233
-     * @return void
234
-     * @throws EE_Error
235
-     * @throws ReflectionException
236
-     */
237
-    public function create_new_custom()
238
-    {
239
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_edit_messages', 'create_new_custom_ajax')) {
240
-            wp_die(esc_html__('You don\'t have privileges to do this action', 'event_espresso'));
241
-        }
242
-
243
-        /** @var RequestInterface $request */
244
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
245
-        $new_template = [];
246
-
247
-        // let's clean up the request data a bit for downstream usage of name and description.
248
-        $templateName = $this->request->getRequestParam('custom_template_args[MTP_name]', '');
249
-        if (! $templateName) {
250
-            EE_Error::add_error(
251
-                esc_html__(
252
-                    'Please provide a template name when creating a new message template.',
253
-                    'event_espresso'
254
-                ),
255
-                __FILE__,
256
-                __FUNCTION__,
257
-                __LINE__
258
-            );
259
-        } else {
260
-            $request->setRequestParam('templateName', $templateName);
261
-            $templateDescription = $this->request->getRequestParam('custom_template_args[MTP_description]', '');
262
-            $request->setRequestParam('templateDescription', $templateDescription);
263
-
264
-            /** @var MessageTemplateManager $message_template_manager */
265
-            $message_template_manager = LoaderFactory::getShared(MessageTemplateManager::class);
266
-            $new_template = $message_template_manager->generateNewTemplates();
267
-        }
268
-
269
-        if ($templateName && $new_template) {
270
-            EE_Error::overwrite_success();
271
-            EE_Error::add_success(
272
-                esc_html__(
273
-                    'The new template has been created and automatically selected for this event. You can edit the new template by clicking the edit button. Note before this template is assigned to this event, the event must be saved.',
274
-                    'event_espresso'
275
-                )
276
-            );
277
-        }
278
-        $this->returnJson(
279
-            '',
280
-            [
281
-                'grpID'        => $new_template['GRP_ID'] ?? 0,
282
-                'templateName' => $templateName,
283
-                'success'      => (bool) $new_template,
284
-                'close'        => true,
285
-            ],
286
-        );
287
-
288
-    }
289
-
290
-
291
-    public function create_new_admin_footer()
292
-    {
293
-        $this->edit_admin_footer();
294
-    }
295
-
296
-
297
-    /**
298
-     * This is the dynamic method for this class
299
-     * that will end up hooking into the 'admin_footer' hook on the 'edit_event' route in the events page.
300
-     *
301
-     * @return void
302
-     * @throws DomainException
303
-     */
304
-    public function edit_admin_footer()
305
-    {
306
-        EEH_Template::display_template(
307
-            EE_CORE_CAF_ADMIN_EXTEND . 'messages/templates/create_custom_template_form.template.php'
308
-        );
309
-    }
310
-
311
-
312
-    /**
313
-     * Callback for AHEE__Extend_Events_Admin_Page___duplicate_event__after hook used to ensure new events duplicate
314
-     * the assigned custom message templates.
315
-     *
316
-     * @param EE_Event $new_event
317
-     * @param EE_Event $original_event
318
-     * @throws EE_Error
319
-     * @throws ReflectionException
320
-     */
321
-    public function duplicate_custom_message_settings(EE_Event $new_event, EE_Event $original_event)
322
-    {
323
-        $message_template_groups = $original_event->get_many_related('Message_Template_Group');
324
-        foreach ($message_template_groups as $message_template_group) {
325
-            $new_event->_add_relation_to($message_template_group, 'Message_Template_Group');
326
-        }
327
-        // save new event
328
-        $new_event->save();
329
-    }
213
+		if (defined('DOING_AJAX')) {
214
+			return $tabbed_content;
215
+		}
216
+
217
+		do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__before_content');
218
+		echo wp_kses(
219
+			$notices . '<div class="messages-tabs-content">' . $tabbed_content . '</div>',
220
+			AllowedTags::getWithFormTags()
221
+		);
222
+		do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__after_content');
223
+		return '';
224
+	}
225
+
226
+
227
+	/**
228
+	 * Ajax callback for ee_msgs_create_new_custom ajax request.
229
+	 * Takes incoming GRP_ID and name and description values from ajax request
230
+	 * to create a new custom template based off of the incoming GRP_ID.
231
+	 *
232
+	 * @access public
233
+	 * @return void
234
+	 * @throws EE_Error
235
+	 * @throws ReflectionException
236
+	 */
237
+	public function create_new_custom()
238
+	{
239
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_edit_messages', 'create_new_custom_ajax')) {
240
+			wp_die(esc_html__('You don\'t have privileges to do this action', 'event_espresso'));
241
+		}
242
+
243
+		/** @var RequestInterface $request */
244
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
245
+		$new_template = [];
246
+
247
+		// let's clean up the request data a bit for downstream usage of name and description.
248
+		$templateName = $this->request->getRequestParam('custom_template_args[MTP_name]', '');
249
+		if (! $templateName) {
250
+			EE_Error::add_error(
251
+				esc_html__(
252
+					'Please provide a template name when creating a new message template.',
253
+					'event_espresso'
254
+				),
255
+				__FILE__,
256
+				__FUNCTION__,
257
+				__LINE__
258
+			);
259
+		} else {
260
+			$request->setRequestParam('templateName', $templateName);
261
+			$templateDescription = $this->request->getRequestParam('custom_template_args[MTP_description]', '');
262
+			$request->setRequestParam('templateDescription', $templateDescription);
263
+
264
+			/** @var MessageTemplateManager $message_template_manager */
265
+			$message_template_manager = LoaderFactory::getShared(MessageTemplateManager::class);
266
+			$new_template = $message_template_manager->generateNewTemplates();
267
+		}
268
+
269
+		if ($templateName && $new_template) {
270
+			EE_Error::overwrite_success();
271
+			EE_Error::add_success(
272
+				esc_html__(
273
+					'The new template has been created and automatically selected for this event. You can edit the new template by clicking the edit button. Note before this template is assigned to this event, the event must be saved.',
274
+					'event_espresso'
275
+				)
276
+			);
277
+		}
278
+		$this->returnJson(
279
+			'',
280
+			[
281
+				'grpID'        => $new_template['GRP_ID'] ?? 0,
282
+				'templateName' => $templateName,
283
+				'success'      => (bool) $new_template,
284
+				'close'        => true,
285
+			],
286
+		);
287
+
288
+	}
289
+
290
+
291
+	public function create_new_admin_footer()
292
+	{
293
+		$this->edit_admin_footer();
294
+	}
295
+
296
+
297
+	/**
298
+	 * This is the dynamic method for this class
299
+	 * that will end up hooking into the 'admin_footer' hook on the 'edit_event' route in the events page.
300
+	 *
301
+	 * @return void
302
+	 * @throws DomainException
303
+	 */
304
+	public function edit_admin_footer()
305
+	{
306
+		EEH_Template::display_template(
307
+			EE_CORE_CAF_ADMIN_EXTEND . 'messages/templates/create_custom_template_form.template.php'
308
+		);
309
+	}
310
+
311
+
312
+	/**
313
+	 * Callback for AHEE__Extend_Events_Admin_Page___duplicate_event__after hook used to ensure new events duplicate
314
+	 * the assigned custom message templates.
315
+	 *
316
+	 * @param EE_Event $new_event
317
+	 * @param EE_Event $original_event
318
+	 * @throws EE_Error
319
+	 * @throws ReflectionException
320
+	 */
321
+	public function duplicate_custom_message_settings(EE_Event $new_event, EE_Event $original_event)
322
+	{
323
+		$message_template_groups = $original_event->get_many_related('Message_Template_Group');
324
+		foreach ($message_template_groups as $message_template_group) {
325
+			$new_event->_add_relation_to($message_template_group, 'Message_Template_Group');
326
+		}
327
+		// save new event
328
+		$new_event->save();
329
+	}
330 330
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
      */
59 59
     protected function _extend_properties()
60 60
     {
61
-        define('EE_MSGS_EXTEND_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'messages/assets/');
61
+        define('EE_MSGS_EXTEND_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'messages/assets/');
62 62
         $this->_ajax_func = ['ee_msgs_create_new_custom' => 'create_new_custom'];
63 63
         $this->_metaboxes = [
64 64
             0 => [
@@ -73,11 +73,11 @@  discard block
 block discarded – undo
73 73
         $this->_scripts_styles = [
74 74
             'registers' => [
75 75
                 'events_msg_admin'     => [
76
-                    'url'     => EE_MSGS_EXTEND_ASSETS_URL . 'events_messages_admin.js',
76
+                    'url'     => EE_MSGS_EXTEND_ASSETS_URL.'events_messages_admin.js',
77 77
                     'depends' => ['ee-dialog', 'ee-parse-uri', 'ee-serialize-full-array'],
78 78
                 ],
79 79
                 'events_msg_admin_css' => [
80
-                    'url'  => EE_MSGS_EXTEND_ASSETS_URL . 'ee_msg_events_admin.css',
80
+                    'url'  => EE_MSGS_EXTEND_ASSETS_URL.'ee_msg_events_admin.css',
81 81
                     'type' => 'css',
82 82
                 ],
83 83
             ],
@@ -160,18 +160,18 @@  discard block
 block discarded – undo
160 160
                 ['action' => 'settings'],
161 161
                 EE_MSG_ADMIN_URL
162 162
             );
163
-            $error_msg        = sprintf(
163
+            $error_msg = sprintf(
164 164
                 esc_html__(
165 165
                     'There are no active messengers. So no notifications will go out for %1$sany%2$s events.  You will want to %3$sActivate a Messenger%4$s.',
166 166
                     'event_espresso'
167 167
                 ),
168 168
                 '<strong>',
169 169
                 '</strong>',
170
-                '<a href="' . esc_url_raw($msg_activate_url) . '">',
170
+                '<a href="'.esc_url_raw($msg_activate_url).'">',
171 171
                 '</a>'
172 172
             );
173
-            $error_content    = '<div class="error"><p>' . $error_msg . '</p></div>';
174
-            $internal_content = '<div id="messages-error"><p>' . $error_msg . '</p></div>';
173
+            $error_content    = '<div class="error"><p>'.$error_msg.'</p></div>';
174
+            $internal_content = '<div id="messages-error"><p>'.$error_msg.'</p></div>';
175 175
 
176 176
             echo wp_kses($error_content, AllowedTags::getAllowedTags());
177 177
             echo wp_kses($internal_content, AllowedTags::getAllowedTags());
@@ -192,8 +192,8 @@  discard block
 block discarded – undo
192 192
                 ['event' => $EVT_ID]
193 193
             );
194 194
 
195
-            if (! empty($tab_content)) {
196
-                $tabs[ $name ] = $tab_content;
195
+            if ( ! empty($tab_content)) {
196
+                $tabs[$name] = $tab_content;
197 197
             }
198 198
         }
199 199
 
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
         $notices = '
207 207
         <div id="espresso-ajax-loading" class="ajax-loader-grey">
208 208
             <span class="ee-spinner ee-spin"></span>
209
-            <span class="hidden">' . esc_html__('loading...', 'event_espresso') . '</span>
209
+            <span class="hidden">' . esc_html__('loading...', 'event_espresso').'</span>
210 210
         </div>
211 211
         <div class="ee-notices"></div>';
212 212
 
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
 
217 217
         do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__before_content');
218 218
         echo wp_kses(
219
-            $notices . '<div class="messages-tabs-content">' . $tabbed_content . '</div>',
219
+            $notices.'<div class="messages-tabs-content">'.$tabbed_content.'</div>',
220 220
             AllowedTags::getWithFormTags()
221 221
         );
222 222
         do_action('AHEE__espresso_events_Messages_Hooks_Extend__messages_metabox__after_content');
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
      */
237 237
     public function create_new_custom()
238 238
     {
239
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_edit_messages', 'create_new_custom_ajax')) {
239
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_edit_messages', 'create_new_custom_ajax')) {
240 240
             wp_die(esc_html__('You don\'t have privileges to do this action', 'event_espresso'));
241 241
         }
242 242
 
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 
247 247
         // let's clean up the request data a bit for downstream usage of name and description.
248 248
         $templateName = $this->request->getRequestParam('custom_template_args[MTP_name]', '');
249
-        if (! $templateName) {
249
+        if ( ! $templateName) {
250 250
             EE_Error::add_error(
251 251
                 esc_html__(
252 252
                     'Please provide a template name when creating a new message template.',
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
     public function edit_admin_footer()
305 305
     {
306 306
         EEH_Template::display_template(
307
-            EE_CORE_CAF_ADMIN_EXTEND . 'messages/templates/create_custom_template_form.template.php'
307
+            EE_CORE_CAF_ADMIN_EXTEND.'messages/templates/create_custom_template_form.template.php'
308 308
         );
309 309
     }
310 310
 
Please login to merge, or discard this patch.
public/template_tags.php 2 patches
Indentation   +1073 added lines, -1073 removed lines patch added patch discarded remove patch
@@ -22,13 +22,13 @@  discard block
 block discarded – undo
22 22
  */
23 23
 function is_espresso_event($event = null)
24 24
 {
25
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
26
-        // extract EE_Event object from passed param regardless of what it is (within reason of course)
27
-        $event = EEH_Event_View::get_event($event);
28
-        // do we have a valid event ?
29
-        return $event instanceof EE_Event;
30
-    }
31
-    return false;
25
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
26
+		// extract EE_Event object from passed param regardless of what it is (within reason of course)
27
+		$event = EEH_Event_View::get_event($event);
28
+		// do we have a valid event ?
29
+		return $event instanceof EE_Event;
30
+	}
31
+	return false;
32 32
 }
33 33
 
34 34
 /**
@@ -39,12 +39,12 @@  discard block
 block discarded – undo
39 39
  */
40 40
 function is_espresso_event_single()
41 41
 {
42
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
43
-        global $wp_query;
44
-        // return conditionals set by CPTs
45
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_single : false;
46
-    }
47
-    return false;
42
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
43
+		global $wp_query;
44
+		// return conditionals set by CPTs
45
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_single : false;
46
+	}
47
+	return false;
48 48
 }
49 49
 
50 50
 /**
@@ -55,11 +55,11 @@  discard block
 block discarded – undo
55 55
  */
56 56
 function is_espresso_event_archive()
57 57
 {
58
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
59
-        global $wp_query;
60
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_archive : false;
61
-    }
62
-    return false;
58
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
59
+		global $wp_query;
60
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_archive : false;
61
+	}
62
+	return false;
63 63
 }
64 64
 
65 65
 /**
@@ -70,11 +70,11 @@  discard block
 block discarded – undo
70 70
  */
71 71
 function is_espresso_event_taxonomy()
72 72
 {
73
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
74
-        global $wp_query;
75
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_taxonomy : false;
76
-    }
77
-    return false;
73
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
74
+		global $wp_query;
75
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_event_taxonomy : false;
76
+	}
77
+	return false;
78 78
 }
79 79
 
80 80
 /**
@@ -88,13 +88,13 @@  discard block
 block discarded – undo
88 88
  */
89 89
 function is_espresso_venue($venue = null)
90 90
 {
91
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
92
-        // extract EE_Venue object from passed param regardless of what it is (within reason of course)
93
-        $venue = EEH_Venue_View::get_venue($venue, false);
94
-        // do we have a valid event ?
95
-        return $venue instanceof EE_Venue;
96
-    }
97
-    return false;
91
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
92
+		// extract EE_Venue object from passed param regardless of what it is (within reason of course)
93
+		$venue = EEH_Venue_View::get_venue($venue, false);
94
+		// do we have a valid event ?
95
+		return $venue instanceof EE_Venue;
96
+	}
97
+	return false;
98 98
 }
99 99
 
100 100
 /**
@@ -105,11 +105,11 @@  discard block
 block discarded – undo
105 105
  */
106 106
 function is_espresso_venue_single()
107 107
 {
108
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
109
-        global $wp_query;
110
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_single : false;
111
-    }
112
-    return false;
108
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
109
+		global $wp_query;
110
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_single : false;
111
+	}
112
+	return false;
113 113
 }
114 114
 
115 115
 /**
@@ -120,11 +120,11 @@  discard block
 block discarded – undo
120 120
  */
121 121
 function is_espresso_venue_archive()
122 122
 {
123
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
124
-        global $wp_query;
125
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_archive : false;
126
-    }
127
-    return false;
123
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
124
+		global $wp_query;
125
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_archive : false;
126
+	}
127
+	return false;
128 128
 }
129 129
 
130 130
 /**
@@ -135,11 +135,11 @@  discard block
 block discarded – undo
135 135
  */
136 136
 function is_espresso_venue_taxonomy()
137 137
 {
138
-    if (can_use_espresso_conditionals(__FUNCTION__)) {
139
-        global $wp_query;
140
-        return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_taxonomy : false;
141
-    }
142
-    return false;
138
+	if (can_use_espresso_conditionals(__FUNCTION__)) {
139
+		global $wp_query;
140
+		return $wp_query instanceof WP_Query ? $wp_query->is_espresso_venue_taxonomy : false;
141
+	}
142
+	return false;
143 143
 }
144 144
 
145 145
 /**
@@ -151,62 +151,62 @@  discard block
 block discarded – undo
151 151
  */
152 152
 function can_use_espresso_conditionals($conditional_tag)
153 153
 {
154
-    if (! did_action('AHEE__EE_System__initialize')) {
155
-        EE_Error::doing_it_wrong(
156
-            __FUNCTION__,
157
-            sprintf(
158
-                esc_html__(
159
-                    'The "%s" conditional tag can not be used until after the "init" hook has run, but works best when used within a theme\'s template files.',
160
-                    'event_espresso'
161
-                ),
162
-                $conditional_tag
163
-            ),
164
-            '4.4.0'
165
-        );
166
-        return false;
167
-    }
168
-    return true;
154
+	if (! did_action('AHEE__EE_System__initialize')) {
155
+		EE_Error::doing_it_wrong(
156
+			__FUNCTION__,
157
+			sprintf(
158
+				esc_html__(
159
+					'The "%s" conditional tag can not be used until after the "init" hook has run, but works best when used within a theme\'s template files.',
160
+					'event_espresso'
161
+				),
162
+				$conditional_tag
163
+			),
164
+			'4.4.0'
165
+		);
166
+		return false;
167
+	}
168
+	return true;
169 169
 }
170 170
 
171 171
 
172 172
 /*************************** Event Queries ***************************/
173 173
 
174 174
 if (! function_exists('espresso_get_events')) {
175
-    /**
176
-     *    espresso_get_events
177
-     *
178
-     * @param array $params
179
-     * @return array
180
-     */
181
-    function espresso_get_events($params = [])
182
-    {
183
-        //set default params
184
-        $default_espresso_events_params = [
185
-            'limit'         => 10,
186
-            'show_expired'  => false,
187
-            'month'         => null,
188
-            'category_slug' => null,
189
-            'order_by'      => 'start_date',
190
-            'sort'          => 'ASC',
191
-        ];
192
-        // allow the defaults to be filtered
193
-        $default_espresso_events_params = apply_filters(
194
-            'espresso_get_events__default_espresso_events_params',
195
-            $default_espresso_events_params
196
-        );
197
-        // grab params and merge with defaults, then extract
198
-        $params = array_merge($default_espresso_events_params, $params);
199
-        // run the query
200
-        $events_query = new EventEspresso\core\domain\services\wp_queries\EventListQuery($params);
201
-        // assign results to a variable so we can return it
202
-        $events = $events_query->have_posts() ? $events_query->posts : [];
203
-        // but first reset the query and postdata
204
-        wp_reset_query();
205
-        wp_reset_postdata();
206
-        EED_Events_Archive::remove_all_events_archive_filters();
207
-        unset($events_query);
208
-        return $events;
209
-    }
175
+	/**
176
+	 *    espresso_get_events
177
+	 *
178
+	 * @param array $params
179
+	 * @return array
180
+	 */
181
+	function espresso_get_events($params = [])
182
+	{
183
+		//set default params
184
+		$default_espresso_events_params = [
185
+			'limit'         => 10,
186
+			'show_expired'  => false,
187
+			'month'         => null,
188
+			'category_slug' => null,
189
+			'order_by'      => 'start_date',
190
+			'sort'          => 'ASC',
191
+		];
192
+		// allow the defaults to be filtered
193
+		$default_espresso_events_params = apply_filters(
194
+			'espresso_get_events__default_espresso_events_params',
195
+			$default_espresso_events_params
196
+		);
197
+		// grab params and merge with defaults, then extract
198
+		$params = array_merge($default_espresso_events_params, $params);
199
+		// run the query
200
+		$events_query = new EventEspresso\core\domain\services\wp_queries\EventListQuery($params);
201
+		// assign results to a variable so we can return it
202
+		$events = $events_query->have_posts() ? $events_query->posts : [];
203
+		// but first reset the query and postdata
204
+		wp_reset_query();
205
+		wp_reset_postdata();
206
+		EED_Events_Archive::remove_all_events_archive_filters();
207
+		unset($events_query);
208
+		return $events;
209
+	}
210 210
 }
211 211
 
212 212
 
@@ -221,115 +221,115 @@  discard block
 block discarded – undo
221 221
  */
222 222
 function espresso_load_ticket_selector()
223 223
 {
224
-    EE_Registry::instance()->load_file(EE_MODULES . 'ticket_selector', 'EED_Ticket_Selector', 'module');
224
+	EE_Registry::instance()->load_file(EE_MODULES . 'ticket_selector', 'EED_Ticket_Selector', 'module');
225 225
 }
226 226
 
227 227
 if (! function_exists('espresso_ticket_selector')) {
228
-    /**
229
-     * espresso_ticket_selector
230
-     *
231
-     * @param null $event
232
-     * @throws EE_Error
233
-     * @throws ReflectionException
234
-     */
235
-    function espresso_ticket_selector($event = null)
236
-    {
237
-        if (! apply_filters('FHEE_disable_espresso_ticket_selector', false)) {
238
-            espresso_load_ticket_selector();
239
-            EED_Ticket_Selector::set_definitions();
240
-            echo EED_Ticket_Selector::display_ticket_selector($event); // already escaped
241
-        }
242
-    }
228
+	/**
229
+	 * espresso_ticket_selector
230
+	 *
231
+	 * @param null $event
232
+	 * @throws EE_Error
233
+	 * @throws ReflectionException
234
+	 */
235
+	function espresso_ticket_selector($event = null)
236
+	{
237
+		if (! apply_filters('FHEE_disable_espresso_ticket_selector', false)) {
238
+			espresso_load_ticket_selector();
239
+			EED_Ticket_Selector::set_definitions();
240
+			echo EED_Ticket_Selector::display_ticket_selector($event); // already escaped
241
+		}
242
+	}
243 243
 }
244 244
 
245 245
 
246 246
 if (! function_exists('espresso_view_details_btn')) {
247
-    /**
248
-     * espresso_view_details_btn
249
-     *
250
-     * @param null $event
251
-     * @throws EE_Error
252
-     * @throws ReflectionException
253
-     */
254
-    function espresso_view_details_btn($event = null)
255
-    {
256
-        if (! apply_filters('FHEE_disable_espresso_view_details_btn', false)) {
257
-            espresso_load_ticket_selector();
258
-            echo EED_Ticket_Selector::display_ticket_selector($event, true); // already escaped
259
-        }
260
-    }
247
+	/**
248
+	 * espresso_view_details_btn
249
+	 *
250
+	 * @param null $event
251
+	 * @throws EE_Error
252
+	 * @throws ReflectionException
253
+	 */
254
+	function espresso_view_details_btn($event = null)
255
+	{
256
+		if (! apply_filters('FHEE_disable_espresso_view_details_btn', false)) {
257
+			espresso_load_ticket_selector();
258
+			echo EED_Ticket_Selector::display_ticket_selector($event, true); // already escaped
259
+		}
260
+	}
261 261
 }
262 262
 
263 263
 
264 264
 /*************************** EEH_Event_View ***************************/
265 265
 
266 266
 if (! function_exists('espresso_load_event_list_assets')) {
267
-    /**
268
-     * espresso_load_event_list_assets
269
-     * ensures that event list styles and scripts are loaded
270
-     *
271
-     * @return void
272
-     */
273
-    function espresso_load_event_list_assets()
274
-    {
275
-        $event_list = EED_Events_Archive::instance();
276
-        add_action('AHEE__EE_System__initialize_last', [$event_list, 'load_event_list_assets'], 10);
277
-        add_filter('FHEE_enable_default_espresso_css', '__return_true');
278
-    }
267
+	/**
268
+	 * espresso_load_event_list_assets
269
+	 * ensures that event list styles and scripts are loaded
270
+	 *
271
+	 * @return void
272
+	 */
273
+	function espresso_load_event_list_assets()
274
+	{
275
+		$event_list = EED_Events_Archive::instance();
276
+		add_action('AHEE__EE_System__initialize_last', [$event_list, 'load_event_list_assets'], 10);
277
+		add_filter('FHEE_enable_default_espresso_css', '__return_true');
278
+	}
279 279
 }
280 280
 
281 281
 
282 282
 if (! function_exists('espresso_event_reg_button')) {
283
-    /**
284
-     * espresso_event_reg_button
285
-     * returns the "Register Now" button if event is active,
286
-     * an inactive button like status banner if the event is not active
287
-     * or a "Read More" button if so desired
288
-     *
289
-     * @param null $btn_text_if_active
290
-     * @param bool $btn_text_if_inactive
291
-     * @param bool $EVT_ID
292
-     * @return void
293
-     * @throws EE_Error
294
-     * @throws ReflectionException
295
-     */
296
-    function espresso_event_reg_button($btn_text_if_active = null, $btn_text_if_inactive = false, $EVT_ID = false)
297
-    {
298
-        $event = EEH_Event_View::get_event($EVT_ID);
299
-        if (! $event instanceof EE_Event) {
300
-            return;
301
-        }
302
-        $event_status = $event->get_active_status();
303
-        switch ($event_status) {
304
-            case EE_Datetime::sold_out :
305
-                $btn_text = __('Sold Out', 'event_espresso');
306
-                $class    = 'ee-pink';
307
-                break;
308
-            case EE_Datetime::expired :
309
-                $btn_text = __('Event is Over', 'event_espresso');
310
-                $class    = 'ee-grey';
311
-                break;
312
-            case EE_Datetime::inactive :
313
-                $btn_text = __('Event Not Active', 'event_espresso');
314
-                $class    = 'ee-grey';
315
-                break;
316
-            case EE_Datetime::cancelled :
317
-                $btn_text = __('Event was Cancelled', 'event_espresso');
318
-                $class    = 'ee-red';
319
-                break;
320
-            case EE_Datetime::upcoming :
321
-            case EE_Datetime::active :
322
-            default :
323
-                $btn_text = ! empty($btn_text_if_active)
324
-                    ? $btn_text_if_active
325
-                    : __('Register Now', 'event_espresso');
326
-                $class    = 'ee-green';
327
-        }
328
-        if ($event_status < 1 && ! empty($btn_text_if_inactive)) {
329
-            $btn_text = $btn_text_if_inactive;
330
-            $class    = 'ee-grey';
331
-        }
332
-        ?>
283
+	/**
284
+	 * espresso_event_reg_button
285
+	 * returns the "Register Now" button if event is active,
286
+	 * an inactive button like status banner if the event is not active
287
+	 * or a "Read More" button if so desired
288
+	 *
289
+	 * @param null $btn_text_if_active
290
+	 * @param bool $btn_text_if_inactive
291
+	 * @param bool $EVT_ID
292
+	 * @return void
293
+	 * @throws EE_Error
294
+	 * @throws ReflectionException
295
+	 */
296
+	function espresso_event_reg_button($btn_text_if_active = null, $btn_text_if_inactive = false, $EVT_ID = false)
297
+	{
298
+		$event = EEH_Event_View::get_event($EVT_ID);
299
+		if (! $event instanceof EE_Event) {
300
+			return;
301
+		}
302
+		$event_status = $event->get_active_status();
303
+		switch ($event_status) {
304
+			case EE_Datetime::sold_out :
305
+				$btn_text = __('Sold Out', 'event_espresso');
306
+				$class    = 'ee-pink';
307
+				break;
308
+			case EE_Datetime::expired :
309
+				$btn_text = __('Event is Over', 'event_espresso');
310
+				$class    = 'ee-grey';
311
+				break;
312
+			case EE_Datetime::inactive :
313
+				$btn_text = __('Event Not Active', 'event_espresso');
314
+				$class    = 'ee-grey';
315
+				break;
316
+			case EE_Datetime::cancelled :
317
+				$btn_text = __('Event was Cancelled', 'event_espresso');
318
+				$class    = 'ee-red';
319
+				break;
320
+			case EE_Datetime::upcoming :
321
+			case EE_Datetime::active :
322
+			default :
323
+				$btn_text = ! empty($btn_text_if_active)
324
+					? $btn_text_if_active
325
+					: __('Register Now', 'event_espresso');
326
+				$class    = 'ee-green';
327
+		}
328
+		if ($event_status < 1 && ! empty($btn_text_if_inactive)) {
329
+			$btn_text = $btn_text_if_inactive;
330
+			$class    = 'ee-grey';
331
+		}
332
+		?>
333 333
         <a class="ee-button ee-register-button <?php echo esc_attr($class); ?>"
334 334
             href="<?php espresso_event_link_url($EVT_ID); ?>"
335 335
             <?php echo AttributesSanitizer::clean(EED_Events_Archive::link_target(), AllowedTags::getAllowedTags(), 'a'); ?>
@@ -337,244 +337,244 @@  discard block
 block discarded – undo
337 337
             <?php echo esc_html($btn_text); ?>
338 338
         </a>
339 339
         <?php
340
-    }
340
+	}
341 341
 }
342 342
 
343 343
 
344 344
 if (! function_exists('espresso_display_ticket_selector')) {
345
-    /**
346
-     * espresso_display_ticket_selector
347
-     * whether or not to display the Ticket Selector for an event
348
-     *
349
-     * @param bool $EVT_ID
350
-     * @return boolean
351
-     * @throws EE_Error
352
-     * @throws ReflectionException
353
-     */
354
-    function espresso_display_ticket_selector($EVT_ID = false)
355
-    {
356
-        return EEH_Event_View::display_ticket_selector($EVT_ID);
357
-    }
345
+	/**
346
+	 * espresso_display_ticket_selector
347
+	 * whether or not to display the Ticket Selector for an event
348
+	 *
349
+	 * @param bool $EVT_ID
350
+	 * @return boolean
351
+	 * @throws EE_Error
352
+	 * @throws ReflectionException
353
+	 */
354
+	function espresso_display_ticket_selector($EVT_ID = false)
355
+	{
356
+		return EEH_Event_View::display_ticket_selector($EVT_ID);
357
+	}
358 358
 }
359 359
 
360 360
 
361 361
 if (! function_exists('espresso_event_status_banner')) {
362
-    /**
363
-     * espresso_event_status
364
-     * returns a banner showing the event status if it is sold out, expired, or inactive
365
-     *
366
-     * @param bool $EVT_ID
367
-     * @return string
368
-     * @throws EE_Error
369
-     * @throws ReflectionException
370
-     */
371
-    function espresso_event_status_banner($EVT_ID = false)
372
-    {
373
-        return EEH_Event_View::event_status($EVT_ID);
374
-    }
362
+	/**
363
+	 * espresso_event_status
364
+	 * returns a banner showing the event status if it is sold out, expired, or inactive
365
+	 *
366
+	 * @param bool $EVT_ID
367
+	 * @return string
368
+	 * @throws EE_Error
369
+	 * @throws ReflectionException
370
+	 */
371
+	function espresso_event_status_banner($EVT_ID = false)
372
+	{
373
+		return EEH_Event_View::event_status($EVT_ID);
374
+	}
375 375
 }
376 376
 
377 377
 
378 378
 if (! function_exists('espresso_event_status')) {
379
-    /**
380
-     * espresso_event_status
381
-     * returns the event status if it is sold out, expired, or inactive
382
-     *
383
-     * @param int  $EVT_ID
384
-     * @param bool $echo
385
-     * @return string
386
-     * @throws EE_Error
387
-     * @throws ReflectionException
388
-     */
389
-    function espresso_event_status($EVT_ID = 0, $echo = true)
390
-    {
391
-        return EEH_Event_View::event_active_status($EVT_ID, $echo);
392
-    }
379
+	/**
380
+	 * espresso_event_status
381
+	 * returns the event status if it is sold out, expired, or inactive
382
+	 *
383
+	 * @param int  $EVT_ID
384
+	 * @param bool $echo
385
+	 * @return string
386
+	 * @throws EE_Error
387
+	 * @throws ReflectionException
388
+	 */
389
+	function espresso_event_status($EVT_ID = 0, $echo = true)
390
+	{
391
+		return EEH_Event_View::event_active_status($EVT_ID, $echo);
392
+	}
393 393
 }
394 394
 
395 395
 
396 396
 if (! function_exists('espresso_event_categories')) {
397
-    /**
398
-     * espresso_event_categories
399
-     * returns the terms associated with an event
400
-     *
401
-     * @param int  $EVT_ID
402
-     * @param bool $hide_uncategorized
403
-     * @param bool $echo
404
-     * @return string
405
-     * @throws EE_Error
406
-     * @throws ReflectionException
407
-     */
408
-    function espresso_event_categories($EVT_ID = 0, $hide_uncategorized = true, $echo = true)
409
-    {
410
-        if ($echo) {
411
-            echo wp_kses(EEH_Event_View::event_categories($EVT_ID, $hide_uncategorized), AllowedTags::getWithFormTags());
412
-            return '';
413
-        }
414
-        return EEH_Event_View::event_categories($EVT_ID, $hide_uncategorized);
415
-    }
397
+	/**
398
+	 * espresso_event_categories
399
+	 * returns the terms associated with an event
400
+	 *
401
+	 * @param int  $EVT_ID
402
+	 * @param bool $hide_uncategorized
403
+	 * @param bool $echo
404
+	 * @return string
405
+	 * @throws EE_Error
406
+	 * @throws ReflectionException
407
+	 */
408
+	function espresso_event_categories($EVT_ID = 0, $hide_uncategorized = true, $echo = true)
409
+	{
410
+		if ($echo) {
411
+			echo wp_kses(EEH_Event_View::event_categories($EVT_ID, $hide_uncategorized), AllowedTags::getWithFormTags());
412
+			return '';
413
+		}
414
+		return EEH_Event_View::event_categories($EVT_ID, $hide_uncategorized);
415
+	}
416 416
 }
417 417
 
418 418
 
419 419
 if (! function_exists('espresso_event_tickets_available')) {
420
-    /**
421
-     * espresso_event_tickets_available
422
-     * returns the ticket types available for purchase for an event
423
-     *
424
-     * @param int  $EVT_ID
425
-     * @param bool $echo
426
-     * @param bool $format
427
-     * @return string
428
-     * @throws EE_Error
429
-     * @throws ReflectionException
430
-     */
431
-    function espresso_event_tickets_available($EVT_ID = 0, $echo = true, $format = true)
432
-    {
433
-        $tickets = EEH_Event_View::event_tickets_available($EVT_ID);
434
-        if (is_array($tickets) && ! empty($tickets)) {
435
-            // if formatting then $html will be a string, else it will be an array of ticket objects
436
-            $html =
437
-                $format ? '<ul id="ee-event-tickets-ul-' . esc_attr($EVT_ID) . '" class="ee-event-tickets-ul">' : [];
438
-            foreach ($tickets as $ticket) {
439
-                if ($ticket instanceof EE_Ticket) {
440
-                    if ($format) {
441
-                        $html .= '<li id="ee-event-tickets-li-'
442
-                                 . esc_attr($ticket->ID())
443
-                                 . '" class="ee-event-tickets-li">';
444
-                        $html .= esc_html($ticket->name()) . ' ';
445
-                        $html .= EEH_Template::format_currency(
446
-                            $ticket->get_ticket_total_with_taxes()
447
-                        ); // already escaped
448
-                        $html .= '</li>';
449
-                    } else {
450
-                        $html[] = $ticket;
451
-                    }
452
-                }
453
-            }
454
-            if ($format) {
455
-                $html .= '</ul>';
456
-            }
457
-            if ($echo && $format) {
458
-                echo wp_kses($html, AllowedTags::getAllowedTags());
459
-                return '';
460
-            }
461
-            return $html;
462
-        }
463
-        return '';
464
-    }
420
+	/**
421
+	 * espresso_event_tickets_available
422
+	 * returns the ticket types available for purchase for an event
423
+	 *
424
+	 * @param int  $EVT_ID
425
+	 * @param bool $echo
426
+	 * @param bool $format
427
+	 * @return string
428
+	 * @throws EE_Error
429
+	 * @throws ReflectionException
430
+	 */
431
+	function espresso_event_tickets_available($EVT_ID = 0, $echo = true, $format = true)
432
+	{
433
+		$tickets = EEH_Event_View::event_tickets_available($EVT_ID);
434
+		if (is_array($tickets) && ! empty($tickets)) {
435
+			// if formatting then $html will be a string, else it will be an array of ticket objects
436
+			$html =
437
+				$format ? '<ul id="ee-event-tickets-ul-' . esc_attr($EVT_ID) . '" class="ee-event-tickets-ul">' : [];
438
+			foreach ($tickets as $ticket) {
439
+				if ($ticket instanceof EE_Ticket) {
440
+					if ($format) {
441
+						$html .= '<li id="ee-event-tickets-li-'
442
+								 . esc_attr($ticket->ID())
443
+								 . '" class="ee-event-tickets-li">';
444
+						$html .= esc_html($ticket->name()) . ' ';
445
+						$html .= EEH_Template::format_currency(
446
+							$ticket->get_ticket_total_with_taxes()
447
+						); // already escaped
448
+						$html .= '</li>';
449
+					} else {
450
+						$html[] = $ticket;
451
+					}
452
+				}
453
+			}
454
+			if ($format) {
455
+				$html .= '</ul>';
456
+			}
457
+			if ($echo && $format) {
458
+				echo wp_kses($html, AllowedTags::getAllowedTags());
459
+				return '';
460
+			}
461
+			return $html;
462
+		}
463
+		return '';
464
+	}
465 465
 }
466 466
 
467 467
 if (! function_exists('espresso_event_date_obj')) {
468
-    /**
469
-     * espresso_event_date_obj
470
-     * returns the primary date object for an event
471
-     *
472
-     * @param bool $EVT_ID
473
-     * @return EE_Datetime|null
474
-     * @throws EE_Error
475
-     * @throws ReflectionException
476
-     */
477
-    function espresso_event_date_obj($EVT_ID = false)
478
-    {
479
-        return EEH_Event_View::get_primary_date_obj($EVT_ID);
480
-    }
468
+	/**
469
+	 * espresso_event_date_obj
470
+	 * returns the primary date object for an event
471
+	 *
472
+	 * @param bool $EVT_ID
473
+	 * @return EE_Datetime|null
474
+	 * @throws EE_Error
475
+	 * @throws ReflectionException
476
+	 */
477
+	function espresso_event_date_obj($EVT_ID = false)
478
+	{
479
+		return EEH_Event_View::get_primary_date_obj($EVT_ID);
480
+	}
481 481
 }
482 482
 
483 483
 
484 484
 if (! function_exists('espresso_event_date')) {
485
-    /**
486
-     * espresso_event_date
487
-     * returns the primary date for an event
488
-     *
489
-     * @param string $date_format
490
-     * @param string $time_format
491
-     * @param bool   $EVT_ID
492
-     * @param bool   $echo
493
-     * @return string
494
-     * @throws EE_Error
495
-     * @throws ReflectionException
496
-     */
497
-    function espresso_event_date($date_format = '', $time_format = '', $EVT_ID = false, $echo = true)
498
-    {
499
-        $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
500
-        $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
501
-        $date_format = apply_filters('FHEE__espresso_event_date__date_format', $date_format);
502
-        $time_format = apply_filters('FHEE__espresso_event_date__time_format', $time_format);
503
-        if ($echo) {
504
-            echo wp_kses(EEH_Event_View::the_event_date($date_format, $time_format, $EVT_ID), AllowedTags::getWithFormTags());
505
-            return '';
506
-        }
507
-        return EEH_Event_View::the_event_date($date_format, $time_format, $EVT_ID);
508
-
509
-    }
485
+	/**
486
+	 * espresso_event_date
487
+	 * returns the primary date for an event
488
+	 *
489
+	 * @param string $date_format
490
+	 * @param string $time_format
491
+	 * @param bool   $EVT_ID
492
+	 * @param bool   $echo
493
+	 * @return string
494
+	 * @throws EE_Error
495
+	 * @throws ReflectionException
496
+	 */
497
+	function espresso_event_date($date_format = '', $time_format = '', $EVT_ID = false, $echo = true)
498
+	{
499
+		$date_format = ! empty($date_format) ? $date_format : get_option('date_format');
500
+		$time_format = ! empty($time_format) ? $time_format : get_option('time_format');
501
+		$date_format = apply_filters('FHEE__espresso_event_date__date_format', $date_format);
502
+		$time_format = apply_filters('FHEE__espresso_event_date__time_format', $time_format);
503
+		if ($echo) {
504
+			echo wp_kses(EEH_Event_View::the_event_date($date_format, $time_format, $EVT_ID), AllowedTags::getWithFormTags());
505
+			return '';
506
+		}
507
+		return EEH_Event_View::the_event_date($date_format, $time_format, $EVT_ID);
508
+
509
+	}
510 510
 }
511 511
 
512 512
 
513 513
 if (! function_exists('espresso_list_of_event_dates')) {
514
-    /**
515
-     * espresso_list_of_event_dates
516
-     * returns a unordered list of dates for an event
517
-     *
518
-     * @param int    $EVT_ID
519
-     * @param string $date_format
520
-     * @param string $time_format
521
-     * @param bool   $echo
522
-     * @param null   $show_expired
523
-     * @param bool   $format
524
-     * @param bool   $add_breaks
525
-     * @param null   $limit
526
-     * @return string
527
-     * @throws EE_Error
528
-     * @throws ReflectionException
529
-     */
530
-    function espresso_list_of_event_dates(
531
-        $EVT_ID = 0,
532
-        $date_format = '',
533
-        $time_format = '',
534
-        $echo = true,
535
-        $show_expired = null,
536
-        $format = true,
537
-        $add_breaks = true,
538
-        $limit = null
539
-    ) {
540
-        $allowedtags = AllowedTags::getAllowedTags();
541
-
542
-        $DTT_ID = LoaderFactory::getShared(RequestInterface::class)->getRequestParam('datetime', 0, 'int');
543
-        $arguments = apply_filters(
544
-            'FHEE__espresso_list_of_event_dates__arguments',
545
-            [ $EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID ]
546
-        );
547
-        [$EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID] = $arguments;
548
-        $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
549
-        $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
550
-        $date_format = apply_filters('FHEE__espresso_list_of_event_dates__date_format', $date_format);
551
-        $time_format = apply_filters('FHEE__espresso_list_of_event_dates__time_format', $time_format);
552
-        $datetimes   = $DTT_ID
553
-            ? [EEH_Event_View::get_date_obj($DTT_ID)]
554
-            : EEH_Event_View::get_all_date_obj($EVT_ID, $show_expired, false, (int) $limit);
555
-        if (! $format) {
556
-            return apply_filters('FHEE__espresso_list_of_event_dates__datetimes', $datetimes);
557
-        }
558
-        $newline = $add_breaks ? '<br />' : '';
559
-        if (is_array($datetimes) && ! empty($datetimes)) {
560
-            global $post;
514
+	/**
515
+	 * espresso_list_of_event_dates
516
+	 * returns a unordered list of dates for an event
517
+	 *
518
+	 * @param int    $EVT_ID
519
+	 * @param string $date_format
520
+	 * @param string $time_format
521
+	 * @param bool   $echo
522
+	 * @param null   $show_expired
523
+	 * @param bool   $format
524
+	 * @param bool   $add_breaks
525
+	 * @param null   $limit
526
+	 * @return string
527
+	 * @throws EE_Error
528
+	 * @throws ReflectionException
529
+	 */
530
+	function espresso_list_of_event_dates(
531
+		$EVT_ID = 0,
532
+		$date_format = '',
533
+		$time_format = '',
534
+		$echo = true,
535
+		$show_expired = null,
536
+		$format = true,
537
+		$add_breaks = true,
538
+		$limit = null
539
+	) {
540
+		$allowedtags = AllowedTags::getAllowedTags();
541
+
542
+		$DTT_ID = LoaderFactory::getShared(RequestInterface::class)->getRequestParam('datetime', 0, 'int');
543
+		$arguments = apply_filters(
544
+			'FHEE__espresso_list_of_event_dates__arguments',
545
+			[ $EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID ]
546
+		);
547
+		[$EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID] = $arguments;
548
+		$date_format = ! empty($date_format) ? $date_format : get_option('date_format');
549
+		$time_format = ! empty($time_format) ? $time_format : get_option('time_format');
550
+		$date_format = apply_filters('FHEE__espresso_list_of_event_dates__date_format', $date_format);
551
+		$time_format = apply_filters('FHEE__espresso_list_of_event_dates__time_format', $time_format);
552
+		$datetimes   = $DTT_ID
553
+			? [EEH_Event_View::get_date_obj($DTT_ID)]
554
+			: EEH_Event_View::get_all_date_obj($EVT_ID, $show_expired, false, (int) $limit);
555
+		if (! $format) {
556
+			return apply_filters('FHEE__espresso_list_of_event_dates__datetimes', $datetimes);
557
+		}
558
+		$newline = $add_breaks ? '<br />' : '';
559
+		if (is_array($datetimes) && ! empty($datetimes)) {
560
+			global $post;
561 561
 			$cols = count($datetimes);
562 562
 			$cols = $cols >= 3 ? 'big' : 'small';
563 563
 			$ul_class = "ee-event-datetimes-ul ee-event-datetimes-ul--{$cols}";
564 564
 			$html = '<ul id="ee-event-datetimes-ul-' . esc_attr($post->ID) . '" class="'. $ul_class.'">';
565 565
 
566
-            foreach ($datetimes as $datetime) {
567
-                if ($datetime instanceof EE_Datetime) {
566
+			foreach ($datetimes as $datetime) {
567
+				if ($datetime instanceof EE_Datetime) {
568 568
 
569
-                    $datetime_name        = $datetime->name();
570
-                    $datetime_html        = ! empty($datetime_name)
571
-                        ? '
569
+					$datetime_name        = $datetime->name();
570
+					$datetime_html        = ! empty($datetime_name)
571
+						? '
572 572
                         <strong class="ee-event-datetimes-li-date-name">
573 573
                           ' . esc_html($datetime_name) . '
574 574
                        </strong>' . $newline
575
-                        : '';
575
+						: '';
576 576
 
577
-                    $datetime_html .= '
577
+					$datetime_html .= '
578 578
                         <span class="ee-event-datetimes-li-daterange">
579 579
 							<span class="dashicons dashicons-calendar"></span>&nbsp;'
580 580
 							. $datetime->date_range($date_format). '
@@ -586,501 +586,501 @@  discard block
 block discarded – undo
586 586
 						</span>
587 587
                         ';
588 588
 
589
-                    $venue = $datetime->venue();
590
-                    if ($venue instanceof EE_Venue) {
591
-                    	$venue_name      = esc_html($venue->name());
592
-                        $datetime_html .= '<br /><span class="ee-event-datetimes-li-venue">';
593
-                        $datetime_html .= '<span class="dashicons dashicons-admin-home"></span>&nbsp;';
594
-                        $datetime_html .= '<a href="'. esc_url_raw($venue->get_permalink()) .'" target="_blank">';
595
-                        $datetime_html .= $venue_name . '</a></span>';
596
-                    }
597
-
598
-                    $datetime_description = $datetime->description();
599
-                    $datetime_html .= ! empty($datetime_description)
600
-                        ? '
589
+					$venue = $datetime->venue();
590
+					if ($venue instanceof EE_Venue) {
591
+						$venue_name      = esc_html($venue->name());
592
+						$datetime_html .= '<br /><span class="ee-event-datetimes-li-venue">';
593
+						$datetime_html .= '<span class="dashicons dashicons-admin-home"></span>&nbsp;';
594
+						$datetime_html .= '<a href="'. esc_url_raw($venue->get_permalink()) .'" target="_blank">';
595
+						$datetime_html .= $venue_name . '</a></span>';
596
+					}
597
+
598
+					$datetime_description = $datetime->description();
599
+					$datetime_html .= ! empty($datetime_description)
600
+						? '
601 601
                         <span class="ee-event-datetimes-li-date-desc">
602 602
                             ' . wp_kses($datetime_description, $allowedtags) . '
603 603
                         </span>' . $newline
604
-                        : '';
604
+						: '';
605 605
 
606
-                    $datetime_html = apply_filters(
607
-                        'FHEE__espresso_list_of_event_dates__datetime_html',
608
-                        $datetime_html,
609
-                        $datetime,
610
-                        $arguments
611
-                    );
606
+					$datetime_html = apply_filters(
607
+						'FHEE__espresso_list_of_event_dates__datetime_html',
608
+						$datetime_html,
609
+						$datetime,
610
+						$arguments
611
+					);
612 612
 
613
-                    $DTD_ID        = esc_attr($datetime->ID());
614
-                    $active_status = esc_attr('ee-event-datetimes-li-' . $datetime->get_active_status());
613
+					$DTD_ID        = esc_attr($datetime->ID());
614
+					$active_status = esc_attr('ee-event-datetimes-li-' . $datetime->get_active_status());
615 615
 
616
-                    $html .= '
616
+					$html .= '
617 617
                     <li id="ee-event-datetimes-li-' . $DTD_ID . '" class="ee-event-datetimes-li ' . $active_status . '">
618 618
                         ' . $datetime_html . '
619 619
                     </li>';
620
-                }
621
-            }
622
-            $html .= '</ul>';
623
-            $html = apply_filters('FHEE__espresso_list_of_event_dates__html', $html, $arguments, $datetime);
624
-        } else {
625
-            $html =
626
-                '
620
+				}
621
+			}
622
+			$html .= '</ul>';
623
+			$html = apply_filters('FHEE__espresso_list_of_event_dates__html', $html, $arguments, $datetime);
624
+		} else {
625
+			$html =
626
+				'
627 627
             <p>
628 628
                 <span class="dashicons dashicons-marker pink-text"></span>
629 629
                 ' . esc_html__(
630
-                    'There are no upcoming dates for this event.',
631
-                    'event_espresso'
632
-                ) . '
630
+					'There are no upcoming dates for this event.',
631
+					'event_espresso'
632
+				) . '
633 633
             </p>
634 634
             <br/>';
635
-        }
636
-        if ($echo) {
637
-            echo wp_kses($html, AllowedTags::getWithFormTags());
638
-            return '';
639
-        }
640
-        return $html;
641
-    }
635
+		}
636
+		if ($echo) {
637
+			echo wp_kses($html, AllowedTags::getWithFormTags());
638
+			return '';
639
+		}
640
+		return $html;
641
+	}
642 642
 }
643 643
 
644 644
 
645 645
 if (! function_exists('espresso_event_end_date')) {
646
-    /**
647
-     * espresso_event_end_date
648
-     * returns the last date for an event
649
-     *
650
-     * @param string $date_format
651
-     * @param string $time_format
652
-     * @param bool   $EVT_ID
653
-     * @param bool   $echo
654
-     * @return string
655
-     * @throws EE_Error
656
-     * @throws ReflectionException
657
-     */
658
-    function espresso_event_end_date($date_format = '', $time_format = '', $EVT_ID = false, $echo = true)
659
-    {
660
-        $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
661
-        $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
662
-        $date_format = apply_filters('FHEE__espresso_event_end_date__date_format', $date_format);
663
-        $time_format = apply_filters('FHEE__espresso_event_end_date__time_format', $time_format);
664
-        if ($echo) {
665
-            echo wp_kses(EEH_Event_View::the_event_end_date($date_format, $time_format, $EVT_ID), AllowedTags::getWithFormTags());
666
-            return '';
667
-        }
668
-        return EEH_Event_View::the_event_end_date($date_format, $time_format, $EVT_ID);
669
-    }
646
+	/**
647
+	 * espresso_event_end_date
648
+	 * returns the last date for an event
649
+	 *
650
+	 * @param string $date_format
651
+	 * @param string $time_format
652
+	 * @param bool   $EVT_ID
653
+	 * @param bool   $echo
654
+	 * @return string
655
+	 * @throws EE_Error
656
+	 * @throws ReflectionException
657
+	 */
658
+	function espresso_event_end_date($date_format = '', $time_format = '', $EVT_ID = false, $echo = true)
659
+	{
660
+		$date_format = ! empty($date_format) ? $date_format : get_option('date_format');
661
+		$time_format = ! empty($time_format) ? $time_format : get_option('time_format');
662
+		$date_format = apply_filters('FHEE__espresso_event_end_date__date_format', $date_format);
663
+		$time_format = apply_filters('FHEE__espresso_event_end_date__time_format', $time_format);
664
+		if ($echo) {
665
+			echo wp_kses(EEH_Event_View::the_event_end_date($date_format, $time_format, $EVT_ID), AllowedTags::getWithFormTags());
666
+			return '';
667
+		}
668
+		return EEH_Event_View::the_event_end_date($date_format, $time_format, $EVT_ID);
669
+	}
670 670
 }
671 671
 
672 672
 if (! function_exists('espresso_event_date_range')) {
673
-    /**
674
-     * espresso_event_date_range
675
-     * returns the first and last chronologically ordered dates for an event (if different)
676
-     *
677
-     * @param string $date_format
678
-     * @param string $time_format
679
-     * @param string $single_date_format
680
-     * @param string $single_time_format
681
-     * @param bool   $EVT_ID
682
-     * @param bool   $echo
683
-     * @return string
684
-     * @throws EE_Error
685
-     * @throws ReflectionException
686
-     */
687
-    function espresso_event_date_range(
688
-        $date_format = '',
689
-        $time_format = '',
690
-        $single_date_format = '',
691
-        $single_time_format = '',
692
-        $EVT_ID = false,
693
-        $echo = true
694
-    ) {
695
-        // set and filter date and time formats when a range is returned
696
-        $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
697
-        $date_format = apply_filters('FHEE__espresso_event_date_range__date_format', $date_format);
698
-        // get the start and end date with NO time portion
699
-        $the_event_date     = EEH_Event_View::the_earliest_event_date($date_format, '', $EVT_ID);
700
-        $the_event_end_date = EEH_Event_View::the_latest_event_date($date_format, '', $EVT_ID);
701
-        // now we can determine if date range spans more than one day
702
-        if ($the_event_date != $the_event_end_date) {
703
-            $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
704
-            $time_format = apply_filters('FHEE__espresso_event_date_range__time_format', $time_format);
705
-            $html        = sprintf(
706
-            /* translators: 1: first event date, 2: last event date */
707
-                esc_html__('%1$s - %2$s', 'event_espresso'),
708
-                EEH_Event_View::the_earliest_event_date($date_format, $time_format, $EVT_ID),
709
-                EEH_Event_View::the_latest_event_date($date_format, $time_format, $EVT_ID)
710
-            );
711
-        } else {
712
-            // set and filter date and time formats when only a single datetime is returned
713
-            $single_date_format = ! empty($single_date_format) ? $single_date_format : get_option('date_format');
714
-            $single_time_format = ! empty($single_time_format) ? $single_time_format : get_option('time_format');
715
-            $single_date_format =
716
-                apply_filters('FHEE__espresso_event_date_range__single_date_format', $single_date_format);
717
-            $single_time_format =
718
-                apply_filters('FHEE__espresso_event_date_range__single_time_format', $single_time_format);
719
-            $html               =
720
-                EEH_Event_View::the_earliest_event_date($single_date_format, $single_time_format, $EVT_ID);
721
-        }
722
-        if ($echo) {
723
-            echo wp_kses($html, AllowedTags::getAllowedTags());
724
-            return '';
725
-        }
726
-        return $html;
727
-    }
673
+	/**
674
+	 * espresso_event_date_range
675
+	 * returns the first and last chronologically ordered dates for an event (if different)
676
+	 *
677
+	 * @param string $date_format
678
+	 * @param string $time_format
679
+	 * @param string $single_date_format
680
+	 * @param string $single_time_format
681
+	 * @param bool   $EVT_ID
682
+	 * @param bool   $echo
683
+	 * @return string
684
+	 * @throws EE_Error
685
+	 * @throws ReflectionException
686
+	 */
687
+	function espresso_event_date_range(
688
+		$date_format = '',
689
+		$time_format = '',
690
+		$single_date_format = '',
691
+		$single_time_format = '',
692
+		$EVT_ID = false,
693
+		$echo = true
694
+	) {
695
+		// set and filter date and time formats when a range is returned
696
+		$date_format = ! empty($date_format) ? $date_format : get_option('date_format');
697
+		$date_format = apply_filters('FHEE__espresso_event_date_range__date_format', $date_format);
698
+		// get the start and end date with NO time portion
699
+		$the_event_date     = EEH_Event_View::the_earliest_event_date($date_format, '', $EVT_ID);
700
+		$the_event_end_date = EEH_Event_View::the_latest_event_date($date_format, '', $EVT_ID);
701
+		// now we can determine if date range spans more than one day
702
+		if ($the_event_date != $the_event_end_date) {
703
+			$time_format = ! empty($time_format) ? $time_format : get_option('time_format');
704
+			$time_format = apply_filters('FHEE__espresso_event_date_range__time_format', $time_format);
705
+			$html        = sprintf(
706
+			/* translators: 1: first event date, 2: last event date */
707
+				esc_html__('%1$s - %2$s', 'event_espresso'),
708
+				EEH_Event_View::the_earliest_event_date($date_format, $time_format, $EVT_ID),
709
+				EEH_Event_View::the_latest_event_date($date_format, $time_format, $EVT_ID)
710
+			);
711
+		} else {
712
+			// set and filter date and time formats when only a single datetime is returned
713
+			$single_date_format = ! empty($single_date_format) ? $single_date_format : get_option('date_format');
714
+			$single_time_format = ! empty($single_time_format) ? $single_time_format : get_option('time_format');
715
+			$single_date_format =
716
+				apply_filters('FHEE__espresso_event_date_range__single_date_format', $single_date_format);
717
+			$single_time_format =
718
+				apply_filters('FHEE__espresso_event_date_range__single_time_format', $single_time_format);
719
+			$html               =
720
+				EEH_Event_View::the_earliest_event_date($single_date_format, $single_time_format, $EVT_ID);
721
+		}
722
+		if ($echo) {
723
+			echo wp_kses($html, AllowedTags::getAllowedTags());
724
+			return '';
725
+		}
726
+		return $html;
727
+	}
728 728
 }
729 729
 
730 730
 if (! function_exists('espresso_next_upcoming_datetime_obj')) {
731
-    /**
732
-     * espresso_next_upcoming_datetime_obj
733
-     * returns the next upcoming datetime object for an event
734
-     *
735
-     * @param int $EVT_ID
736
-     * @return EE_Datetime|null
737
-     * @throws EE_Error
738
-     */
739
-    function espresso_next_upcoming_datetime_obj($EVT_ID = 0)
740
-    {
741
-        return EEH_Event_View::get_next_upcoming_date_obj($EVT_ID);
742
-    }
731
+	/**
732
+	 * espresso_next_upcoming_datetime_obj
733
+	 * returns the next upcoming datetime object for an event
734
+	 *
735
+	 * @param int $EVT_ID
736
+	 * @return EE_Datetime|null
737
+	 * @throws EE_Error
738
+	 */
739
+	function espresso_next_upcoming_datetime_obj($EVT_ID = 0)
740
+	{
741
+		return EEH_Event_View::get_next_upcoming_date_obj($EVT_ID);
742
+	}
743 743
 }
744 744
 
745 745
 if (! function_exists('espresso_next_upcoming_datetime')) {
746
-    /**
747
-     * espresso_next_upcoming_datetime
748
-     * returns the start date and time for the next upcoming event.
749
-     *
750
-     * @param string $date_format
751
-     * @param string $time_format
752
-     * @param int    $EVT_ID
753
-     * @param bool   $echo
754
-     * @return string
755
-     * @throws EE_Error
756
-     * @throws ReflectionException
757
-     */
758
-    function espresso_next_upcoming_datetime($date_format = '', $time_format = '', $EVT_ID = 0, $echo = true)
759
-    {
760
-
761
-        $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
762
-        $date_format = apply_filters('FHEE__espresso_next_upcoming_datetime__date_format', $date_format);
763
-
764
-        $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
765
-        $time_format = apply_filters('FHEE__espresso_next_upcoming_datetime__time_format', $time_format);
766
-
767
-        $datetime_format = trim($date_format . ' ' . $time_format);
768
-
769
-        $datetime = espresso_next_upcoming_datetime_obj($EVT_ID);
770
-
771
-        if (! $datetime instanceof EE_Datetime) {
772
-            return '';
773
-        }
774
-        if ($echo) {
775
-            echo esc_html($datetime->get_i18n_datetime('DTT_EVT_start', $datetime_format));
776
-            return '';
777
-        }
778
-        return $datetime->get_i18n_datetime('DTT_EVT_start', $datetime_format);
779
-    }
746
+	/**
747
+	 * espresso_next_upcoming_datetime
748
+	 * returns the start date and time for the next upcoming event.
749
+	 *
750
+	 * @param string $date_format
751
+	 * @param string $time_format
752
+	 * @param int    $EVT_ID
753
+	 * @param bool   $echo
754
+	 * @return string
755
+	 * @throws EE_Error
756
+	 * @throws ReflectionException
757
+	 */
758
+	function espresso_next_upcoming_datetime($date_format = '', $time_format = '', $EVT_ID = 0, $echo = true)
759
+	{
760
+
761
+		$date_format = ! empty($date_format) ? $date_format : get_option('date_format');
762
+		$date_format = apply_filters('FHEE__espresso_next_upcoming_datetime__date_format', $date_format);
763
+
764
+		$time_format = ! empty($time_format) ? $time_format : get_option('time_format');
765
+		$time_format = apply_filters('FHEE__espresso_next_upcoming_datetime__time_format', $time_format);
766
+
767
+		$datetime_format = trim($date_format . ' ' . $time_format);
768
+
769
+		$datetime = espresso_next_upcoming_datetime_obj($EVT_ID);
770
+
771
+		if (! $datetime instanceof EE_Datetime) {
772
+			return '';
773
+		}
774
+		if ($echo) {
775
+			echo esc_html($datetime->get_i18n_datetime('DTT_EVT_start', $datetime_format));
776
+			return '';
777
+		}
778
+		return $datetime->get_i18n_datetime('DTT_EVT_start', $datetime_format);
779
+	}
780 780
 }
781 781
 
782 782
 if (! function_exists('espresso_event_date_as_calendar_page')) {
783
-    /**
784
-     * espresso_event_date_as_calendar_page
785
-     * returns the primary date for an event, stylized to appear as the page of a calendar
786
-     *
787
-     * @param bool $EVT_ID
788
-     * @return void
789
-     * @throws EE_Error
790
-     * @throws ReflectionException
791
-     */
792
-    function espresso_event_date_as_calendar_page($EVT_ID = false)
793
-    {
794
-        EEH_Event_View::event_date_as_calendar_page($EVT_ID);
795
-    }
783
+	/**
784
+	 * espresso_event_date_as_calendar_page
785
+	 * returns the primary date for an event, stylized to appear as the page of a calendar
786
+	 *
787
+	 * @param bool $EVT_ID
788
+	 * @return void
789
+	 * @throws EE_Error
790
+	 * @throws ReflectionException
791
+	 */
792
+	function espresso_event_date_as_calendar_page($EVT_ID = false)
793
+	{
794
+		EEH_Event_View::event_date_as_calendar_page($EVT_ID);
795
+	}
796 796
 }
797 797
 
798 798
 
799 799
 if (! function_exists('espresso_event_link_url')) {
800
-    /**
801
-     * espresso_event_link_url
802
-     *
803
-     * @param int  $EVT_ID
804
-     * @param bool $echo
805
-     * @return string
806
-     * @throws EE_Error
807
-     * @throws ReflectionException
808
-     */
809
-    function espresso_event_link_url($EVT_ID = 0, $echo = true)
810
-    {
811
-        if ($echo) {
812
-            echo wp_kses(EEH_Event_View::event_link_url($EVT_ID), AllowedTags::getWithFormTags());
813
-            return '';
814
-        }
815
-        return EEH_Event_View::event_link_url($EVT_ID);
816
-    }
800
+	/**
801
+	 * espresso_event_link_url
802
+	 *
803
+	 * @param int  $EVT_ID
804
+	 * @param bool $echo
805
+	 * @return string
806
+	 * @throws EE_Error
807
+	 * @throws ReflectionException
808
+	 */
809
+	function espresso_event_link_url($EVT_ID = 0, $echo = true)
810
+	{
811
+		if ($echo) {
812
+			echo wp_kses(EEH_Event_View::event_link_url($EVT_ID), AllowedTags::getWithFormTags());
813
+			return '';
814
+		}
815
+		return EEH_Event_View::event_link_url($EVT_ID);
816
+	}
817 817
 }
818 818
 
819 819
 
820 820
 if (! function_exists('espresso_event_has_content_or_excerpt')) {
821
-    /**
822
-     *    espresso_event_has_content_or_excerpt
823
-     *
824
-     * @access    public
825
-     * @param bool $EVT_ID
826
-     * @return    boolean
827
-     * @throws EE_Error
828
-     * @throws ReflectionException
829
-     */
830
-    function espresso_event_has_content_or_excerpt($EVT_ID = false)
831
-    {
832
-        return EEH_Event_View::event_has_content_or_excerpt($EVT_ID);
833
-    }
821
+	/**
822
+	 *    espresso_event_has_content_or_excerpt
823
+	 *
824
+	 * @access    public
825
+	 * @param bool $EVT_ID
826
+	 * @return    boolean
827
+	 * @throws EE_Error
828
+	 * @throws ReflectionException
829
+	 */
830
+	function espresso_event_has_content_or_excerpt($EVT_ID = false)
831
+	{
832
+		return EEH_Event_View::event_has_content_or_excerpt($EVT_ID);
833
+	}
834 834
 }
835 835
 
836 836
 
837 837
 if (! function_exists('espresso_event_content_or_excerpt')) {
838
-    /**
839
-     * espresso_event_content_or_excerpt
840
-     *
841
-     * @param int  $num_words
842
-     * @param null $more
843
-     * @param bool $echo
844
-     * @return string
845
-     */
846
-    function espresso_event_content_or_excerpt($num_words = 55, $more = null, $echo = true)
847
-    {
848
-        if ($echo) {
849
-            echo wp_kses(EEH_Event_View::event_content_or_excerpt($num_words, $more), AllowedTags::getWithFormTags());
850
-            return '';
851
-        }
852
-        return EEH_Event_View::event_content_or_excerpt($num_words, $more);
853
-    }
838
+	/**
839
+	 * espresso_event_content_or_excerpt
840
+	 *
841
+	 * @param int  $num_words
842
+	 * @param null $more
843
+	 * @param bool $echo
844
+	 * @return string
845
+	 */
846
+	function espresso_event_content_or_excerpt($num_words = 55, $more = null, $echo = true)
847
+	{
848
+		if ($echo) {
849
+			echo wp_kses(EEH_Event_View::event_content_or_excerpt($num_words, $more), AllowedTags::getWithFormTags());
850
+			return '';
851
+		}
852
+		return EEH_Event_View::event_content_or_excerpt($num_words, $more);
853
+	}
854 854
 }
855 855
 
856 856
 
857 857
 if (! function_exists('espresso_event_phone')) {
858
-    /**
859
-     * espresso_event_phone
860
-     *
861
-     * @param int  $EVT_ID
862
-     * @param bool $echo
863
-     * @return string
864
-     * @throws EE_Error
865
-     * @throws ReflectionException
866
-     */
867
-    function espresso_event_phone($EVT_ID = 0, $echo = true)
868
-    {
869
-        if ($echo) {
870
-            echo wp_kses(EEH_Event_View::event_phone($EVT_ID), AllowedTags::getWithFormTags());
871
-            return '';
872
-        }
873
-        return EEH_Event_View::event_phone($EVT_ID);
874
-    }
858
+	/**
859
+	 * espresso_event_phone
860
+	 *
861
+	 * @param int  $EVT_ID
862
+	 * @param bool $echo
863
+	 * @return string
864
+	 * @throws EE_Error
865
+	 * @throws ReflectionException
866
+	 */
867
+	function espresso_event_phone($EVT_ID = 0, $echo = true)
868
+	{
869
+		if ($echo) {
870
+			echo wp_kses(EEH_Event_View::event_phone($EVT_ID), AllowedTags::getWithFormTags());
871
+			return '';
872
+		}
873
+		return EEH_Event_View::event_phone($EVT_ID);
874
+	}
875 875
 }
876 876
 
877 877
 
878 878
 if (! function_exists('espresso_edit_event_link')) {
879
-    /**
880
-     * espresso_edit_event_link
881
-     * returns a link to edit an event
882
-     *
883
-     * @param int  $EVT_ID
884
-     * @param bool $echo
885
-     * @return string
886
-     * @throws EE_Error
887
-     * @throws ReflectionException
888
-     */
889
-    function espresso_edit_event_link($EVT_ID = 0, $echo = true)
890
-    {
891
-        if ($echo) {
892
-            echo wp_kses(EEH_Event_View::edit_event_link($EVT_ID), AllowedTags::getWithFormTags());
893
-            return '';
894
-        }
895
-        return EEH_Event_View::edit_event_link($EVT_ID);
896
-    }
879
+	/**
880
+	 * espresso_edit_event_link
881
+	 * returns a link to edit an event
882
+	 *
883
+	 * @param int  $EVT_ID
884
+	 * @param bool $echo
885
+	 * @return string
886
+	 * @throws EE_Error
887
+	 * @throws ReflectionException
888
+	 */
889
+	function espresso_edit_event_link($EVT_ID = 0, $echo = true)
890
+	{
891
+		if ($echo) {
892
+			echo wp_kses(EEH_Event_View::edit_event_link($EVT_ID), AllowedTags::getWithFormTags());
893
+			return '';
894
+		}
895
+		return EEH_Event_View::edit_event_link($EVT_ID);
896
+	}
897 897
 }
898 898
 
899 899
 
900 900
 if (! function_exists('espresso_organization_name')) {
901
-    /**
902
-     * espresso_organization_name
903
-     *
904
-     * @param bool $echo
905
-     * @return string
906
-     * @throws EE_Error
907
-     */
908
-    function espresso_organization_name($echo = true)
909
-    {
910
-        if ($echo) {
911
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('name'));
912
-            return '';
913
-        }
914
-        return EE_Registry::instance()->CFG->organization->get_pretty('name');
915
-    }
901
+	/**
902
+	 * espresso_organization_name
903
+	 *
904
+	 * @param bool $echo
905
+	 * @return string
906
+	 * @throws EE_Error
907
+	 */
908
+	function espresso_organization_name($echo = true)
909
+	{
910
+		if ($echo) {
911
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('name'));
912
+			return '';
913
+		}
914
+		return EE_Registry::instance()->CFG->organization->get_pretty('name');
915
+	}
916 916
 }
917 917
 
918 918
 if (! function_exists('espresso_organization_address')) {
919
-    /**
920
-     * espresso_organization_address
921
-     *
922
-     * @param string $type
923
-     * @return string
924
-     */
925
-    function espresso_organization_address($type = 'inline')
926
-    {
927
-        if (EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config) {
928
-            $address = new EventEspresso\core\domain\entities\GenericAddress(
929
-                EE_Registry::instance()->CFG->organization->address_1,
930
-                EE_Registry::instance()->CFG->organization->address_2,
931
-                EE_Registry::instance()->CFG->organization->city,
932
-                EE_Registry::instance()->CFG->organization->STA_ID,
933
-                EE_Registry::instance()->CFG->organization->zip,
934
-                EE_Registry::instance()->CFG->organization->CNT_ISO
935
-            );
936
-            return EEH_Address::format($address, $type);
937
-        }
938
-        return '';
939
-    }
919
+	/**
920
+	 * espresso_organization_address
921
+	 *
922
+	 * @param string $type
923
+	 * @return string
924
+	 */
925
+	function espresso_organization_address($type = 'inline')
926
+	{
927
+		if (EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config) {
928
+			$address = new EventEspresso\core\domain\entities\GenericAddress(
929
+				EE_Registry::instance()->CFG->organization->address_1,
930
+				EE_Registry::instance()->CFG->organization->address_2,
931
+				EE_Registry::instance()->CFG->organization->city,
932
+				EE_Registry::instance()->CFG->organization->STA_ID,
933
+				EE_Registry::instance()->CFG->organization->zip,
934
+				EE_Registry::instance()->CFG->organization->CNT_ISO
935
+			);
936
+			return EEH_Address::format($address, $type);
937
+		}
938
+		return '';
939
+	}
940 940
 }
941 941
 
942 942
 if (! function_exists('espresso_organization_email')) {
943
-    /**
944
-     * espresso_organization_email
945
-     *
946
-     * @param bool $echo
947
-     * @return string
948
-     * @throws EE_Error
949
-     */
950
-    function espresso_organization_email($echo = true)
951
-    {
952
-        if ($echo) {
953
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('email'));
954
-            return '';
955
-        }
956
-        return EE_Registry::instance()->CFG->organization->get_pretty('email');
957
-    }
943
+	/**
944
+	 * espresso_organization_email
945
+	 *
946
+	 * @param bool $echo
947
+	 * @return string
948
+	 * @throws EE_Error
949
+	 */
950
+	function espresso_organization_email($echo = true)
951
+	{
952
+		if ($echo) {
953
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('email'));
954
+			return '';
955
+		}
956
+		return EE_Registry::instance()->CFG->organization->get_pretty('email');
957
+	}
958 958
 }
959 959
 
960 960
 if (! function_exists('espresso_organization_logo_url')) {
961
-    /**
962
-     * espresso_organization_logo_url
963
-     *
964
-     * @param bool $echo
965
-     * @return string
966
-     * @throws EE_Error
967
-     */
968
-    function espresso_organization_logo_url($echo = true)
969
-    {
970
-        if ($echo) {
971
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('logo_url'));
972
-            return '';
973
-        }
974
-        return EE_Registry::instance()->CFG->organization->get_pretty('logo_url');
975
-    }
961
+	/**
962
+	 * espresso_organization_logo_url
963
+	 *
964
+	 * @param bool $echo
965
+	 * @return string
966
+	 * @throws EE_Error
967
+	 */
968
+	function espresso_organization_logo_url($echo = true)
969
+	{
970
+		if ($echo) {
971
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('logo_url'));
972
+			return '';
973
+		}
974
+		return EE_Registry::instance()->CFG->organization->get_pretty('logo_url');
975
+	}
976 976
 }
977 977
 
978 978
 if (! function_exists('espresso_organization_facebook')) {
979
-    /**
980
-     * espresso_organization_facebook
981
-     *
982
-     * @param bool $echo
983
-     * @return string
984
-     * @throws EE_Error
985
-     */
986
-    function espresso_organization_facebook($echo = true)
987
-    {
988
-        if ($echo) {
989
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('facebook'));
990
-            return '';
991
-        }
992
-        return EE_Registry::instance()->CFG->organization->get_pretty('facebook');
993
-    }
979
+	/**
980
+	 * espresso_organization_facebook
981
+	 *
982
+	 * @param bool $echo
983
+	 * @return string
984
+	 * @throws EE_Error
985
+	 */
986
+	function espresso_organization_facebook($echo = true)
987
+	{
988
+		if ($echo) {
989
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('facebook'));
990
+			return '';
991
+		}
992
+		return EE_Registry::instance()->CFG->organization->get_pretty('facebook');
993
+	}
994 994
 }
995 995
 
996 996
 if (! function_exists('espresso_organization_twitter')) {
997
-    /**
998
-     * espresso_organization_twitter
999
-     *
1000
-     * @param bool $echo
1001
-     * @return string
1002
-     * @throws EE_Error
1003
-     */
1004
-    function espresso_organization_twitter($echo = true)
1005
-    {
1006
-        if ($echo) {
1007
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('twitter'));
1008
-            return '';
1009
-        }
1010
-        return EE_Registry::instance()->CFG->organization->get_pretty('twitter');
1011
-    }
997
+	/**
998
+	 * espresso_organization_twitter
999
+	 *
1000
+	 * @param bool $echo
1001
+	 * @return string
1002
+	 * @throws EE_Error
1003
+	 */
1004
+	function espresso_organization_twitter($echo = true)
1005
+	{
1006
+		if ($echo) {
1007
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('twitter'));
1008
+			return '';
1009
+		}
1010
+		return EE_Registry::instance()->CFG->organization->get_pretty('twitter');
1011
+	}
1012 1012
 }
1013 1013
 
1014 1014
 if (! function_exists('espresso_organization_linkedin')) {
1015
-    /**
1016
-     * espresso_organization_linkedin
1017
-     *
1018
-     * @param bool $echo
1019
-     * @return string
1020
-     * @throws EE_Error
1021
-     */
1022
-    function espresso_organization_linkedin($echo = true)
1023
-    {
1024
-        if ($echo) {
1025
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('linkedin'));
1026
-            return '';
1027
-        }
1028
-        return EE_Registry::instance()->CFG->organization->get_pretty('linkedin');
1029
-    }
1015
+	/**
1016
+	 * espresso_organization_linkedin
1017
+	 *
1018
+	 * @param bool $echo
1019
+	 * @return string
1020
+	 * @throws EE_Error
1021
+	 */
1022
+	function espresso_organization_linkedin($echo = true)
1023
+	{
1024
+		if ($echo) {
1025
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('linkedin'));
1026
+			return '';
1027
+		}
1028
+		return EE_Registry::instance()->CFG->organization->get_pretty('linkedin');
1029
+	}
1030 1030
 }
1031 1031
 
1032 1032
 if (! function_exists('espresso_organization_pinterest')) {
1033
-    /**
1034
-     * espresso_organization_pinterest
1035
-     *
1036
-     * @param bool $echo
1037
-     * @return string
1038
-     * @throws EE_Error
1039
-     */
1040
-    function espresso_organization_pinterest($echo = true)
1041
-    {
1042
-        if ($echo) {
1043
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('pinterest'));
1044
-            return '';
1045
-        }
1046
-        return EE_Registry::instance()->CFG->organization->get_pretty('pinterest');
1047
-    }
1033
+	/**
1034
+	 * espresso_organization_pinterest
1035
+	 *
1036
+	 * @param bool $echo
1037
+	 * @return string
1038
+	 * @throws EE_Error
1039
+	 */
1040
+	function espresso_organization_pinterest($echo = true)
1041
+	{
1042
+		if ($echo) {
1043
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('pinterest'));
1044
+			return '';
1045
+		}
1046
+		return EE_Registry::instance()->CFG->organization->get_pretty('pinterest');
1047
+	}
1048 1048
 }
1049 1049
 
1050 1050
 if (! function_exists('espresso_organization_google')) {
1051
-    /**
1052
-     * espresso_organization_google
1053
-     *
1054
-     * @param bool $echo
1055
-     * @return string
1056
-     * @throws EE_Error
1057
-     */
1058
-    function espresso_organization_google($echo = true)
1059
-    {
1060
-        if ($echo) {
1061
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('google'));
1062
-            return '';
1063
-        }
1064
-        return EE_Registry::instance()->CFG->organization->get_pretty('google');
1065
-    }
1051
+	/**
1052
+	 * espresso_organization_google
1053
+	 *
1054
+	 * @param bool $echo
1055
+	 * @return string
1056
+	 * @throws EE_Error
1057
+	 */
1058
+	function espresso_organization_google($echo = true)
1059
+	{
1060
+		if ($echo) {
1061
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('google'));
1062
+			return '';
1063
+		}
1064
+		return EE_Registry::instance()->CFG->organization->get_pretty('google');
1065
+	}
1066 1066
 }
1067 1067
 
1068 1068
 if (! function_exists('espresso_organization_instagram')) {
1069
-    /**
1070
-     * espresso_organization_instagram
1071
-     *
1072
-     * @param bool $echo
1073
-     * @return string
1074
-     * @throws EE_Error
1075
-     */
1076
-    function espresso_organization_instagram($echo = true)
1077
-    {
1078
-        if ($echo) {
1079
-            echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('instagram'));
1080
-            return '';
1081
-        }
1082
-        return EE_Registry::instance()->CFG->organization->get_pretty('instagram');
1083
-    }
1069
+	/**
1070
+	 * espresso_organization_instagram
1071
+	 *
1072
+	 * @param bool $echo
1073
+	 * @return string
1074
+	 * @throws EE_Error
1075
+	 */
1076
+	function espresso_organization_instagram($echo = true)
1077
+	{
1078
+		if ($echo) {
1079
+			echo esc_html(EE_Registry::instance()->CFG->organization->get_pretty('instagram'));
1080
+			return '';
1081
+		}
1082
+		return EE_Registry::instance()->CFG->organization->get_pretty('instagram');
1083
+	}
1084 1084
 }
1085 1085
 
1086 1086
 
@@ -1088,345 +1088,345 @@  discard block
 block discarded – undo
1088 1088
 
1089 1089
 
1090 1090
 if (! function_exists('espresso_event_venues')) {
1091
-    /**
1092
-     * espresso_event_venues
1093
-     *
1094
-     * @return array  all venues related to an event
1095
-     * @throws EE_Error
1096
-     * @throws ReflectionException
1097
-     */
1098
-    function espresso_event_venues()
1099
-    {
1100
-        return EEH_Venue_View::get_event_venues();
1101
-    }
1091
+	/**
1092
+	 * espresso_event_venues
1093
+	 *
1094
+	 * @return array  all venues related to an event
1095
+	 * @throws EE_Error
1096
+	 * @throws ReflectionException
1097
+	 */
1098
+	function espresso_event_venues()
1099
+	{
1100
+		return EEH_Venue_View::get_event_venues();
1101
+	}
1102 1102
 }
1103 1103
 
1104 1104
 
1105 1105
 if (! function_exists('espresso_venue_id')) {
1106
-    /**
1107
-     *    espresso_venue_name
1108
-     *
1109
-     * @access    public
1110
-     * @param int $EVT_ID
1111
-     * @return    string
1112
-     * @throws EE_Error
1113
-     * @throws ReflectionException
1114
-     */
1115
-    function espresso_venue_id($EVT_ID = 0)
1116
-    {
1117
-        $venue = EEH_Venue_View::get_venue($EVT_ID);
1118
-        return $venue instanceof EE_Venue ? $venue->ID() : 0;
1119
-    }
1106
+	/**
1107
+	 *    espresso_venue_name
1108
+	 *
1109
+	 * @access    public
1110
+	 * @param int $EVT_ID
1111
+	 * @return    string
1112
+	 * @throws EE_Error
1113
+	 * @throws ReflectionException
1114
+	 */
1115
+	function espresso_venue_id($EVT_ID = 0)
1116
+	{
1117
+		$venue = EEH_Venue_View::get_venue($EVT_ID);
1118
+		return $venue instanceof EE_Venue ? $venue->ID() : 0;
1119
+	}
1120 1120
 }
1121 1121
 
1122 1122
 
1123 1123
 if (! function_exists('espresso_is_venue_private')) {
1124
-    /**
1125
-     * Return whether a venue is private or not.
1126
-     *
1127
-     * @param int $VNU_ID optional, the venue id to check.
1128
-     *
1129
-     * @return bool | null
1130
-     * @throws EE_Error
1131
-     * @throws ReflectionException
1132
-     * @see EEH_Venue_View::get_venue() for more info on expected return results.
1133
-     */
1134
-    function espresso_is_venue_private($VNU_ID = 0)
1135
-    {
1136
-        return EEH_Venue_View::is_venue_private($VNU_ID);
1137
-    }
1124
+	/**
1125
+	 * Return whether a venue is private or not.
1126
+	 *
1127
+	 * @param int $VNU_ID optional, the venue id to check.
1128
+	 *
1129
+	 * @return bool | null
1130
+	 * @throws EE_Error
1131
+	 * @throws ReflectionException
1132
+	 * @see EEH_Venue_View::get_venue() for more info on expected return results.
1133
+	 */
1134
+	function espresso_is_venue_private($VNU_ID = 0)
1135
+	{
1136
+		return EEH_Venue_View::is_venue_private($VNU_ID);
1137
+	}
1138 1138
 }
1139 1139
 
1140 1140
 
1141 1141
 if (! function_exists('espresso_venue_is_password_protected')) {
1142
-    /**
1143
-     * returns true or false if a venue is password protected or not
1144
-     *
1145
-     * @param int $VNU_ID optional, the venue id to check.
1146
-     * @return bool
1147
-     * @throws EE_Error
1148
-     * @throws ReflectionException
1149
-     */
1150
-    function espresso_venue_is_password_protected($VNU_ID = 0)
1151
-    {
1152
-        EE_Registry::instance()->load_helper('Venue_View');
1153
-        return EEH_Venue_View::is_venue_password_protected($VNU_ID);
1154
-    }
1142
+	/**
1143
+	 * returns true or false if a venue is password protected or not
1144
+	 *
1145
+	 * @param int $VNU_ID optional, the venue id to check.
1146
+	 * @return bool
1147
+	 * @throws EE_Error
1148
+	 * @throws ReflectionException
1149
+	 */
1150
+	function espresso_venue_is_password_protected($VNU_ID = 0)
1151
+	{
1152
+		EE_Registry::instance()->load_helper('Venue_View');
1153
+		return EEH_Venue_View::is_venue_password_protected($VNU_ID);
1154
+	}
1155 1155
 }
1156 1156
 
1157 1157
 
1158 1158
 if (! function_exists('espresso_password_protected_venue_form')) {
1159
-    /**
1160
-     * Returns a password form if venue is password protected.
1161
-     *
1162
-     * @param int $VNU_ID optional, the venue id to check.
1163
-     * @return string
1164
-     * @throws EE_Error
1165
-     * @throws ReflectionException
1166
-     */
1167
-    function espresso_password_protected_venue_form($VNU_ID = 0)
1168
-    {
1169
-        EE_Registry::instance()->load_helper('Venue_View');
1170
-        return EEH_Venue_View::password_protected_venue_form($VNU_ID);
1171
-    }
1159
+	/**
1160
+	 * Returns a password form if venue is password protected.
1161
+	 *
1162
+	 * @param int $VNU_ID optional, the venue id to check.
1163
+	 * @return string
1164
+	 * @throws EE_Error
1165
+	 * @throws ReflectionException
1166
+	 */
1167
+	function espresso_password_protected_venue_form($VNU_ID = 0)
1168
+	{
1169
+		EE_Registry::instance()->load_helper('Venue_View');
1170
+		return EEH_Venue_View::password_protected_venue_form($VNU_ID);
1171
+	}
1172 1172
 }
1173 1173
 
1174 1174
 
1175 1175
 if (! function_exists('espresso_venue_name')) {
1176
-    /**
1177
-     *    espresso_venue_name
1178
-     *
1179
-     * @access    public
1180
-     * @param int    $VNU_ID
1181
-     * @param string $link_to - options( details, website, none ) whether to turn Venue name into a clickable link to the Venue's details page or website
1182
-     * @param bool   $echo
1183
-     * @return    string
1184
-     * @throws EE_Error
1185
-     * @throws ReflectionException
1186
-     */
1187
-    function espresso_venue_name($VNU_ID = 0, $link_to = 'details', $echo = true)
1188
-    {
1189
-        if ($echo) {
1190
-            echo wp_kses(EEH_Venue_View::venue_name($link_to, $VNU_ID), AllowedTags::getWithFormTags());
1191
-            return '';
1192
-        }
1193
-        return EEH_Venue_View::venue_name($link_to, $VNU_ID);
1194
-    }
1176
+	/**
1177
+	 *    espresso_venue_name
1178
+	 *
1179
+	 * @access    public
1180
+	 * @param int    $VNU_ID
1181
+	 * @param string $link_to - options( details, website, none ) whether to turn Venue name into a clickable link to the Venue's details page or website
1182
+	 * @param bool   $echo
1183
+	 * @return    string
1184
+	 * @throws EE_Error
1185
+	 * @throws ReflectionException
1186
+	 */
1187
+	function espresso_venue_name($VNU_ID = 0, $link_to = 'details', $echo = true)
1188
+	{
1189
+		if ($echo) {
1190
+			echo wp_kses(EEH_Venue_View::venue_name($link_to, $VNU_ID), AllowedTags::getWithFormTags());
1191
+			return '';
1192
+		}
1193
+		return EEH_Venue_View::venue_name($link_to, $VNU_ID);
1194
+	}
1195 1195
 }
1196 1196
 
1197 1197
 
1198 1198
 if (! function_exists('espresso_venue_link')) {
1199
-    /**
1200
-     *    espresso_venue_link
1201
-     *
1202
-     * @access    public
1203
-     * @param int    $VNU_ID
1204
-     * @param string $text
1205
-     * @return    string
1206
-     * @throws EE_Error
1207
-     * @throws ReflectionException
1208
-     */
1209
-    function espresso_venue_link($VNU_ID = 0, $text = '')
1210
-    {
1211
-        return EEH_Venue_View::venue_details_link($VNU_ID, $text);
1212
-    }
1199
+	/**
1200
+	 *    espresso_venue_link
1201
+	 *
1202
+	 * @access    public
1203
+	 * @param int    $VNU_ID
1204
+	 * @param string $text
1205
+	 * @return    string
1206
+	 * @throws EE_Error
1207
+	 * @throws ReflectionException
1208
+	 */
1209
+	function espresso_venue_link($VNU_ID = 0, $text = '')
1210
+	{
1211
+		return EEH_Venue_View::venue_details_link($VNU_ID, $text);
1212
+	}
1213 1213
 }
1214 1214
 
1215 1215
 
1216 1216
 if (! function_exists('espresso_venue_description')) {
1217
-    /**
1218
-     *    espresso_venue_description
1219
-     *
1220
-     * @access    public
1221
-     * @param bool $VNU_ID
1222
-     * @param bool $echo
1223
-     * @return    string
1224
-     * @throws EE_Error
1225
-     * @throws ReflectionException
1226
-     */
1227
-    function espresso_venue_description($VNU_ID = false, $echo = true)
1228
-    {
1229
-        if ($echo) {
1230
-            echo wp_kses(EEH_Venue_View::venue_description($VNU_ID), AllowedTags::getWithFormTags());
1231
-            return '';
1232
-        }
1233
-        return EEH_Venue_View::venue_description($VNU_ID);
1234
-    }
1217
+	/**
1218
+	 *    espresso_venue_description
1219
+	 *
1220
+	 * @access    public
1221
+	 * @param bool $VNU_ID
1222
+	 * @param bool $echo
1223
+	 * @return    string
1224
+	 * @throws EE_Error
1225
+	 * @throws ReflectionException
1226
+	 */
1227
+	function espresso_venue_description($VNU_ID = false, $echo = true)
1228
+	{
1229
+		if ($echo) {
1230
+			echo wp_kses(EEH_Venue_View::venue_description($VNU_ID), AllowedTags::getWithFormTags());
1231
+			return '';
1232
+		}
1233
+		return EEH_Venue_View::venue_description($VNU_ID);
1234
+	}
1235 1235
 }
1236 1236
 
1237 1237
 
1238 1238
 if (! function_exists('espresso_venue_excerpt')) {
1239
-    /**
1240
-     *    espresso_venue_excerpt
1241
-     *
1242
-     * @access    public
1243
-     * @param int  $VNU_ID
1244
-     * @param bool $echo
1245
-     * @return    string
1246
-     * @throws EE_Error
1247
-     * @throws ReflectionException
1248
-     */
1249
-    function espresso_venue_excerpt($VNU_ID = 0, $echo = true)
1250
-    {
1251
-        if ($echo) {
1252
-            echo wp_kses(EEH_Venue_View::venue_excerpt($VNU_ID), AllowedTags::getWithFormTags());
1253
-            return '';
1254
-        }
1255
-        return EEH_Venue_View::venue_excerpt($VNU_ID);
1256
-    }
1239
+	/**
1240
+	 *    espresso_venue_excerpt
1241
+	 *
1242
+	 * @access    public
1243
+	 * @param int  $VNU_ID
1244
+	 * @param bool $echo
1245
+	 * @return    string
1246
+	 * @throws EE_Error
1247
+	 * @throws ReflectionException
1248
+	 */
1249
+	function espresso_venue_excerpt($VNU_ID = 0, $echo = true)
1250
+	{
1251
+		if ($echo) {
1252
+			echo wp_kses(EEH_Venue_View::venue_excerpt($VNU_ID), AllowedTags::getWithFormTags());
1253
+			return '';
1254
+		}
1255
+		return EEH_Venue_View::venue_excerpt($VNU_ID);
1256
+	}
1257 1257
 }
1258 1258
 
1259 1259
 
1260 1260
 if (! function_exists('espresso_venue_categories')) {
1261
-    /**
1262
-     * espresso_venue_categories
1263
-     * returns the terms associated with a venue
1264
-     *
1265
-     * @param int  $VNU_ID
1266
-     * @param bool $hide_uncategorized
1267
-     * @param bool $echo
1268
-     * @return string
1269
-     * @throws EE_Error
1270
-     * @throws ReflectionException
1271
-     */
1272
-    function espresso_venue_categories($VNU_ID = 0, $hide_uncategorized = true, $echo = true)
1273
-    {
1274
-        if ($echo) {
1275
-            echo wp_kses(EEH_Venue_View::venue_categories($VNU_ID, $hide_uncategorized), AllowedTags::getWithFormTags());
1276
-            return '';
1277
-        }
1278
-        return EEH_Venue_View::venue_categories($VNU_ID, $hide_uncategorized);
1279
-    }
1261
+	/**
1262
+	 * espresso_venue_categories
1263
+	 * returns the terms associated with a venue
1264
+	 *
1265
+	 * @param int  $VNU_ID
1266
+	 * @param bool $hide_uncategorized
1267
+	 * @param bool $echo
1268
+	 * @return string
1269
+	 * @throws EE_Error
1270
+	 * @throws ReflectionException
1271
+	 */
1272
+	function espresso_venue_categories($VNU_ID = 0, $hide_uncategorized = true, $echo = true)
1273
+	{
1274
+		if ($echo) {
1275
+			echo wp_kses(EEH_Venue_View::venue_categories($VNU_ID, $hide_uncategorized), AllowedTags::getWithFormTags());
1276
+			return '';
1277
+		}
1278
+		return EEH_Venue_View::venue_categories($VNU_ID, $hide_uncategorized);
1279
+	}
1280 1280
 }
1281 1281
 
1282 1282
 
1283 1283
 if (! function_exists('espresso_venue_address')) {
1284
-    /**
1285
-     * espresso_venue_address
1286
-     * returns a formatted block of html  for displaying a venue's address
1287
-     *
1288
-     * @param string $type 'inline' or 'multiline'
1289
-     * @param int    $VNU_ID
1290
-     * @param bool   $echo
1291
-     * @return string
1292
-     * @throws EE_Error
1293
-     * @throws ReflectionException
1294
-     */
1295
-    function espresso_venue_address($type = 'multiline', $VNU_ID = 0, $echo = true)
1296
-    {
1297
-        if ($echo) {
1298
-            echo wp_kses(EEH_Venue_View::venue_address($type, $VNU_ID), AllowedTags::getWithFormTags());
1299
-            return '';
1300
-        }
1301
-        return EEH_Venue_View::venue_address($type, $VNU_ID);
1302
-    }
1284
+	/**
1285
+	 * espresso_venue_address
1286
+	 * returns a formatted block of html  for displaying a venue's address
1287
+	 *
1288
+	 * @param string $type 'inline' or 'multiline'
1289
+	 * @param int    $VNU_ID
1290
+	 * @param bool   $echo
1291
+	 * @return string
1292
+	 * @throws EE_Error
1293
+	 * @throws ReflectionException
1294
+	 */
1295
+	function espresso_venue_address($type = 'multiline', $VNU_ID = 0, $echo = true)
1296
+	{
1297
+		if ($echo) {
1298
+			echo wp_kses(EEH_Venue_View::venue_address($type, $VNU_ID), AllowedTags::getWithFormTags());
1299
+			return '';
1300
+		}
1301
+		return EEH_Venue_View::venue_address($type, $VNU_ID);
1302
+	}
1303 1303
 }
1304 1304
 
1305 1305
 
1306 1306
 if (! function_exists('espresso_venue_raw_address')) {
1307
-    /**
1308
-     * espresso_venue_address
1309
-     * returns an UN-formatted string containing a venue's address
1310
-     *
1311
-     * @param string $type 'inline' or 'multiline'
1312
-     * @param int    $VNU_ID
1313
-     * @param bool   $echo
1314
-     * @return string
1315
-     * @throws EE_Error
1316
-     * @throws ReflectionException
1317
-     */
1318
-    function espresso_venue_raw_address($type = 'multiline', $VNU_ID = 0, $echo = true)
1319
-    {
1320
-        if ($echo) {
1321
-            echo wp_kses(EEH_Venue_View::venue_address($type, $VNU_ID, false, false), AllowedTags::getWithFormTags());
1322
-            return '';
1323
-        }
1324
-        return EEH_Venue_View::venue_address($type, $VNU_ID, false, false);
1325
-    }
1307
+	/**
1308
+	 * espresso_venue_address
1309
+	 * returns an UN-formatted string containing a venue's address
1310
+	 *
1311
+	 * @param string $type 'inline' or 'multiline'
1312
+	 * @param int    $VNU_ID
1313
+	 * @param bool   $echo
1314
+	 * @return string
1315
+	 * @throws EE_Error
1316
+	 * @throws ReflectionException
1317
+	 */
1318
+	function espresso_venue_raw_address($type = 'multiline', $VNU_ID = 0, $echo = true)
1319
+	{
1320
+		if ($echo) {
1321
+			echo wp_kses(EEH_Venue_View::venue_address($type, $VNU_ID, false, false), AllowedTags::getWithFormTags());
1322
+			return '';
1323
+		}
1324
+		return EEH_Venue_View::venue_address($type, $VNU_ID, false, false);
1325
+	}
1326 1326
 }
1327 1327
 
1328 1328
 
1329 1329
 if (! function_exists('espresso_venue_has_address')) {
1330
-    /**
1331
-     * espresso_venue_has_address
1332
-     * returns TRUE or FALSE if a Venue has address information
1333
-     *
1334
-     * @param int $VNU_ID
1335
-     * @return bool
1336
-     * @throws EE_Error
1337
-     * @throws ReflectionException
1338
-     */
1339
-    function espresso_venue_has_address($VNU_ID = 0)
1340
-    {
1341
-        return EEH_Venue_View::venue_has_address($VNU_ID);
1342
-    }
1330
+	/**
1331
+	 * espresso_venue_has_address
1332
+	 * returns TRUE or FALSE if a Venue has address information
1333
+	 *
1334
+	 * @param int $VNU_ID
1335
+	 * @return bool
1336
+	 * @throws EE_Error
1337
+	 * @throws ReflectionException
1338
+	 */
1339
+	function espresso_venue_has_address($VNU_ID = 0)
1340
+	{
1341
+		return EEH_Venue_View::venue_has_address($VNU_ID);
1342
+	}
1343 1343
 }
1344 1344
 
1345 1345
 
1346 1346
 if (! function_exists('espresso_venue_gmap')) {
1347
-    /**
1348
-     * espresso_venue_gmap
1349
-     * returns a google map for the venue address
1350
-     *
1351
-     * @param int   $VNU_ID
1352
-     * @param bool  $map_ID
1353
-     * @param array $gmap
1354
-     * @param bool  $echo
1355
-     * @return string
1356
-     * @throws EE_Error
1357
-     * @throws ReflectionException
1358
-     */
1359
-    function espresso_venue_gmap($VNU_ID = 0, $map_ID = false, $gmap = [], $echo = true)
1360
-    {
1361
-        if ($echo) {
1362
-            echo EEH_Venue_View::venue_gmap($VNU_ID, $map_ID, $gmap); // already escaped
1363
-            return '';
1364
-        }
1365
-        return EEH_Venue_View::venue_gmap($VNU_ID, $map_ID, $gmap);
1366
-    }
1347
+	/**
1348
+	 * espresso_venue_gmap
1349
+	 * returns a google map for the venue address
1350
+	 *
1351
+	 * @param int   $VNU_ID
1352
+	 * @param bool  $map_ID
1353
+	 * @param array $gmap
1354
+	 * @param bool  $echo
1355
+	 * @return string
1356
+	 * @throws EE_Error
1357
+	 * @throws ReflectionException
1358
+	 */
1359
+	function espresso_venue_gmap($VNU_ID = 0, $map_ID = false, $gmap = [], $echo = true)
1360
+	{
1361
+		if ($echo) {
1362
+			echo EEH_Venue_View::venue_gmap($VNU_ID, $map_ID, $gmap); // already escaped
1363
+			return '';
1364
+		}
1365
+		return EEH_Venue_View::venue_gmap($VNU_ID, $map_ID, $gmap);
1366
+	}
1367 1367
 }
1368 1368
 
1369 1369
 
1370 1370
 if (! function_exists('espresso_venue_phone')) {
1371
-    /**
1372
-     * espresso_venue_phone
1373
-     *
1374
-     * @param int  $VNU_ID
1375
-     * @param bool $echo
1376
-     * @return string
1377
-     * @throws EE_Error
1378
-     * @throws ReflectionException
1379
-     */
1380
-    function espresso_venue_phone($VNU_ID = 0, $echo = true)
1381
-    {
1382
-        if ($echo) {
1383
-            echo wp_kses(EEH_Venue_View::venue_phone($VNU_ID), AllowedTags::getWithFormTags());
1384
-            return '';
1385
-        }
1386
-        return EEH_Venue_View::venue_phone($VNU_ID);
1387
-    }
1371
+	/**
1372
+	 * espresso_venue_phone
1373
+	 *
1374
+	 * @param int  $VNU_ID
1375
+	 * @param bool $echo
1376
+	 * @return string
1377
+	 * @throws EE_Error
1378
+	 * @throws ReflectionException
1379
+	 */
1380
+	function espresso_venue_phone($VNU_ID = 0, $echo = true)
1381
+	{
1382
+		if ($echo) {
1383
+			echo wp_kses(EEH_Venue_View::venue_phone($VNU_ID), AllowedTags::getWithFormTags());
1384
+			return '';
1385
+		}
1386
+		return EEH_Venue_View::venue_phone($VNU_ID);
1387
+	}
1388 1388
 }
1389 1389
 
1390 1390
 
1391 1391
 if (! function_exists('espresso_venue_website')) {
1392
-    /**
1393
-     * espresso_venue_website
1394
-     *
1395
-     * @param int  $VNU_ID
1396
-     * @param bool $echo
1397
-     * @return string
1398
-     * @throws EE_Error
1399
-     * @throws ReflectionException
1400
-     */
1401
-    function espresso_venue_website($VNU_ID = 0, $echo = true)
1402
-    {
1403
-        if ($echo) {
1404
-            echo wp_kses(EEH_Venue_View::venue_website_link($VNU_ID), AllowedTags::getWithFormTags());
1405
-            return '';
1406
-        }
1407
-        return EEH_Venue_View::venue_website_link($VNU_ID);
1408
-    }
1392
+	/**
1393
+	 * espresso_venue_website
1394
+	 *
1395
+	 * @param int  $VNU_ID
1396
+	 * @param bool $echo
1397
+	 * @return string
1398
+	 * @throws EE_Error
1399
+	 * @throws ReflectionException
1400
+	 */
1401
+	function espresso_venue_website($VNU_ID = 0, $echo = true)
1402
+	{
1403
+		if ($echo) {
1404
+			echo wp_kses(EEH_Venue_View::venue_website_link($VNU_ID), AllowedTags::getWithFormTags());
1405
+			return '';
1406
+		}
1407
+		return EEH_Venue_View::venue_website_link($VNU_ID);
1408
+	}
1409 1409
 }
1410 1410
 
1411 1411
 
1412 1412
 if (! function_exists('espresso_edit_venue_link')) {
1413
-    /**
1414
-     * espresso_edit_venue_link
1415
-     *
1416
-     * @param int  $VNU_ID
1417
-     * @param bool $echo
1418
-     * @return string
1419
-     * @throws EE_Error
1420
-     * @throws ReflectionException
1421
-     */
1422
-    function espresso_edit_venue_link($VNU_ID = 0, $echo = true)
1423
-    {
1424
-        if ($echo) {
1425
-            echo wp_kses(EEH_Venue_View::edit_venue_link($VNU_ID), AllowedTags::getWithFormTags());
1426
-            return '';
1427
-        }
1428
-        return EEH_Venue_View::edit_venue_link($VNU_ID);
1429
-    }
1413
+	/**
1414
+	 * espresso_edit_venue_link
1415
+	 *
1416
+	 * @param int  $VNU_ID
1417
+	 * @param bool $echo
1418
+	 * @return string
1419
+	 * @throws EE_Error
1420
+	 * @throws ReflectionException
1421
+	 */
1422
+	function espresso_edit_venue_link($VNU_ID = 0, $echo = true)
1423
+	{
1424
+		if ($echo) {
1425
+			echo wp_kses(EEH_Venue_View::edit_venue_link($VNU_ID), AllowedTags::getWithFormTags());
1426
+			return '';
1427
+		}
1428
+		return EEH_Venue_View::edit_venue_link($VNU_ID);
1429
+	}
1430 1430
 }
1431 1431
 
1432 1432
 
Please login to merge, or discard this patch.
Spacing   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
  */
152 152
 function can_use_espresso_conditionals($conditional_tag)
153 153
 {
154
-    if (! did_action('AHEE__EE_System__initialize')) {
154
+    if ( ! did_action('AHEE__EE_System__initialize')) {
155 155
         EE_Error::doing_it_wrong(
156 156
             __FUNCTION__,
157 157
             sprintf(
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
 
172 172
 /*************************** Event Queries ***************************/
173 173
 
174
-if (! function_exists('espresso_get_events')) {
174
+if ( ! function_exists('espresso_get_events')) {
175 175
     /**
176 176
      *    espresso_get_events
177 177
      *
@@ -221,10 +221,10 @@  discard block
 block discarded – undo
221 221
  */
222 222
 function espresso_load_ticket_selector()
223 223
 {
224
-    EE_Registry::instance()->load_file(EE_MODULES . 'ticket_selector', 'EED_Ticket_Selector', 'module');
224
+    EE_Registry::instance()->load_file(EE_MODULES.'ticket_selector', 'EED_Ticket_Selector', 'module');
225 225
 }
226 226
 
227
-if (! function_exists('espresso_ticket_selector')) {
227
+if ( ! function_exists('espresso_ticket_selector')) {
228 228
     /**
229 229
      * espresso_ticket_selector
230 230
      *
@@ -234,7 +234,7 @@  discard block
 block discarded – undo
234 234
      */
235 235
     function espresso_ticket_selector($event = null)
236 236
     {
237
-        if (! apply_filters('FHEE_disable_espresso_ticket_selector', false)) {
237
+        if ( ! apply_filters('FHEE_disable_espresso_ticket_selector', false)) {
238 238
             espresso_load_ticket_selector();
239 239
             EED_Ticket_Selector::set_definitions();
240 240
             echo EED_Ticket_Selector::display_ticket_selector($event); // already escaped
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
 }
244 244
 
245 245
 
246
-if (! function_exists('espresso_view_details_btn')) {
246
+if ( ! function_exists('espresso_view_details_btn')) {
247 247
     /**
248 248
      * espresso_view_details_btn
249 249
      *
@@ -253,7 +253,7 @@  discard block
 block discarded – undo
253 253
      */
254 254
     function espresso_view_details_btn($event = null)
255 255
     {
256
-        if (! apply_filters('FHEE_disable_espresso_view_details_btn', false)) {
256
+        if ( ! apply_filters('FHEE_disable_espresso_view_details_btn', false)) {
257 257
             espresso_load_ticket_selector();
258 258
             echo EED_Ticket_Selector::display_ticket_selector($event, true); // already escaped
259 259
         }
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 
264 264
 /*************************** EEH_Event_View ***************************/
265 265
 
266
-if (! function_exists('espresso_load_event_list_assets')) {
266
+if ( ! function_exists('espresso_load_event_list_assets')) {
267 267
     /**
268 268
      * espresso_load_event_list_assets
269 269
      * ensures that event list styles and scripts are loaded
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
 }
280 280
 
281 281
 
282
-if (! function_exists('espresso_event_reg_button')) {
282
+if ( ! function_exists('espresso_event_reg_button')) {
283 283
     /**
284 284
      * espresso_event_reg_button
285 285
      * returns the "Register Now" button if event is active,
@@ -296,7 +296,7 @@  discard block
 block discarded – undo
296 296
     function espresso_event_reg_button($btn_text_if_active = null, $btn_text_if_inactive = false, $EVT_ID = false)
297 297
     {
298 298
         $event = EEH_Event_View::get_event($EVT_ID);
299
-        if (! $event instanceof EE_Event) {
299
+        if ( ! $event instanceof EE_Event) {
300 300
             return;
301 301
         }
302 302
         $event_status = $event->get_active_status();
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
 }
342 342
 
343 343
 
344
-if (! function_exists('espresso_display_ticket_selector')) {
344
+if ( ! function_exists('espresso_display_ticket_selector')) {
345 345
     /**
346 346
      * espresso_display_ticket_selector
347 347
      * whether or not to display the Ticket Selector for an event
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
 }
359 359
 
360 360
 
361
-if (! function_exists('espresso_event_status_banner')) {
361
+if ( ! function_exists('espresso_event_status_banner')) {
362 362
     /**
363 363
      * espresso_event_status
364 364
      * returns a banner showing the event status if it is sold out, expired, or inactive
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 }
376 376
 
377 377
 
378
-if (! function_exists('espresso_event_status')) {
378
+if ( ! function_exists('espresso_event_status')) {
379 379
     /**
380 380
      * espresso_event_status
381 381
      * returns the event status if it is sold out, expired, or inactive
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
 }
394 394
 
395 395
 
396
-if (! function_exists('espresso_event_categories')) {
396
+if ( ! function_exists('espresso_event_categories')) {
397 397
     /**
398 398
      * espresso_event_categories
399 399
      * returns the terms associated with an event
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
 }
417 417
 
418 418
 
419
-if (! function_exists('espresso_event_tickets_available')) {
419
+if ( ! function_exists('espresso_event_tickets_available')) {
420 420
     /**
421 421
      * espresso_event_tickets_available
422 422
      * returns the ticket types available for purchase for an event
@@ -434,14 +434,14 @@  discard block
 block discarded – undo
434 434
         if (is_array($tickets) && ! empty($tickets)) {
435 435
             // if formatting then $html will be a string, else it will be an array of ticket objects
436 436
             $html =
437
-                $format ? '<ul id="ee-event-tickets-ul-' . esc_attr($EVT_ID) . '" class="ee-event-tickets-ul">' : [];
437
+                $format ? '<ul id="ee-event-tickets-ul-'.esc_attr($EVT_ID).'" class="ee-event-tickets-ul">' : [];
438 438
             foreach ($tickets as $ticket) {
439 439
                 if ($ticket instanceof EE_Ticket) {
440 440
                     if ($format) {
441 441
                         $html .= '<li id="ee-event-tickets-li-'
442 442
                                  . esc_attr($ticket->ID())
443 443
                                  . '" class="ee-event-tickets-li">';
444
-                        $html .= esc_html($ticket->name()) . ' ';
444
+                        $html .= esc_html($ticket->name()).' ';
445 445
                         $html .= EEH_Template::format_currency(
446 446
                             $ticket->get_ticket_total_with_taxes()
447 447
                         ); // already escaped
@@ -464,7 +464,7 @@  discard block
 block discarded – undo
464 464
     }
465 465
 }
466 466
 
467
-if (! function_exists('espresso_event_date_obj')) {
467
+if ( ! function_exists('espresso_event_date_obj')) {
468 468
     /**
469 469
      * espresso_event_date_obj
470 470
      * returns the primary date object for an event
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
 }
482 482
 
483 483
 
484
-if (! function_exists('espresso_event_date')) {
484
+if ( ! function_exists('espresso_event_date')) {
485 485
     /**
486 486
      * espresso_event_date
487 487
      * returns the primary date for an event
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
 }
511 511
 
512 512
 
513
-if (! function_exists('espresso_list_of_event_dates')) {
513
+if ( ! function_exists('espresso_list_of_event_dates')) {
514 514
     /**
515 515
      * espresso_list_of_event_dates
516 516
      * returns a unordered list of dates for an event
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
         $DTT_ID = LoaderFactory::getShared(RequestInterface::class)->getRequestParam('datetime', 0, 'int');
543 543
         $arguments = apply_filters(
544 544
             'FHEE__espresso_list_of_event_dates__arguments',
545
-            [ $EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID ]
545
+            [$EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID]
546 546
         );
547 547
         [$EVT_ID, $date_format, $time_format, $echo, $show_expired, $format, $add_breaks, $limit, $DTT_ID] = $arguments;
548 548
         $date_format = ! empty($date_format) ? $date_format : get_option('date_format');
@@ -552,7 +552,7 @@  discard block
 block discarded – undo
552 552
         $datetimes   = $DTT_ID
553 553
             ? [EEH_Event_View::get_date_obj($DTT_ID)]
554 554
             : EEH_Event_View::get_all_date_obj($EVT_ID, $show_expired, false, (int) $limit);
555
-        if (! $format) {
555
+        if ( ! $format) {
556 556
             return apply_filters('FHEE__espresso_list_of_event_dates__datetimes', $datetimes);
557 557
         }
558 558
         $newline = $add_breaks ? '<br />' : '';
@@ -561,7 +561,7 @@  discard block
 block discarded – undo
561 561
 			$cols = count($datetimes);
562 562
 			$cols = $cols >= 3 ? 'big' : 'small';
563 563
 			$ul_class = "ee-event-datetimes-ul ee-event-datetimes-ul--{$cols}";
564
-			$html = '<ul id="ee-event-datetimes-ul-' . esc_attr($post->ID) . '" class="'. $ul_class.'">';
564
+			$html = '<ul id="ee-event-datetimes-ul-'.esc_attr($post->ID).'" class="'.$ul_class.'">';
565 565
 
566 566
             foreach ($datetimes as $datetime) {
567 567
                 if ($datetime instanceof EE_Datetime) {
@@ -570,36 +570,36 @@  discard block
 block discarded – undo
570 570
                     $datetime_html        = ! empty($datetime_name)
571 571
                         ? '
572 572
                         <strong class="ee-event-datetimes-li-date-name">
573
-                          ' . esc_html($datetime_name) . '
573
+                          ' . esc_html($datetime_name).'
574 574
                        </strong>' . $newline
575 575
                         : '';
576 576
 
577 577
                     $datetime_html .= '
578 578
                         <span class="ee-event-datetimes-li-daterange">
579 579
 							<span class="dashicons dashicons-calendar"></span>&nbsp;'
580
-							. $datetime->date_range($date_format). '
580
+							. $datetime->date_range($date_format).'
581 581
 						</span>
582 582
                         <br/>
583 583
                         <span class="ee-event-datetimes-li-timerange">
584 584
 							<span class="dashicons dashicons-clock"></span>&nbsp;'
585
-							. $datetime->time_range($time_format) . '
585
+							. $datetime->time_range($time_format).'
586 586
 						</span>
587 587
                         ';
588 588
 
589 589
                     $venue = $datetime->venue();
590 590
                     if ($venue instanceof EE_Venue) {
591
-                    	$venue_name      = esc_html($venue->name());
591
+                    	$venue_name = esc_html($venue->name());
592 592
                         $datetime_html .= '<br /><span class="ee-event-datetimes-li-venue">';
593 593
                         $datetime_html .= '<span class="dashicons dashicons-admin-home"></span>&nbsp;';
594
-                        $datetime_html .= '<a href="'. esc_url_raw($venue->get_permalink()) .'" target="_blank">';
595
-                        $datetime_html .= $venue_name . '</a></span>';
594
+                        $datetime_html .= '<a href="'.esc_url_raw($venue->get_permalink()).'" target="_blank">';
595
+                        $datetime_html .= $venue_name.'</a></span>';
596 596
                     }
597 597
 
598 598
                     $datetime_description = $datetime->description();
599 599
                     $datetime_html .= ! empty($datetime_description)
600 600
                         ? '
601 601
                         <span class="ee-event-datetimes-li-date-desc">
602
-                            ' . wp_kses($datetime_description, $allowedtags) . '
602
+                            ' . wp_kses($datetime_description, $allowedtags).'
603 603
                         </span>' . $newline
604 604
                         : '';
605 605
 
@@ -611,11 +611,11 @@  discard block
 block discarded – undo
611 611
                     );
612 612
 
613 613
                     $DTD_ID        = esc_attr($datetime->ID());
614
-                    $active_status = esc_attr('ee-event-datetimes-li-' . $datetime->get_active_status());
614
+                    $active_status = esc_attr('ee-event-datetimes-li-'.$datetime->get_active_status());
615 615
 
616 616
                     $html .= '
617
-                    <li id="ee-event-datetimes-li-' . $DTD_ID . '" class="ee-event-datetimes-li ' . $active_status . '">
618
-                        ' . $datetime_html . '
617
+                    <li id="ee-event-datetimes-li-' . $DTD_ID.'" class="ee-event-datetimes-li '.$active_status.'">
618
+                        ' . $datetime_html.'
619 619
                     </li>';
620 620
                 }
621 621
             }
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
                 ' . esc_html__(
630 630
                     'There are no upcoming dates for this event.',
631 631
                     'event_espresso'
632
-                ) . '
632
+                ).'
633 633
             </p>
634 634
             <br/>';
635 635
         }
@@ -642,7 +642,7 @@  discard block
 block discarded – undo
642 642
 }
643 643
 
644 644
 
645
-if (! function_exists('espresso_event_end_date')) {
645
+if ( ! function_exists('espresso_event_end_date')) {
646 646
     /**
647 647
      * espresso_event_end_date
648 648
      * returns the last date for an event
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
     }
670 670
 }
671 671
 
672
-if (! function_exists('espresso_event_date_range')) {
672
+if ( ! function_exists('espresso_event_date_range')) {
673 673
     /**
674 674
      * espresso_event_date_range
675 675
      * returns the first and last chronologically ordered dates for an event (if different)
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
     }
728 728
 }
729 729
 
730
-if (! function_exists('espresso_next_upcoming_datetime_obj')) {
730
+if ( ! function_exists('espresso_next_upcoming_datetime_obj')) {
731 731
     /**
732 732
      * espresso_next_upcoming_datetime_obj
733 733
      * returns the next upcoming datetime object for an event
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
     }
743 743
 }
744 744
 
745
-if (! function_exists('espresso_next_upcoming_datetime')) {
745
+if ( ! function_exists('espresso_next_upcoming_datetime')) {
746 746
     /**
747 747
      * espresso_next_upcoming_datetime
748 748
      * returns the start date and time for the next upcoming event.
@@ -764,11 +764,11 @@  discard block
 block discarded – undo
764 764
         $time_format = ! empty($time_format) ? $time_format : get_option('time_format');
765 765
         $time_format = apply_filters('FHEE__espresso_next_upcoming_datetime__time_format', $time_format);
766 766
 
767
-        $datetime_format = trim($date_format . ' ' . $time_format);
767
+        $datetime_format = trim($date_format.' '.$time_format);
768 768
 
769 769
         $datetime = espresso_next_upcoming_datetime_obj($EVT_ID);
770 770
 
771
-        if (! $datetime instanceof EE_Datetime) {
771
+        if ( ! $datetime instanceof EE_Datetime) {
772 772
             return '';
773 773
         }
774 774
         if ($echo) {
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
     }
780 780
 }
781 781
 
782
-if (! function_exists('espresso_event_date_as_calendar_page')) {
782
+if ( ! function_exists('espresso_event_date_as_calendar_page')) {
783 783
     /**
784 784
      * espresso_event_date_as_calendar_page
785 785
      * returns the primary date for an event, stylized to appear as the page of a calendar
@@ -796,7 +796,7 @@  discard block
 block discarded – undo
796 796
 }
797 797
 
798 798
 
799
-if (! function_exists('espresso_event_link_url')) {
799
+if ( ! function_exists('espresso_event_link_url')) {
800 800
     /**
801 801
      * espresso_event_link_url
802 802
      *
@@ -817,7 +817,7 @@  discard block
 block discarded – undo
817 817
 }
818 818
 
819 819
 
820
-if (! function_exists('espresso_event_has_content_or_excerpt')) {
820
+if ( ! function_exists('espresso_event_has_content_or_excerpt')) {
821 821
     /**
822 822
      *    espresso_event_has_content_or_excerpt
823 823
      *
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
 }
835 835
 
836 836
 
837
-if (! function_exists('espresso_event_content_or_excerpt')) {
837
+if ( ! function_exists('espresso_event_content_or_excerpt')) {
838 838
     /**
839 839
      * espresso_event_content_or_excerpt
840 840
      *
@@ -854,7 +854,7 @@  discard block
 block discarded – undo
854 854
 }
855 855
 
856 856
 
857
-if (! function_exists('espresso_event_phone')) {
857
+if ( ! function_exists('espresso_event_phone')) {
858 858
     /**
859 859
      * espresso_event_phone
860 860
      *
@@ -875,7 +875,7 @@  discard block
 block discarded – undo
875 875
 }
876 876
 
877 877
 
878
-if (! function_exists('espresso_edit_event_link')) {
878
+if ( ! function_exists('espresso_edit_event_link')) {
879 879
     /**
880 880
      * espresso_edit_event_link
881 881
      * returns a link to edit an event
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
 }
898 898
 
899 899
 
900
-if (! function_exists('espresso_organization_name')) {
900
+if ( ! function_exists('espresso_organization_name')) {
901 901
     /**
902 902
      * espresso_organization_name
903 903
      *
@@ -915,7 +915,7 @@  discard block
 block discarded – undo
915 915
     }
916 916
 }
917 917
 
918
-if (! function_exists('espresso_organization_address')) {
918
+if ( ! function_exists('espresso_organization_address')) {
919 919
     /**
920 920
      * espresso_organization_address
921 921
      *
@@ -939,7 +939,7 @@  discard block
 block discarded – undo
939 939
     }
940 940
 }
941 941
 
942
-if (! function_exists('espresso_organization_email')) {
942
+if ( ! function_exists('espresso_organization_email')) {
943 943
     /**
944 944
      * espresso_organization_email
945 945
      *
@@ -957,7 +957,7 @@  discard block
 block discarded – undo
957 957
     }
958 958
 }
959 959
 
960
-if (! function_exists('espresso_organization_logo_url')) {
960
+if ( ! function_exists('espresso_organization_logo_url')) {
961 961
     /**
962 962
      * espresso_organization_logo_url
963 963
      *
@@ -975,7 +975,7 @@  discard block
 block discarded – undo
975 975
     }
976 976
 }
977 977
 
978
-if (! function_exists('espresso_organization_facebook')) {
978
+if ( ! function_exists('espresso_organization_facebook')) {
979 979
     /**
980 980
      * espresso_organization_facebook
981 981
      *
@@ -993,7 +993,7 @@  discard block
 block discarded – undo
993 993
     }
994 994
 }
995 995
 
996
-if (! function_exists('espresso_organization_twitter')) {
996
+if ( ! function_exists('espresso_organization_twitter')) {
997 997
     /**
998 998
      * espresso_organization_twitter
999 999
      *
@@ -1011,7 +1011,7 @@  discard block
 block discarded – undo
1011 1011
     }
1012 1012
 }
1013 1013
 
1014
-if (! function_exists('espresso_organization_linkedin')) {
1014
+if ( ! function_exists('espresso_organization_linkedin')) {
1015 1015
     /**
1016 1016
      * espresso_organization_linkedin
1017 1017
      *
@@ -1029,7 +1029,7 @@  discard block
 block discarded – undo
1029 1029
     }
1030 1030
 }
1031 1031
 
1032
-if (! function_exists('espresso_organization_pinterest')) {
1032
+if ( ! function_exists('espresso_organization_pinterest')) {
1033 1033
     /**
1034 1034
      * espresso_organization_pinterest
1035 1035
      *
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
     }
1048 1048
 }
1049 1049
 
1050
-if (! function_exists('espresso_organization_google')) {
1050
+if ( ! function_exists('espresso_organization_google')) {
1051 1051
     /**
1052 1052
      * espresso_organization_google
1053 1053
      *
@@ -1065,7 +1065,7 @@  discard block
 block discarded – undo
1065 1065
     }
1066 1066
 }
1067 1067
 
1068
-if (! function_exists('espresso_organization_instagram')) {
1068
+if ( ! function_exists('espresso_organization_instagram')) {
1069 1069
     /**
1070 1070
      * espresso_organization_instagram
1071 1071
      *
@@ -1087,7 +1087,7 @@  discard block
 block discarded – undo
1087 1087
 /*************************** EEH_Venue_View ***************************/
1088 1088
 
1089 1089
 
1090
-if (! function_exists('espresso_event_venues')) {
1090
+if ( ! function_exists('espresso_event_venues')) {
1091 1091
     /**
1092 1092
      * espresso_event_venues
1093 1093
      *
@@ -1102,7 +1102,7 @@  discard block
 block discarded – undo
1102 1102
 }
1103 1103
 
1104 1104
 
1105
-if (! function_exists('espresso_venue_id')) {
1105
+if ( ! function_exists('espresso_venue_id')) {
1106 1106
     /**
1107 1107
      *    espresso_venue_name
1108 1108
      *
@@ -1120,7 +1120,7 @@  discard block
 block discarded – undo
1120 1120
 }
1121 1121
 
1122 1122
 
1123
-if (! function_exists('espresso_is_venue_private')) {
1123
+if ( ! function_exists('espresso_is_venue_private')) {
1124 1124
     /**
1125 1125
      * Return whether a venue is private or not.
1126 1126
      *
@@ -1138,7 +1138,7 @@  discard block
 block discarded – undo
1138 1138
 }
1139 1139
 
1140 1140
 
1141
-if (! function_exists('espresso_venue_is_password_protected')) {
1141
+if ( ! function_exists('espresso_venue_is_password_protected')) {
1142 1142
     /**
1143 1143
      * returns true or false if a venue is password protected or not
1144 1144
      *
@@ -1155,7 +1155,7 @@  discard block
 block discarded – undo
1155 1155
 }
1156 1156
 
1157 1157
 
1158
-if (! function_exists('espresso_password_protected_venue_form')) {
1158
+if ( ! function_exists('espresso_password_protected_venue_form')) {
1159 1159
     /**
1160 1160
      * Returns a password form if venue is password protected.
1161 1161
      *
@@ -1172,7 +1172,7 @@  discard block
 block discarded – undo
1172 1172
 }
1173 1173
 
1174 1174
 
1175
-if (! function_exists('espresso_venue_name')) {
1175
+if ( ! function_exists('espresso_venue_name')) {
1176 1176
     /**
1177 1177
      *    espresso_venue_name
1178 1178
      *
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
 }
1196 1196
 
1197 1197
 
1198
-if (! function_exists('espresso_venue_link')) {
1198
+if ( ! function_exists('espresso_venue_link')) {
1199 1199
     /**
1200 1200
      *    espresso_venue_link
1201 1201
      *
@@ -1213,7 +1213,7 @@  discard block
 block discarded – undo
1213 1213
 }
1214 1214
 
1215 1215
 
1216
-if (! function_exists('espresso_venue_description')) {
1216
+if ( ! function_exists('espresso_venue_description')) {
1217 1217
     /**
1218 1218
      *    espresso_venue_description
1219 1219
      *
@@ -1235,7 +1235,7 @@  discard block
 block discarded – undo
1235 1235
 }
1236 1236
 
1237 1237
 
1238
-if (! function_exists('espresso_venue_excerpt')) {
1238
+if ( ! function_exists('espresso_venue_excerpt')) {
1239 1239
     /**
1240 1240
      *    espresso_venue_excerpt
1241 1241
      *
@@ -1257,7 +1257,7 @@  discard block
 block discarded – undo
1257 1257
 }
1258 1258
 
1259 1259
 
1260
-if (! function_exists('espresso_venue_categories')) {
1260
+if ( ! function_exists('espresso_venue_categories')) {
1261 1261
     /**
1262 1262
      * espresso_venue_categories
1263 1263
      * returns the terms associated with a venue
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
 }
1281 1281
 
1282 1282
 
1283
-if (! function_exists('espresso_venue_address')) {
1283
+if ( ! function_exists('espresso_venue_address')) {
1284 1284
     /**
1285 1285
      * espresso_venue_address
1286 1286
      * returns a formatted block of html  for displaying a venue's address
@@ -1303,7 +1303,7 @@  discard block
 block discarded – undo
1303 1303
 }
1304 1304
 
1305 1305
 
1306
-if (! function_exists('espresso_venue_raw_address')) {
1306
+if ( ! function_exists('espresso_venue_raw_address')) {
1307 1307
     /**
1308 1308
      * espresso_venue_address
1309 1309
      * returns an UN-formatted string containing a venue's address
@@ -1326,7 +1326,7 @@  discard block
 block discarded – undo
1326 1326
 }
1327 1327
 
1328 1328
 
1329
-if (! function_exists('espresso_venue_has_address')) {
1329
+if ( ! function_exists('espresso_venue_has_address')) {
1330 1330
     /**
1331 1331
      * espresso_venue_has_address
1332 1332
      * returns TRUE or FALSE if a Venue has address information
@@ -1343,7 +1343,7 @@  discard block
 block discarded – undo
1343 1343
 }
1344 1344
 
1345 1345
 
1346
-if (! function_exists('espresso_venue_gmap')) {
1346
+if ( ! function_exists('espresso_venue_gmap')) {
1347 1347
     /**
1348 1348
      * espresso_venue_gmap
1349 1349
      * returns a google map for the venue address
@@ -1367,7 +1367,7 @@  discard block
 block discarded – undo
1367 1367
 }
1368 1368
 
1369 1369
 
1370
-if (! function_exists('espresso_venue_phone')) {
1370
+if ( ! function_exists('espresso_venue_phone')) {
1371 1371
     /**
1372 1372
      * espresso_venue_phone
1373 1373
      *
@@ -1388,7 +1388,7 @@  discard block
 block discarded – undo
1388 1388
 }
1389 1389
 
1390 1390
 
1391
-if (! function_exists('espresso_venue_website')) {
1391
+if ( ! function_exists('espresso_venue_website')) {
1392 1392
     /**
1393 1393
      * espresso_venue_website
1394 1394
      *
@@ -1409,7 +1409,7 @@  discard block
 block discarded – undo
1409 1409
 }
1410 1410
 
1411 1411
 
1412
-if (! function_exists('espresso_edit_venue_link')) {
1412
+if ( ! function_exists('espresso_edit_venue_link')) {
1413 1413
     /**
1414 1414
      * espresso_edit_venue_link
1415 1415
      *
Please login to merge, or discard this patch.
registration_form/espresso_events_Registration_Form_Hooks.class.php 2 patches
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -15,99 +15,99 @@  discard block
 block discarded – undo
15 15
  */
16 16
 class espresso_events_Registration_Form_Hooks extends EE_Admin_Hooks
17 17
 {
18
-    protected ?EE_Event $_event = null;
19
-
20
-
21
-    protected function _set_hooks_properties()
22
-    {
23
-        $this->_name = 'registration_form';
24
-        if (
25
-            $this->_adminpage_obj->adminConfig()->useAdvancedEditor()
26
-            && $this->_adminpage_obj->feature()->allowed('use_reg_form_builder')
27
-        ) {
28
-            $this->_metaboxes      = [];
29
-            $this->_scripts_styles = [];
30
-            return;
31
-        }
32
-        $this->_metaboxes = [
33
-            0 => [
34
-                'page_route' => ['edit', 'create_new'],
35
-                'func'       => [$this, 'primary_questions'],
36
-                'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
37
-                'priority'   => 'default',
38
-                'context'    => 'side',
39
-            ],
40
-        ];
41
-
42
-        // hook into the handler for saving question groups
43
-        add_filter(
44
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
45
-            [$this, 'modify_callbacks']
46
-        );
47
-
48
-        // hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
49
-        // restricted by page)
50
-        add_action('AHEE_EE_Admin_Page_CPT__restore_revision', [$this, 'restore_revision'], 10, 2);
51
-    }
52
-
53
-
54
-    /**
55
-     * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
56
-     *
57
-     * @param array $callbacks
58
-     * @return array
59
-     */
60
-    public function modify_callbacks(array $callbacks): array
61
-    {
62
-        // now let's add the question group callback
63
-        $callbacks['primary_question_group_update'] = [$this, 'primary_question_group_update'];
64
-        return $callbacks;
65
-    }
66
-
67
-
68
-    /**
69
-     * Hooked into revision restores.
70
-     *
71
-     * @param $post_id
72
-     * @param $revision_id
73
-     * @return EE_Base_Class
74
-     * @throws EE_Error
75
-     * @throws InvalidArgumentException
76
-     * @throws InvalidDataTypeException
77
-     * @throws InvalidInterfaceException
78
-     * @throws ReflectionException
79
-     */
80
-    public function restore_revision($post_id, $revision_id)
81
-    {
82
-        $post_evt = EEM_Event::instance()->get_one_by_ID($post_id);
83
-        // restore revision for primary questions
84
-        if ($post_evt instanceof EE_Event) {
85
-            $post_evt->restore_revision(
86
-                $revision_id,
87
-                ['Question_Group'],
88
-                ['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
89
-            );
90
-        }
91
-        return $post_evt;
92
-    }
93
-
94
-
95
-    /**
96
-     * Content of metabox.
97
-     *
98
-     * @param $post_id
99
-     * @param $post
100
-     * @throws EE_Error
101
-     * @throws InvalidArgumentException
102
-     * @throws InvalidDataTypeException
103
-     * @throws InvalidInterfaceException
104
-     * @throws ReflectionException
105
-     */
106
-    public function primary_questions($post_id, $post)
107
-    {
108
-        $this->_event = $this->_adminpage_obj->get_event_object();
109
-        $event_id     = $this->_event->ID();
110
-        ?>
18
+	protected ?EE_Event $_event = null;
19
+
20
+
21
+	protected function _set_hooks_properties()
22
+	{
23
+		$this->_name = 'registration_form';
24
+		if (
25
+			$this->_adminpage_obj->adminConfig()->useAdvancedEditor()
26
+			&& $this->_adminpage_obj->feature()->allowed('use_reg_form_builder')
27
+		) {
28
+			$this->_metaboxes      = [];
29
+			$this->_scripts_styles = [];
30
+			return;
31
+		}
32
+		$this->_metaboxes = [
33
+			0 => [
34
+				'page_route' => ['edit', 'create_new'],
35
+				'func'       => [$this, 'primary_questions'],
36
+				'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
37
+				'priority'   => 'default',
38
+				'context'    => 'side',
39
+			],
40
+		];
41
+
42
+		// hook into the handler for saving question groups
43
+		add_filter(
44
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
45
+			[$this, 'modify_callbacks']
46
+		);
47
+
48
+		// hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
49
+		// restricted by page)
50
+		add_action('AHEE_EE_Admin_Page_CPT__restore_revision', [$this, 'restore_revision'], 10, 2);
51
+	}
52
+
53
+
54
+	/**
55
+	 * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
56
+	 *
57
+	 * @param array $callbacks
58
+	 * @return array
59
+	 */
60
+	public function modify_callbacks(array $callbacks): array
61
+	{
62
+		// now let's add the question group callback
63
+		$callbacks['primary_question_group_update'] = [$this, 'primary_question_group_update'];
64
+		return $callbacks;
65
+	}
66
+
67
+
68
+	/**
69
+	 * Hooked into revision restores.
70
+	 *
71
+	 * @param $post_id
72
+	 * @param $revision_id
73
+	 * @return EE_Base_Class
74
+	 * @throws EE_Error
75
+	 * @throws InvalidArgumentException
76
+	 * @throws InvalidDataTypeException
77
+	 * @throws InvalidInterfaceException
78
+	 * @throws ReflectionException
79
+	 */
80
+	public function restore_revision($post_id, $revision_id)
81
+	{
82
+		$post_evt = EEM_Event::instance()->get_one_by_ID($post_id);
83
+		// restore revision for primary questions
84
+		if ($post_evt instanceof EE_Event) {
85
+			$post_evt->restore_revision(
86
+				$revision_id,
87
+				['Question_Group'],
88
+				['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
89
+			);
90
+		}
91
+		return $post_evt;
92
+	}
93
+
94
+
95
+	/**
96
+	 * Content of metabox.
97
+	 *
98
+	 * @param $post_id
99
+	 * @param $post
100
+	 * @throws EE_Error
101
+	 * @throws InvalidArgumentException
102
+	 * @throws InvalidDataTypeException
103
+	 * @throws InvalidInterfaceException
104
+	 * @throws ReflectionException
105
+	 */
106
+	public function primary_questions($post_id, $post)
107
+	{
108
+		$this->_event = $this->_adminpage_obj->get_event_object();
109
+		$event_id     = $this->_event->ID();
110
+		?>
111 111
         <div class="inside">
112 112
             <p>
113 113
                 <strong>
@@ -115,69 +115,69 @@  discard block
 block discarded – undo
115 115
                 </strong>
116 116
                 <br/>
117 117
                 <?php
118
-                printf(
119
-                    esc_html__(
120
-                        'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
121
-                        'event_espresso'
122
-                    ),
123
-                    '<a href="admin.php?page=espresso_registration_form" target="_blank">',
124
-                    '</a>'
125
-                )
126
-                ?>
118
+				printf(
119
+					esc_html__(
120
+						'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
121
+						'event_espresso'
122
+					),
123
+					'<a href="admin.php?page=espresso_registration_form" target="_blank">',
124
+					'</a>'
125
+				)
126
+				?>
127 127
             </p>
128 128
             <?php
129 129
 
130
-            $qsg_where['QSG_deleted'] = false;
131
-            $query_params             = apply_filters(
132
-                'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
133
-                [$qsg_where, 'order_by' => ['QSG_order' => 'ASC']]
134
-            );
135
-            $QSGs                     = EEM_Question_Group::instance()->get_all($query_params);
136
-            $EQGs                     = ! empty($event_id)
137
-                ? $this->_event->get_many_related(
138
-                    'Question_Group',
139
-                    [['Event_Question_Group.EQG_primary' => true]]
140
-                )
141
-                : [];
142
-            $EQGids                   = array_keys($EQGs);
143
-
144
-            if (! empty($QSGs)) {
145
-                $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
146
-                foreach ($QSGs as $QSG) {
147
-                    $QSG_ID             = absint($QSG->ID());
148
-                    $is_system_question = $QSG->get('QSG_system') === 1;
149
-                    $checked            = $is_system_question || in_array($QSG_ID, $EQGids, true)
150
-                        ? ' checked'
151
-                        : '';
152
-
153
-                    $visibility = $is_system_question ? ' style="visibility:hidden"' : '';
154
-                    $readonly   = $is_system_question ? ' readonly' : '';
155
-
156
-                    $edit_query_args    = $this->_adminpage_obj->is_caf()
157
-                        ? [
158
-                            'action' => 'edit_question_group',
159
-                            'QSG_ID' => $QSG_ID,
160
-                        ]
161
-                        : ['action' => 'question_groups'];
162
-                    $edit_link          = EE_Admin_Page::add_query_args_and_nonce(
163
-                        $edit_query_args,
164
-                        EE_FORMS_ADMIN_URL
165
-                    );
166
-                    $edit_link_title    = sprintf(
167
-                        esc_attr__('Edit %s Group', 'event_espresso'),
168
-                        $QSG->get('QSG_name')
169
-                    );
170
-
171
-                    $html .= '
130
+			$qsg_where['QSG_deleted'] = false;
131
+			$query_params             = apply_filters(
132
+				'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
133
+				[$qsg_where, 'order_by' => ['QSG_order' => 'ASC']]
134
+			);
135
+			$QSGs                     = EEM_Question_Group::instance()->get_all($query_params);
136
+			$EQGs                     = ! empty($event_id)
137
+				? $this->_event->get_many_related(
138
+					'Question_Group',
139
+					[['Event_Question_Group.EQG_primary' => true]]
140
+				)
141
+				: [];
142
+			$EQGids                   = array_keys($EQGs);
143
+
144
+			if (! empty($QSGs)) {
145
+				$html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
146
+				foreach ($QSGs as $QSG) {
147
+					$QSG_ID             = absint($QSG->ID());
148
+					$is_system_question = $QSG->get('QSG_system') === 1;
149
+					$checked            = $is_system_question || in_array($QSG_ID, $EQGids, true)
150
+						? ' checked'
151
+						: '';
152
+
153
+					$visibility = $is_system_question ? ' style="visibility:hidden"' : '';
154
+					$readonly   = $is_system_question ? ' readonly' : '';
155
+
156
+					$edit_query_args    = $this->_adminpage_obj->is_caf()
157
+						? [
158
+							'action' => 'edit_question_group',
159
+							'QSG_ID' => $QSG_ID,
160
+						]
161
+						: ['action' => 'question_groups'];
162
+					$edit_link          = EE_Admin_Page::add_query_args_and_nonce(
163
+						$edit_query_args,
164
+						EE_FORMS_ADMIN_URL
165
+					);
166
+					$edit_link_title    = sprintf(
167
+						esc_attr__('Edit %s Group', 'event_espresso'),
168
+						$QSG->get('QSG_name')
169
+					);
170
+
171
+					$html .= '
172 172
 					<p id="event-question-group-' . $QSG_ID . '">
173 173
 						<input value="' . $QSG_ID . '"
174 174
 						    type="checkbox"
175 175
 						    name="question_groups[' . $QSG_ID . ']"
176 176
                             aria-label="' . sprintf(esc_attr__('primary registrant %s questions'), $QSG->get('QSG_name')) . '" '
177
-                            . $visibility
178
-                            . $checked
179
-                            . $readonly
180
-                            . '
177
+							. $visibility
178
+							. $checked
179
+							. $readonly
180
+							. '
181 181
                         />
182 182
 						<a href="' . esc_url_raw($edit_link) . '"
183 183
 						    aria-label="' . esc_attr($edit_link_title) . '"
@@ -186,62 +186,62 @@  discard block
 block discarded – undo
186 186
 						    ' . $QSG->get('QSG_name') . '
187 187
                         </a>
188 188
 					</p>';
189
-                }
190
-                $html .= count($QSGs) > 10 ? '</div>' : '';
191
-                echo wp_kses($html, AllowedTags::getWithFormTags());
192
-            } else {
193
-                esc_html_e(
194
-                    'There seems to be a problem with your questions. Please contact [email protected]',
195
-                    'event_espresso'
196
-                );
197
-            }
198
-            do_action('AHEE_event_editor_questions_notice');
199
-            ?>
189
+				}
190
+				$html .= count($QSGs) > 10 ? '</div>' : '';
191
+				echo wp_kses($html, AllowedTags::getWithFormTags());
192
+			} else {
193
+				esc_html_e(
194
+					'There seems to be a problem with your questions. Please contact [email protected]',
195
+					'event_espresso'
196
+				);
197
+			}
198
+			do_action('AHEE_event_editor_questions_notice');
199
+			?>
200 200
         </div>
201 201
         <?php
202
-    }
203
-
204
-
205
-    /**
206
-     * @param EE_Event $event
207
-     * @param array    $data
208
-     * @return bool
209
-     * @throws EE_Error
210
-     * @throws ReflectionException
211
-     */
212
-    public function primary_question_group_update(EE_Event $event, array $data): bool
213
-    {
214
-        $question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : [];
215
-        $added_qgs       = array_keys($question_groups);
216
-        $success         = true;
217
-
218
-        // let's get all current question groups associated with this event.
219
-        $current_qgs = $event->get_many_related(
220
-            'Question_Group',
221
-            [['Event_Question_Group.EQG_primary' => true]]
222
-        );
223
-        $current_qgs = array_keys($current_qgs); // we just want the ids
224
-
225
-        // now let's get the groups selected in the editor and update (IF we have data)
226
-        if (! empty($question_groups)) {
227
-            foreach ($question_groups as $QSG_ID => $val) {
228
-                // add to event
229
-                if ($val) {
230
-                    $qg = $event->_add_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
231
-                }
232
-                // trip success to false if result is empty
233
-                $success = ! empty($qg) ? $success : false;
234
-            }
235
-        }
236
-
237
-        // wait a minute... are there question groups missing in the saved groups that ARE with the current event?
238
-        $removed_qgs = array_diff($current_qgs, $added_qgs);
239
-
240
-        foreach ($removed_qgs as $QSG_ID) {
241
-            $qg = $event->_remove_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
242
-            // trip success to false if result is empty
243
-            $success = ! empty($qg) ? $success : false;
244
-        }
245
-        return $success;
246
-    }
202
+	}
203
+
204
+
205
+	/**
206
+	 * @param EE_Event $event
207
+	 * @param array    $data
208
+	 * @return bool
209
+	 * @throws EE_Error
210
+	 * @throws ReflectionException
211
+	 */
212
+	public function primary_question_group_update(EE_Event $event, array $data): bool
213
+	{
214
+		$question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : [];
215
+		$added_qgs       = array_keys($question_groups);
216
+		$success         = true;
217
+
218
+		// let's get all current question groups associated with this event.
219
+		$current_qgs = $event->get_many_related(
220
+			'Question_Group',
221
+			[['Event_Question_Group.EQG_primary' => true]]
222
+		);
223
+		$current_qgs = array_keys($current_qgs); // we just want the ids
224
+
225
+		// now let's get the groups selected in the editor and update (IF we have data)
226
+		if (! empty($question_groups)) {
227
+			foreach ($question_groups as $QSG_ID => $val) {
228
+				// add to event
229
+				if ($val) {
230
+					$qg = $event->_add_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
231
+				}
232
+				// trip success to false if result is empty
233
+				$success = ! empty($qg) ? $success : false;
234
+			}
235
+		}
236
+
237
+		// wait a minute... are there question groups missing in the saved groups that ARE with the current event?
238
+		$removed_qgs = array_diff($current_qgs, $added_qgs);
239
+
240
+		foreach ($removed_qgs as $QSG_ID) {
241
+			$qg = $event->_remove_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
242
+			// trip success to false if result is empty
243
+			$success = ! empty($qg) ? $success : false;
244
+		}
245
+		return $success;
246
+	}
247 247
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -139,9 +139,9 @@  discard block
 block discarded – undo
139 139
                     [['Event_Question_Group.EQG_primary' => true]]
140 140
                 )
141 141
                 : [];
142
-            $EQGids                   = array_keys($EQGs);
142
+            $EQGids = array_keys($EQGs);
143 143
 
144
-            if (! empty($QSGs)) {
144
+            if ( ! empty($QSGs)) {
145 145
                 $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
146 146
                 foreach ($QSGs as $QSG) {
147 147
                     $QSG_ID             = absint($QSG->ID());
@@ -153,37 +153,37 @@  discard block
 block discarded – undo
153 153
                     $visibility = $is_system_question ? ' style="visibility:hidden"' : '';
154 154
                     $readonly   = $is_system_question ? ' readonly' : '';
155 155
 
156
-                    $edit_query_args    = $this->_adminpage_obj->is_caf()
156
+                    $edit_query_args = $this->_adminpage_obj->is_caf()
157 157
                         ? [
158 158
                             'action' => 'edit_question_group',
159 159
                             'QSG_ID' => $QSG_ID,
160 160
                         ]
161 161
                         : ['action' => 'question_groups'];
162
-                    $edit_link          = EE_Admin_Page::add_query_args_and_nonce(
162
+                    $edit_link = EE_Admin_Page::add_query_args_and_nonce(
163 163
                         $edit_query_args,
164 164
                         EE_FORMS_ADMIN_URL
165 165
                     );
166
-                    $edit_link_title    = sprintf(
166
+                    $edit_link_title = sprintf(
167 167
                         esc_attr__('Edit %s Group', 'event_espresso'),
168 168
                         $QSG->get('QSG_name')
169 169
                     );
170 170
 
171 171
                     $html .= '
172
-					<p id="event-question-group-' . $QSG_ID . '">
173
-						<input value="' . $QSG_ID . '"
172
+					<p id="event-question-group-' . $QSG_ID.'">
173
+						<input value="' . $QSG_ID.'"
174 174
 						    type="checkbox"
175
-						    name="question_groups[' . $QSG_ID . ']"
176
-                            aria-label="' . sprintf(esc_attr__('primary registrant %s questions'), $QSG->get('QSG_name')) . '" '
175
+						    name="question_groups[' . $QSG_ID.']"
176
+                            aria-label="' . sprintf(esc_attr__('primary registrant %s questions'), $QSG->get('QSG_name')).'" '
177 177
                             . $visibility
178 178
                             . $checked
179 179
                             . $readonly
180 180
                             . '
181 181
                         />
182
-						<a href="' . esc_url_raw($edit_link) . '"
183
-						    aria-label="' . esc_attr($edit_link_title) . '"
182
+						<a href="' . esc_url_raw($edit_link).'"
183
+						    aria-label="' . esc_attr($edit_link_title).'"
184 184
 						    target="_blank"
185 185
 						    >
186
-						    ' . $QSG->get('QSG_name') . '
186
+						    ' . $QSG->get('QSG_name').'
187 187
                         </a>
188 188
 					</p>';
189 189
                 }
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
         $current_qgs = array_keys($current_qgs); // we just want the ids
224 224
 
225 225
         // now let's get the groups selected in the editor and update (IF we have data)
226
-        if (! empty($question_groups)) {
226
+        if ( ! empty($question_groups)) {
227 227
             foreach ($question_groups as $QSG_ID => $val) {
228 228
                 // add to event
229 229
                 if ($val) {
Please login to merge, or discard this patch.
registration_form/templates/questions_main_meta_box.template.php 2 patches
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -12,25 +12,25 @@  discard block
 block discarded – undo
12 12
 
13 13
 // the following are already escaped
14 14
 echo wp_kses(
15
-    EEH_Form_Fields::hidden_input(
16
-        'QST_system',
17
-        $question->system_ID()
18
-    ),
19
-    AllowedTags::getWithFormTags()
15
+	EEH_Form_Fields::hidden_input(
16
+		'QST_system',
17
+		$question->system_ID()
18
+	),
19
+	AllowedTags::getWithFormTags()
20 20
 );
21 21
 echo wp_kses(
22
-    EEH_Form_Fields::hidden_input(
23
-        'QST_wp_user',
24
-        $question->wp_user()
25
-    ),
26
-    AllowedTags::getWithFormTags()
22
+	EEH_Form_Fields::hidden_input(
23
+		'QST_wp_user',
24
+		$question->wp_user()
25
+	),
26
+	AllowedTags::getWithFormTags()
27 27
 );
28 28
 echo wp_kses(
29
-    EEH_Form_Fields::hidden_input(
30
-        'QST_deleted',
31
-        $question->deleted()
32
-    ),
33
-    AllowedTags::getWithFormTags()
29
+	EEH_Form_Fields::hidden_input(
30
+		'QST_deleted',
31
+		$question->deleted()
32
+	),
33
+	AllowedTags::getWithFormTags()
34 34
 );
35 35
 
36 36
 $QST_system = $question->system_ID();
@@ -43,23 +43,23 @@  discard block
 block discarded – undo
43 43
 global $allowedposttags;
44 44
 $info_box = '';
45 45
 if ($QST_system === 'country') {
46
-    // already escaped
47
-    $info_box = EEH_HTML::div(
48
-        EEH_HTML::h3(
49
-            '<span class="dashicons dashicons-info"></span> '
50
-            . esc_html__('Did you know...', 'event_espresso'),
51
-            '',
52
-            'ee-status--info'
53
-        ) .
54
-        EEH_HTML::p(
55
-            esc_html__(
56
-                'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
57
-                'event_espresso'
58
-            )
59
-        ),
60
-        '',
61
-        'ee-info-box'
62
-    );
46
+	// already escaped
47
+	$info_box = EEH_HTML::div(
48
+		EEH_HTML::h3(
49
+			'<span class="dashicons dashicons-info"></span> '
50
+			. esc_html__('Did you know...', 'event_espresso'),
51
+			'',
52
+			'ee-status--info'
53
+		) .
54
+		EEH_HTML::p(
55
+			esc_html__(
56
+				'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
57
+				'event_espresso'
58
+			)
59
+		),
60
+		'',
61
+		'ee-info-box'
62
+	);
63 63
 }
64 64
 ?>
65 65
 
@@ -95,9 +95,9 @@  discard block
 block discarded – undo
95 95
                     </th>
96 96
                     <td>
97 97
                         <?php
98
-                        $id            = ! empty($QST_system) ? '_disabled' : '';
99
-                        $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
100
-                        ?>
98
+						$id            = ! empty($QST_system) ? '_disabled' : '';
99
+						$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
100
+						?>
101 101
                         <input id="QST_admin_label<?php echo esc_attr($id); ?>"
102 102
                                name="QST_admin_label<?php echo esc_attr($id); ?>"
103 103
                                type="text"
@@ -135,29 +135,29 @@  discard block
 block discarded – undo
135 135
                     </th>
136 136
                     <td>
137 137
                         <?php
138
-                        $id            = ! empty($QST_system) ? '_disabled' : '';
139
-                        $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
140
-                        $admin_only    = $question->get('QST_admin_only');
141
-                        $checked       = ! empty($admin_only) ? ' checked' : '';
142
-                        ?>
138
+						$id            = ! empty($QST_system) ? '_disabled' : '';
139
+						$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
140
+						$admin_only    = $question->get('QST_admin_only');
141
+						$checked       = ! empty($admin_only) ? ' checked' : '';
142
+						?>
143 143
                         <input class="QST_admin_only"
144 144
                                id="QST_admin_only<?php echo esc_attr($id); ?>"
145 145
                                name="QST_admin_only<?php echo esc_attr($id); ?>"
146 146
                                type="checkbox"
147 147
                                value="1"
148 148
                             <?php
149
-                            echo esc_attr($disabled_attr);
150
-                            echo esc_attr($checked);
151
-                            ?>
149
+							echo esc_attr($disabled_attr);
150
+							echo esc_attr($checked);
151
+							?>
152 152
                         />
153 153
                         <br />
154 154
                             <?php
155
-                            if (! empty($QST_system)) { ?>
155
+							if (! empty($QST_system)) { ?>
156 156
                                 <p class="description ee-system-question" >
157 157
                                     <?php esc_html_e(
158
-                                        'System question! This field cannot be changed.',
159
-                                        'event_espresso'
160
-                                    ); ?>
158
+										'System question! This field cannot be changed.',
159
+										'event_espresso'
160
+									); ?>
161 161
                                 </p>
162 162
                             <?php } ?>
163 163
                     </td>
@@ -172,47 +172,47 @@  discard block
 block discarded – undo
172 172
                     </th>
173 173
                     <td>
174 174
                         <?php
175
-                        $disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
176
-                        if ($disabled) {
177
-                            $disabled_attr = 'disabled="disabled"';
178
-                            $id            = '_disabled';
179
-                        } else {
180
-                            $disabled_attr = '';
181
-                            $id            = '';
182
-                        }
175
+						$disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
176
+						if ($disabled) {
177
+							$disabled_attr = 'disabled="disabled"';
178
+							$id            = '_disabled';
179
+						} else {
180
+							$disabled_attr = '';
181
+							$id            = '';
182
+						}
183 183
 
184
-                        // Only display Confirm email for
185
-                        if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
186
-                            unset($question_types[ EEM_Question::QST_type_email_confirm ]);
187
-                        }
184
+						// Only display Confirm email for
185
+						if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
186
+							unset($question_types[ EEM_Question::QST_type_email_confirm ]);
187
+						}
188 188
 
189
-                        echo wp_kses(
190
-                            EEH_Form_Fields::select_input(
191
-                                'QST_type' . $id,
192
-                                $question_types,
193
-                                $question->type(),
194
-                                'id="QST_type' . $id . '"' . $disabled_attr
195
-                            ),
196
-                            AllowedTags::getWithFormTags()
197
-                        );
198
-                        if ($disabled) { ?>
189
+						echo wp_kses(
190
+							EEH_Form_Fields::select_input(
191
+								'QST_type' . $id,
192
+								$question_types,
193
+								$question->type(),
194
+								'id="QST_type' . $id . '"' . $disabled_attr
195
+							),
196
+							AllowedTags::getWithFormTags()
197
+						);
198
+						if ($disabled) { ?>
199 199
                             <input id='QST_type'
200 200
                                    name="QST_type"
201 201
                                    type="hidden"
202 202
                                    value="<?php echo esc_attr($question->type()); ?>"
203 203
                             />
204 204
                             <?php
205
-                            $explanatory_text = esc_html__(
206
-                                'System question! This field cannot be changed.',
207
-                                'event_espresso'
208
-                            );
209
-                        } else {
210
-                            $explanatory_text = esc_html__(
211
-                                'Because there are currently answers for this question in the database, your options to change the question type have been limited to similar question-types.',
212
-                                'event_espresso'
213
-                            );
214
-                        }
215
-                        if ($disabled || $has_answers) { ?>
205
+							$explanatory_text = esc_html__(
206
+								'System question! This field cannot be changed.',
207
+								'event_espresso'
208
+							);
209
+						} else {
210
+							$explanatory_text = esc_html__(
211
+								'Because there are currently answers for this question in the database, your options to change the question type have been limited to similar question-types.',
212
+								'event_espresso'
213
+							);
214
+						}
215
+						if ($disabled || $has_answers) { ?>
216 216
                             <p class="description ee-system-question" >
217 217
                                     <?php echo esc_html($explanatory_text); ?>
218 218
                             </p>
@@ -241,19 +241,19 @@  discard block
 block discarded – undo
241 241
                         />
242 242
                         <p class="description">
243 243
                             <?php esc_html_e(
244
-                                'Maximum number of characters allowed when answering this question',
245
-                                'event_espresso'
246
-                            ); ?>
244
+								'Maximum number of characters allowed when answering this question',
245
+								'event_espresso'
246
+							); ?>
247 247
                         </p>
248 248
                         <?php if ($QST_system) { ?>
249 249
                         <p class="description ee-system-question" >
250 250
                             <?php printf(
251
-                                esc_html__(
252
-                                    'System question! The maximum number of characters that can be used for this question is %1$s',
253
-                                    'event_espresso'
254
-                                ),
255
-                                $max_max
256
-                            ); ?>
251
+								esc_html__(
252
+									'System question! The maximum number of characters that can be used for this question is %1$s',
253
+									'event_espresso'
254
+								),
255
+								$max_max
256
+							); ?>
257 257
                         </p>
258 258
                         <?php } ?>
259 259
                     </td>
@@ -277,9 +277,9 @@  discard block
 block discarded – undo
277 277
                                     <th class="option-desc-header">
278 278
                                         <label>
279 279
                                         <?php esc_html_e(
280
-                                            'Description (optional, only shown on registration form)',
281
-                                            'event_espresso'
282
-                                        ) ?>
280
+											'Description (optional, only shown on registration form)',
281
+											'event_espresso'
282
+										) ?>
283 283
                                         </label>
284 284
                                     </th>
285 285
                                     <th class="option-actions-header">
@@ -322,9 +322,9 @@  discard block
 block discarded – undo
322 322
                                         </a>
323 323
                                         <a class="button button--icon-only sortable-drag-handle ee-aria-tooltip"
324 324
                                             aria-label="<?php esc_html_e(
325
-                                                'click and drag to change the order of this option',
326
-                                                'event_espresso'
327
-                                            ) ?>"
325
+												'click and drag to change the order of this option',
326
+												'event_espresso'
327
+											) ?>"
328 328
                                         >
329 329
                                             <span class='dashicons dashicons-image-flip-vertical '></span>
330 330
                                         </a>
@@ -332,14 +332,14 @@  discard block
 block discarded – undo
332 332
                                 </tr>
333 333
 
334 334
                                 <?php
335
-                                $count            = 0;
336
-                                $question_options = $question->options();
337
-                                if (! empty($question_options)) {
338
-                                    foreach ($question_options as $option_id => $option) {
339
-                                        $disabled_attr = $has_answers || $option->get('QSO_system')
340
-                                            ? 'disabled'
341
-                                            : '';
342
-                                        ?>
335
+								$count            = 0;
336
+								$question_options = $question->options();
337
+								if (! empty($question_options)) {
338
+									foreach ($question_options as $option_id => $option) {
339
+										$disabled_attr = $has_answers || $option->get('QSO_system')
340
+											? 'disabled'
341
+											: '';
342
+										?>
343 343
                                         <tr class="question-option ee-options-sortable">
344 344
                                             <td class="option-value-cell">
345 345
                                                 <label class='screen-reader-text'
@@ -389,35 +389,35 @@  discard block
 block discarded – undo
389 389
                                             <?php } ?>
390 390
                                                 <a class='button button--icon-only sortable-drag-handle ee-aria-tooltip'
391 391
                                                    aria-label="<?php esc_html_e(
392
-                                                       'click and drag to change the order of this option',
393
-                                                       'event_espresso'
394
-                                                   ) ?>"
392
+													   'click and drag to change the order of this option',
393
+													   'event_espresso'
394
+												   ) ?>"
395 395
                                                 >
396 396
                                                     <span class='dashicons dashicons-image-flip-vertical '></span>
397 397
                                                 </a>
398 398
                                             <?php
399
-                                            echo wp_kses(
400
-                                                EEH_Form_Fields::hidden_input(
401
-                                                    "question_options[{$count}][QST_ID])",
402
-                                                    $option->question_ID()
403
-                                                ),
404
-                                                AllowedTags::getWithFormTags()
405
-                                            );
406
-                                            echo wp_kses(
407
-                                                EEH_Form_Fields::hidden_input(
408
-                                                    "question_options[{$count}][QSO_ID])",
409
-                                                    $option->ID()
410
-                                                ),
411
-                                                AllowedTags::getWithFormTags()
412
-                                            );
413
-                                            $count++;
414
-                                            ?>
399
+											echo wp_kses(
400
+												EEH_Form_Fields::hidden_input(
401
+													"question_options[{$count}][QST_ID])",
402
+													$option->question_ID()
403
+												),
404
+												AllowedTags::getWithFormTags()
405
+											);
406
+											echo wp_kses(
407
+												EEH_Form_Fields::hidden_input(
408
+													"question_options[{$count}][QSO_ID])",
409
+													$option->ID()
410
+												),
411
+												AllowedTags::getWithFormTags()
412
+											);
413
+											$count++;
414
+											?>
415 415
                                             </td>
416 416
                                         </tr>
417 417
                                         <?php
418
-                                    }
419
-                                } else {
420
-                                    ?>
418
+									}
419
+								} else {
420
+									?>
421 421
                                     <tr class="question-option ee-options-sortable">
422 422
                                         <td class="option-value-cell">
423 423
                                             <input type="text"
@@ -438,17 +438,17 @@  discard block
 block discarded – undo
438 438
                                         </td>
439 439
                                         <td class="option-actions-cell">
440 440
                                             <?php echo wp_kses(
441
-                                                EEH_Form_Fields::hidden_input(
442
-                                                    "question_options_count",
443
-                                                    $count
444
-                                                ),
445
-                                                AllowedTags::getWithFormTags()
446
-                                            ); ?>
441
+												EEH_Form_Fields::hidden_input(
442
+													"question_options_count",
443
+													$count
444
+												),
445
+												AllowedTags::getWithFormTags()
446
+											); ?>
447 447
                                         </td>
448 448
                                     </tr>
449 449
                                     <?php
450
-                                }
451
-                                ?>
450
+								}
451
+								?>
452 452
                             </tbody>
453 453
                         </table>
454 454
                         <div class="ee-admin-button-row">
@@ -456,27 +456,27 @@  discard block
 block discarded – undo
456 456
                                 <?php esc_html_e('Add Another Answer Option', 'event_espresso') ?>
457 457
                             </a>
458 458
                             <?php echo wp_kses(
459
-                                EEH_Form_Fields::hidden_input(
460
-                                    "question_options_count",
461
-                                    $count
462
-                                ),
463
-                                AllowedTags::getWithFormTags()
464
-                            ); ?>
459
+								EEH_Form_Fields::hidden_input(
460
+									"question_options_count",
461
+									$count
462
+								),
463
+								AllowedTags::getWithFormTags()
464
+							); ?>
465 465
                         </div>
466 466
                         <br />
467 467
 
468 468
                         <p class="description">
469 469
                             <?php esc_html_e(
470
-                                'Answer Options are the choices that you give people to select from for RADIO_BTN, CHECKBOX or DROPDOWN questions. The Value is a simple key that will be saved to the database and the description is optional. Note that values CANNOT contain any HTML, but descriptions can.',
471
-                                'event_espresso'
472
-                            ) ?>
470
+								'Answer Options are the choices that you give people to select from for RADIO_BTN, CHECKBOX or DROPDOWN questions. The Value is a simple key that will be saved to the database and the description is optional. Note that values CANNOT contain any HTML, but descriptions can.',
471
+								'event_espresso'
472
+							) ?>
473 473
                         </p>
474 474
                         <?php if ($has_answers) : ?>
475 475
                             <p class="description ee-system-question" >
476 476
                                 <?php esc_html_e(
477
-                                    'Answer values that are uneditable are this way because there are registrations in the database that have answers for this question.  If you need to correct a mistake, or edit an existing option value, then trash the existing one and create a new option with the changes.  This will ensure that the existing registrations that chose the original answer will preserve that answer.',
478
-                                    'event_espresso'
479
-                                ); ?>
477
+									'Answer values that are uneditable are this way because there are registrations in the database that have answers for this question.  If you need to correct a mistake, or edit an existing option value, then trash the existing one and create a new option with the changes.  This will ensure that the existing registrations that chose the original answer will preserve that answer.',
478
+									'event_espresso'
479
+								); ?>
480 480
                             </p>
481 481
                         <?php endif; ?>
482 482
                     </td>
@@ -491,41 +491,41 @@  discard block
 block discarded – undo
491 491
                     </th>
492 492
                     <td>
493 493
                         <?php
494
-                        $system_required   = ['fname', 'email'];
495
-                        $disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
496
-                        $required_on       = $question->get('QST_admin_only');
497
-                        $show_required_class = $admin_only && $required_on ? '' : ' hidden';
498
-                        $disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
499
-                        $id                =
500
-                            ! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
501
-                        $requiredOptions   = [
502
-                            ['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
503
-                            ['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
504
-                        ];
505
-                        echo wp_kses(
506
-                            EEH_Form_Fields::select_input(
507
-                                'QST_required' . $id,
508
-                                $requiredOptions,
509
-                                $question->required(),
510
-                                'id="QST_required' . $id . '"' . $disabled_attr,
511
-                                'ee-input-width--small'
512
-                            ),
513
-                            AllowedTags::getWithFormTags()
514
-                        );
515
-                        ?>
494
+						$system_required   = ['fname', 'email'];
495
+						$disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
496
+						$required_on       = $question->get('QST_admin_only');
497
+						$show_required_class = $admin_only && $required_on ? '' : ' hidden';
498
+						$disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
499
+						$id                =
500
+							! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
501
+						$requiredOptions   = [
502
+							['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
503
+							['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
504
+						];
505
+						echo wp_kses(
506
+							EEH_Form_Fields::select_input(
507
+								'QST_required' . $id,
508
+								$requiredOptions,
509
+								$question->required(),
510
+								'id="QST_required' . $id . '"' . $disabled_attr,
511
+								'ee-input-width--small'
512
+							),
513
+							AllowedTags::getWithFormTags()
514
+						);
515
+						?>
516 516
                         <p id="required_toggled_on"
517 517
                            class="description<?php echo esc_attr($show_required_class); ?>"
518 518
                         >
519 519
                             <?php esc_html_e(
520
-                                'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
521
-                                'event_espresso'
522
-                            ) ?>
520
+								'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
521
+								'event_espresso'
522
+							) ?>
523 523
                         </p>
524 524
                         <p id="required_toggled_off" class="description ee-system-question" style="color:#D54E21; display: none;">
525 525
                                 <?php esc_html_e(
526
-                                    'Required option field is no longer disabled because the question is not Admin-Only',
527
-                                    'event_espresso'
528
-                                ) ?>
526
+									'Required option field is no longer disabled because the question is not Admin-Only',
527
+									'event_espresso'
528
+								) ?>
529 529
                         </p>
530 530
                         <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
531 531
                             <input id="QST_required"
@@ -559,8 +559,8 @@  discard block
 block discarded – undo
559 559
                     </td>
560 560
                 </tr>
561 561
                 <?php
562
-                do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
563
-                ?>
562
+				do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
563
+				?>
564 564
             </tbody>
565 565
         </table>
566 566
 
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
             . esc_html__('Did you know...', 'event_espresso'),
51 51
             '',
52 52
             'ee-status--info'
53
-        ) .
53
+        ).
54 54
         EEH_HTML::p(
55 55
             esc_html__(
56 56
                 'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
                                value="<?php echo esc_attr($question->get_f('QST_admin_label')); ?>"
105 105
                                <?php echo esc_attr($disabled_attr); ?>
106 106
                         />
107
-                        <?php if (! empty($QST_system)) { ?>
107
+                        <?php if ( ! empty($QST_system)) { ?>
108 108
                             <input id='QST_admin_label'
109 109
                                    name="QST_admin_label"
110 110
                                    type="hidden"
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
                             />
113 113
                         <?php } ?>
114 114
                         <br />
115
-                        <?php if (! empty($QST_system)) { ?>
115
+                        <?php if ( ! empty($QST_system)) { ?>
116 116
                             <p class="description ee-system-question" >
117 117
                                 <?php esc_html_e('System question! This field cannot be changed.', 'event_espresso') ?>
118 118
                             </p>
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
                         />
153 153
                         <br />
154 154
                             <?php
155
-                            if (! empty($QST_system)) { ?>
155
+                            if ( ! empty($QST_system)) { ?>
156 156
                                 <p class="description ee-system-question" >
157 157
                                     <?php esc_html_e(
158 158
                                         'System question! This field cannot be changed.',
@@ -183,15 +183,15 @@  discard block
 block discarded – undo
183 183
 
184 184
                         // Only display Confirm email for
185 185
                         if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
186
-                            unset($question_types[ EEM_Question::QST_type_email_confirm ]);
186
+                            unset($question_types[EEM_Question::QST_type_email_confirm]);
187 187
                         }
188 188
 
189 189
                         echo wp_kses(
190 190
                             EEH_Form_Fields::select_input(
191
-                                'QST_type' . $id,
191
+                                'QST_type'.$id,
192 192
                                 $question_types,
193 193
                                 $question->type(),
194
-                                'id="QST_type' . $id . '"' . $disabled_attr
194
+                                'id="QST_type'.$id.'"'.$disabled_attr
195 195
                             ),
196 196
                             AllowedTags::getWithFormTags()
197 197
                         );
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
                         <input id="QST_max"
233 233
                             class="ee-input-width--small"
234 234
                         <?php if ($max_max !== EE_INF) :?>
235
-                            max="<?php echo esc_attr($max_max);?>"
235
+                            max="<?php echo esc_attr($max_max); ?>"
236 236
                         <?php  endif; ?>
237 237
                             min="1"
238 238
                             name="QST_max"
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
                                 <?php
335 335
                                 $count            = 0;
336 336
                                 $question_options = $question->options();
337
-                                if (! empty($question_options)) {
337
+                                if ( ! empty($question_options)) {
338 338
                                     foreach ($question_options as $option_id => $option) {
339 339
                                         $disabled_attr = $has_answers || $option->get('QSO_system')
340 340
                                             ? 'disabled'
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
                                                 />
381 381
                                             </td>
382 382
                                             <td class="option-actions-cell">
383
-                                            <?php if (! $option->system()) { ?>
383
+                                            <?php if ( ! $option->system()) { ?>
384 384
                                                 <a class='button button--icon-only remove-option remove-item ee-aria-tooltip'
385 385
                                                    aria-label="<?php esc_html_e('click to delete this option', 'event_espresso') ?>"
386 386
                                                 >
@@ -504,10 +504,10 @@  discard block
 block discarded – undo
504 504
                         ];
505 505
                         echo wp_kses(
506 506
                             EEH_Form_Fields::select_input(
507
-                                'QST_required' . $id,
507
+                                'QST_required'.$id,
508 508
                                 $requiredOptions,
509 509
                                 $question->required(),
510
-                                'id="QST_required' . $id . '"' . $disabled_attr,
510
+                                'id="QST_required'.$id.'"'.$disabled_attr,
511 511
                                 'ee-input-width--small'
512 512
                             ),
513 513
                             AllowedTags::getWithFormTags()
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
                                     'event_espresso'
528 528
                                 ) ?>
529 529
                         </p>
530
-                        <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
530
+                        <?php if ( ! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
531 531
                             <input id="QST_required"
532 532
                                    name="QST_required"
533 533
                                    type='hidden'
Please login to merge, or discard this patch.
admin_pages/general_settings/General_Settings_Admin_Page.core.php 1 patch
Indentation   +1450 added lines, -1450 removed lines patch added patch discarded remove patch
@@ -22,1467 +22,1467 @@
 block discarded – undo
22 22
  */
23 23
 class General_Settings_Admin_Page extends EE_Admin_Page
24 24
 {
25
-    /**
26
-     * @var EE_Core_Config
27
-     */
28
-    public $core_config;
29
-
30
-
31
-    /**
32
-     * Initialize basic properties.
33
-     */
34
-    protected function _init_page_props()
35
-    {
36
-        $this->page_slug        = GEN_SET_PG_SLUG;
37
-        $this->page_label       = GEN_SET_LABEL;
38
-        $this->_admin_base_url  = GEN_SET_ADMIN_URL;
39
-        $this->_admin_base_path = GEN_SET_ADMIN;
40
-
41
-        $this->core_config = EE_Registry::instance()->CFG->core;
42
-    }
43
-
44
-
45
-    /**
46
-     * Set ajax hooks
47
-     */
48
-    protected function _ajax_hooks()
49
-    {
50
-        add_action('wp_ajax_espresso_display_country_settings', [$this, 'display_country_settings']);
51
-        add_action('wp_ajax_espresso_display_country_states', [$this, 'display_country_states']);
52
-        add_action('wp_ajax_espresso_delete_state', [$this, 'delete_state'], 10, 3);
53
-        add_action('wp_ajax_espresso_add_new_state', [$this, 'add_new_state']);
54
-    }
55
-
56
-
57
-    /**
58
-     * More page properties initialization.
59
-     */
60
-    protected function _define_page_props()
61
-    {
62
-        $this->_admin_page_title = GEN_SET_LABEL;
63
-        $this->_labels           = ['publishbox' => esc_html__('Update Settings', 'event_espresso')];
64
-    }
65
-
66
-
67
-    /**
68
-     * Set page routes property.
69
-     */
70
-    protected function _set_page_routes()
71
-    {
72
-        $this->_page_routes = [
73
-            'critical_pages'                => [
74
-                'func'       => [$this, '_espresso_page_settings'],
75
-                'capability' => 'manage_options',
76
-            ],
77
-            'update_espresso_page_settings' => [
78
-                'func'       => [$this, '_update_espresso_page_settings'],
79
-                'capability' => 'manage_options',
80
-                'noheader'   => true,
81
-            ],
82
-            'default'                       => [
83
-                'func'       => [$this, '_your_organization_settings'],
84
-                'capability' => 'manage_options',
85
-            ],
86
-
87
-            'update_your_organization_settings' => [
88
-                'func'       => [$this, '_update_your_organization_settings'],
89
-                'capability' => 'manage_options',
90
-                'noheader'   => true,
91
-            ],
92
-
93
-            'admin_option_settings' => [
94
-                'func'       => [$this, '_admin_option_settings'],
95
-                'capability' => 'manage_options',
96
-            ],
97
-
98
-            'update_admin_option_settings' => [
99
-                'func'       => [$this, '_update_admin_option_settings'],
100
-                'capability' => 'manage_options',
101
-                'noheader'   => true,
102
-            ],
103
-
104
-            'country_settings' => [
105
-                'func'       => [$this, '_country_settings'],
106
-                'capability' => 'manage_options',
107
-            ],
108
-
109
-            'update_country_settings' => [
110
-                'func'       => [$this, '_update_country_settings'],
111
-                'capability' => 'manage_options',
112
-                'noheader'   => true,
113
-            ],
114
-
115
-            'display_country_settings' => [
116
-                'func'       => [$this, 'display_country_settings'],
117
-                'capability' => 'manage_options',
118
-                'noheader'   => true,
119
-            ],
120
-
121
-            'add_new_state' => [
122
-                'func'       => [$this, 'add_new_state'],
123
-                'capability' => 'manage_options',
124
-                'noheader'   => true,
125
-            ],
126
-
127
-            'delete_state'            => [
128
-                'func'       => [$this, 'delete_state'],
129
-                'capability' => 'manage_options',
130
-                'noheader'   => true,
131
-            ],
132
-
133
-            'privacy_settings'        => [
134
-                'func'       => [$this, 'privacySettings'],
135
-                'capability' => 'manage_options',
136
-            ],
137
-
138
-            'update_privacy_settings' => [
139
-                'func'               => [$this, 'updatePrivacySettings'],
140
-                'capability'         => 'manage_options',
141
-                'noheader'           => true,
142
-                'headers_sent_route' => 'privacy_settings',
143
-            ],
144
-
145
-            'set_font_size'            => [
146
-                'func'       => [$this, 'setFontSize'],
147
-                'noheader'   => true,
148
-            ],
149
-        ];
150
-    }
151
-
152
-
153
-    /**
154
-     * Set page configuration property
155
-     */
156
-    protected function _set_page_config()
157
-    {
158
-        $this->_page_config = [
159
-            'critical_pages'        => [
160
-                'nav'           => [
161
-                    'label' => esc_html__('Critical Pages', 'event_espresso'),
162
-                    'icon' => 'dashicons-warning',
163
-                    'order' => 50,
164
-                ],
165
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
166
-                'help_tabs'     => [
167
-                    'general_settings_critical_pages_help_tab' => [
168
-                        'title'    => esc_html__('Critical Pages', 'event_espresso'),
169
-                        'filename' => 'general_settings_critical_pages',
170
-                    ],
171
-                ],
172
-                'require_nonce' => false,
173
-            ],
174
-            'default'               => [
175
-                'nav'           => [
176
-                    'label' => esc_html__('Your Organization', 'event_espresso'),
177
-                    'icon' => 'dashicons-admin-home',
178
-                    'order' => 20,
179
-                ],
180
-                'help_tabs'     => [
181
-                    'general_settings_your_organization_help_tab' => [
182
-                        'title'    => esc_html__('Your Organization', 'event_espresso'),
183
-                        'filename' => 'general_settings_your_organization',
184
-                    ],
185
-                ],
186
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
187
-                'require_nonce' => false,
188
-            ],
189
-            'admin_option_settings' => [
190
-                'nav'           => [
191
-                    'label' => esc_html__('Admin Options', 'event_espresso'),
192
-                    'icon' => 'dashicons-admin-settings',
193
-                    'order' => 60,
194
-                ],
195
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
196
-                'help_tabs'     => [
197
-                    'general_settings_admin_options_help_tab' => [
198
-                        'title'    => esc_html__('Admin Options', 'event_espresso'),
199
-                        'filename' => 'general_settings_admin_options',
200
-                    ],
201
-                ],
202
-                'require_nonce' => false,
203
-            ],
204
-            'country_settings'      => [
205
-                'nav'           => [
206
-                    'label' => esc_html__('Countries', 'event_espresso'),
207
-                    'icon' => 'dashicons-admin-site',
208
-                    'order' => 70,
209
-                ],
210
-                'help_tabs'     => [
211
-                    'general_settings_countries_help_tab' => [
212
-                        'title'    => esc_html__('Countries', 'event_espresso'),
213
-                        'filename' => 'general_settings_countries',
214
-                    ],
215
-                ],
216
-                'require_nonce' => false,
217
-            ],
218
-            'privacy_settings'      => [
219
-                'nav'           => [
220
-                    'label' => esc_html__('Privacy', 'event_espresso'),
221
-                    'icon' => 'dashicons-privacy',
222
-                    'order' => 80,
223
-                ],
224
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
225
-                'require_nonce' => false,
226
-            ],
227
-        ];
228
-    }
229
-
230
-
231
-    protected function _add_screen_options()
232
-    {
233
-    }
234
-
235
-
236
-    protected function _add_feature_pointers()
237
-    {
238
-    }
239
-
240
-
241
-    /**
242
-     * Enqueue global scripts and styles for all routes in the General Settings Admin Pages.
243
-     */
244
-    public function load_scripts_styles()
245
-    {
246
-        // styles
247
-        wp_enqueue_style('espresso-ui-theme');
248
-        // scripts
249
-        wp_enqueue_script('ee_admin_js');
250
-    }
251
-
252
-
253
-    /**
254
-     * Execute logic running on `admin_init`
255
-     */
256
-    public function admin_init()
257
-    {
258
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = wp_strip_all_tags(
259
-            esc_html__(
260
-                'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
261
-                'event_espresso'
262
-            )
263
-        );
264
-        EE_Registry::$i18n_js_strings['error_occurred']          = wp_strip_all_tags(
265
-            esc_html__(
266
-                'An error occurred! Please refresh the page and try again.',
267
-                'event_espresso'
268
-            )
269
-        );
270
-        EE_Registry::$i18n_js_strings['confirm_delete_state']    = wp_strip_all_tags(
271
-            esc_html__(
272
-                'Are you sure you want to delete this State / Province?',
273
-                'event_espresso'
274
-            )
275
-        );
276
-        EE_Registry::$i18n_js_strings['ajax_url']                = admin_url(
277
-            'admin-ajax.php?page=espresso_general_settings',
278
-            is_ssl() ? 'https://' : 'http://'
279
-        );
280
-    }
281
-
282
-
283
-    public function admin_notices()
284
-    {
285
-    }
286
-
287
-
288
-    public function admin_footer_scripts()
289
-    {
290
-    }
291
-
292
-
293
-    /**
294
-     * Enqueue scripts and styles for the default route.
295
-     */
296
-    public function load_scripts_styles_default()
297
-    {
298
-        // styles
299
-        wp_enqueue_style('thickbox');
300
-        // scripts
301
-        wp_enqueue_script('media-upload');
302
-        wp_enqueue_script('thickbox');
303
-        wp_register_script(
304
-            'organization_settings',
305
-            GEN_SET_ASSETS_URL . 'your_organization_settings.js',
306
-            ['jquery', 'media-upload', 'thickbox'],
307
-            EVENT_ESPRESSO_VERSION,
308
-            true
309
-        );
310
-        wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', [], EVENT_ESPRESSO_VERSION);
311
-        wp_enqueue_script('organization_settings');
312
-        wp_enqueue_style('organization-css');
313
-        $confirm_image_delete = [
314
-            'text' => wp_strip_all_tags(
315
-                esc_html__(
316
-                    'Do you really want to delete this image? Please remember to save your settings to complete the removal.',
317
-                    'event_espresso'
318
-                )
319
-            ),
320
-        ];
321
-        wp_localize_script('organization_settings', 'confirm_image_delete', $confirm_image_delete);
322
-    }
323
-
324
-
325
-    /**
326
-     * Enqueue scripts and styles for the country settings route.
327
-     */
328
-    public function load_scripts_styles_country_settings()
329
-    {
330
-        // scripts
331
-        wp_register_script(
332
-            'gen_settings_countries',
333
-            GEN_SET_ASSETS_URL . 'gen_settings_countries.js',
334
-            ['ee_admin_js'],
335
-            EVENT_ESPRESSO_VERSION,
336
-            true
337
-        );
338
-        wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', [], EVENT_ESPRESSO_VERSION);
339
-        wp_enqueue_script('gen_settings_countries');
340
-        wp_enqueue_style('organization-css');
341
-    }
342
-
343
-
344
-    /*************        Espresso Pages        *************/
345
-    /**
346
-     * _espresso_page_settings
347
-     *
348
-     * @throws EE_Error
349
-     * @throws DomainException
350
-     * @throws DomainException
351
-     * @throws InvalidDataTypeException
352
-     * @throws InvalidArgumentException
353
-     */
354
-    protected function _espresso_page_settings()
355
-    {
356
-        // Check to make sure all of the main pages are set up properly,
357
-        // if not create the default pages and display an admin notice
358
-        EEH_Activation::verify_default_pages_exist();
359
-        $this->_transient_garbage_collection();
360
-
361
-        $this->_template_args['values'] = $this->_yes_no_values;
362
-
363
-        $this->_template_args['reg_page_id']  = $this->core_config->reg_page_id ?? null;
364
-        $this->_template_args['reg_page_obj'] = isset($this->core_config->reg_page_id)
365
-            ? get_post($this->core_config->reg_page_id)
366
-            : false;
367
-
368
-        $this->_template_args['txn_page_id']  = $this->core_config->txn_page_id ?? null;
369
-        $this->_template_args['txn_page_obj'] = isset($this->core_config->txn_page_id)
370
-            ? get_post($this->core_config->txn_page_id)
371
-            : false;
372
-
373
-        $this->_template_args['thank_you_page_id']  = $this->core_config->thank_you_page_id ?? null;
374
-        $this->_template_args['thank_you_page_obj'] = isset($this->core_config->thank_you_page_id)
375
-            ? get_post($this->core_config->thank_you_page_id)
376
-            : false;
377
-
378
-        $this->_template_args['cancel_page_id']  = $this->core_config->cancel_page_id ?? null;
379
-        $this->_template_args['cancel_page_obj'] = isset($this->core_config->cancel_page_id)
380
-            ? get_post($this->core_config->cancel_page_id)
381
-            : false;
382
-
383
-        $this->_set_add_edit_form_tags('update_espresso_page_settings');
384
-        $this->_set_publish_post_box_vars();
385
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
386
-            GEN_SET_TEMPLATE_PATH . 'espresso_page_settings.template.php',
387
-            $this->_template_args,
388
-            true
389
-        );
390
-        $this->display_admin_page_with_sidebar();
391
-    }
392
-
393
-
394
-    /**
395
-     * Handler for updating espresso page settings.
396
-     *
397
-     * @throws EE_Error
398
-     */
399
-    protected function _update_espresso_page_settings()
400
-    {
401
-        $this->core_config = EE_Registry::instance()->CFG->core;
402
-        // capture incoming request data && set page IDs
403
-        $this->core_config->reg_page_id       = $this->request->getRequestParam(
404
-            'reg_page_id',
405
-            $this->core_config->reg_page_id,
406
-            DataType::INT
407
-        );
408
-        $this->core_config->txn_page_id       = $this->request->getRequestParam(
409
-            'txn_page_id',
410
-            $this->core_config->txn_page_id,
411
-            DataType::INT
412
-        );
413
-        $this->core_config->thank_you_page_id = $this->request->getRequestParam(
414
-            'thank_you_page_id',
415
-            $this->core_config->thank_you_page_id,
416
-            DataType::INT
417
-        );
418
-        $this->core_config->cancel_page_id    = $this->request->getRequestParam(
419
-            'cancel_page_id',
420
-            $this->core_config->cancel_page_id,
421
-            DataType::INT
422
-        );
423
-
424
-        $this->core_config = apply_filters(
425
-            'FHEE__General_Settings_Admin_Page___update_espresso_page_settings__CFG_core',
426
-            $this->core_config,
427
-            $this->request->requestParams()
428
-        );
429
-
430
-        $what = esc_html__('Critical Pages & Shortcodes', 'event_espresso');
431
-        $this->_redirect_after_action(
432
-            $this->_update_espresso_configuration(
433
-                $what,
434
-                $this->core_config,
435
-                __FILE__,
436
-                __FUNCTION__,
437
-                __LINE__
438
-            ),
439
-            $what,
440
-            '',
441
-            [
442
-                'action' => 'critical_pages',
443
-            ],
444
-            true
445
-        );
446
-    }
447
-
448
-
449
-    /*************        Your Organization        *************/
450
-
451
-
452
-    /**
453
-     * @throws DomainException
454
-     * @throws EE_Error
455
-     * @throws InvalidArgumentException
456
-     * @throws InvalidDataTypeException
457
-     * @throws InvalidInterfaceException
458
-     */
459
-    protected function _your_organization_settings()
460
-    {
461
-        $this->_template_args['admin_page_content'] = '';
462
-        try {
463
-            /** @var OrganizationSettings $organization_settings_form */
464
-            $organization_settings_form = $this->loader->getShared(OrganizationSettings::class);
465
-
466
-            $this->_template_args['admin_page_content'] = EEH_HTML::div(
467
-                $organization_settings_form->display(),
468
-                '',
469
-                'padding'
470
-            );
471
-        } catch (Exception $e) {
472
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
473
-        }
474
-        $this->_set_add_edit_form_tags('update_your_organization_settings');
475
-        $this->_set_publish_post_box_vars();
476
-        $this->display_admin_page_with_sidebar();
477
-    }
478
-
479
-
480
-    /**
481
-     * Handler for updating organization settings.
482
-     *
483
-     * @throws EE_Error
484
-     */
485
-    protected function _update_your_organization_settings()
486
-    {
487
-        try {
488
-            /** @var OrganizationSettings $organization_settings_form */
489
-            $organization_settings_form = $this->loader->getShared(OrganizationSettings::class);
490
-
491
-            $success = $organization_settings_form->process($this->request->requestParams());
492
-
493
-            EE_Registry::instance()->CFG = apply_filters(
494
-                'FHEE__General_Settings_Admin_Page___update_your_organization_settings__CFG',
495
-                EE_Registry::instance()->CFG
496
-            );
497
-        } catch (Exception $e) {
498
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
499
-            $success = false;
500
-        }
501
-
502
-        if ($success) {
503
-            $success = $this->_update_espresso_configuration(
504
-                esc_html__('Your Organization Settings', 'event_espresso'),
505
-                EE_Registry::instance()->CFG,
506
-                __FILE__,
507
-                __FUNCTION__,
508
-                __LINE__
509
-            );
510
-        }
511
-
512
-        $this->_redirect_after_action($success, '', '', ['action' => 'default'], true);
513
-    }
514
-
515
-
516
-
517
-    /*************        Admin Options        *************/
518
-
519
-
520
-    /**
521
-     * _admin_option_settings
522
-     *
523
-     * @throws EE_Error
524
-     * @throws LogicException
525
-     */
526
-    protected function _admin_option_settings()
527
-    {
528
-        $this->_template_args['admin_page_content'] = '';
529
-        try {
530
-            $admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
531
-            // still need this for the old school form in Extend_General_Settings_Admin_Page
532
-            $this->_template_args['values'] = $this->_yes_no_values;
533
-            // also need to account for the do_action that was in the old template
534
-            $admin_options_settings_form->setTemplateArgs($this->_template_args);
535
-            $this->_template_args['admin_page_content'] = EEH_HTML::div(
536
-                $admin_options_settings_form->display(),
537
-                '',
538
-                'padding'
539
-            );
540
-        } catch (Exception $e) {
541
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
542
-        }
543
-        $this->_set_add_edit_form_tags('update_admin_option_settings');
544
-        $this->_set_publish_post_box_vars();
545
-        $this->display_admin_page_with_sidebar();
546
-    }
547
-
548
-
549
-    /**
550
-     * _update_admin_option_settings
551
-     *
552
-     * @throws EE_Error
553
-     * @throws InvalidDataTypeException
554
-     * @throws InvalidFormSubmissionException
555
-     * @throws InvalidArgumentException
556
-     * @throws LogicException
557
-     */
558
-    protected function _update_admin_option_settings()
559
-    {
560
-        try {
561
-            $admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
562
-            $admin_options_settings_form->process(
563
-                $this->request->getRequestParam(
564
-                    $admin_options_settings_form->slug(),
565
-                    [],
566
-                    DataType::STRING,
567
-                    true
568
-                )
569
-            );
570
-            EE_Registry::instance()->CFG->admin = apply_filters(
571
-                'FHEE__General_Settings_Admin_Page___update_admin_option_settings__CFG_admin',
572
-                EE_Registry::instance()->CFG->admin
573
-            );
574
-        } catch (Exception $e) {
575
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
576
-        }
577
-        $this->_redirect_after_action(
578
-            apply_filters(
579
-                'FHEE__General_Settings_Admin_Page___update_admin_option_settings__success',
580
-                $this->_update_espresso_configuration(
581
-                    esc_html__('Admin Options', 'event_espresso'),
582
-                    EE_Registry::instance()->CFG->admin,
583
-                    __FILE__,
584
-                    __FUNCTION__,
585
-                    __LINE__
586
-                )
587
-            ),
588
-            esc_html__('Admin Options', 'event_espresso'),
589
-            'updated',
590
-            ['action' => 'admin_option_settings']
591
-        );
592
-    }
593
-
594
-
595
-    /*************        Countries        *************/
596
-
597
-
598
-    /**
599
-     * @param string|null $default
600
-     * @return string
601
-     */
602
-    protected function getCountryISO(?string $default = null): string
603
-    {
604
-        $default = $default ?? $this->getCountryIsoForSite();
605
-        $CNT_ISO = $this->request->getRequestParam('country', $default);
606
-        $CNT_ISO = $this->request->getRequestParam('CNT_ISO', $CNT_ISO);
607
-        return strtoupper($CNT_ISO);
608
-    }
609
-
610
-
611
-    /**
612
-     * @return string
613
-     */
614
-    protected function getCountryIsoForSite(): string
615
-    {
616
-        return ! empty(EE_Registry::instance()->CFG->organization->CNT_ISO)
617
-            ? EE_Registry::instance()->CFG->organization->CNT_ISO
618
-            : 'US';
619
-    }
620
-
621
-
622
-    /**
623
-     * @param string          $CNT_ISO
624
-     * @param EE_Country|null $country
625
-     * @return EE_Base_Class|EE_Country
626
-     * @throws EE_Error
627
-     * @throws InvalidArgumentException
628
-     * @throws InvalidDataTypeException
629
-     * @throws InvalidInterfaceException
630
-     * @throws ReflectionException
631
-     */
632
-    protected function verifyOrGetCountryFromIso(string $CNT_ISO, ?EE_Country $country = null)
633
-    {
634
-        /** @var EE_Country $country */
635
-        return $country instanceof EE_Country && $country->ID() === $CNT_ISO
636
-            ? $country
637
-            : EEM_Country::instance()->get_one_by_ID($CNT_ISO);
638
-    }
639
-
640
-
641
-    /**
642
-     * Output Country Settings view.
643
-     *
644
-     * @throws DomainException
645
-     * @throws EE_Error
646
-     * @throws InvalidArgumentException
647
-     * @throws InvalidDataTypeException
648
-     * @throws InvalidInterfaceException
649
-     * @throws ReflectionException
650
-     */
651
-    protected function _country_settings()
652
-    {
653
-        $CNT_ISO = $this->getCountryISO();
654
-
655
-        $this->_template_args['values']    = $this->_yes_no_values;
656
-        $this->_template_args['countries'] = new EE_Question_Form_Input(
657
-            EE_Question::new_instance(
658
-                [
659
-                  'QST_ID'           => 0,
660
-                  'QST_display_text' => esc_html__('Select Country', 'event_espresso'),
661
-                  'QST_system'       => 'admin-country',
662
-                ]
663
-            ),
664
-            EE_Answer::new_instance(
665
-                [
666
-                    'ANS_ID'    => 0,
667
-                    'ANS_value' => $CNT_ISO,
668
-                ]
669
-            ),
670
-            [
671
-                'input_id'       => 'country',
672
-                'input_name'     => 'country',
673
-                'input_prefix'   => '',
674
-                'append_qstn_id' => false,
675
-            ]
676
-        );
677
-
678
-        $country = $this->verifyOrGetCountryFromIso($CNT_ISO);
679
-        add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'country_form_field_label_wrap'], 10);
680
-        add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'country_form_field_input__wrap'], 10);
681
-        $this->_template_args['country_details_settings'] = $this->display_country_settings(
682
-            $country->ID(),
683
-            $country
684
-        );
685
-        $this->_template_args['country_states_settings']  = $this->display_country_states(
686
-            $country->ID(),
687
-            $country
688
-        );
689
-        $this->_template_args['CNT_name_for_site']        = $country->name();
690
-
691
-        $this->_set_add_edit_form_tags('update_country_settings');
692
-        $this->_set_publish_post_box_vars();
693
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
694
-            GEN_SET_TEMPLATE_PATH . 'countries_settings.template.php',
695
-            $this->_template_args,
696
-            true
697
-        );
698
-        $this->display_admin_page_with_no_sidebar();
699
-    }
700
-
701
-
702
-    /**
703
-     * @param string          $CNT_ISO
704
-     * @param EE_Country|null $country
705
-     * @return string
706
-     * @throws DomainException
707
-     * @throws EE_Error
708
-     * @throws InvalidArgumentException
709
-     * @throws InvalidDataTypeException
710
-     * @throws InvalidInterfaceException
711
-     * @throws ReflectionException
712
-     */
713
-    public function display_country_settings(string $CNT_ISO = '', ?EE_Country $country = null): string
714
-    {
715
-        $CNT_ISO          = $this->getCountryISO($CNT_ISO);
716
-        $CNT_ISO_for_site = $this->getCountryIsoForSite();
717
-
718
-        if (! $CNT_ISO) {
719
-            return '';
720
-        }
721
-
722
-        // for ajax
723
-        remove_all_filters('FHEE__EEH_Form_Fields__label_html');
724
-        remove_all_filters('FHEE__EEH_Form_Fields__input_html');
725
-        add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'country_form_field_label_wrap'], 10, 2);
726
-        add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'country_form_field_input__wrap'], 10, 2);
727
-        $country                                  = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
728
-        $CNT_cur_disabled                         = $CNT_ISO !== $CNT_ISO_for_site;
729
-        $this->_template_args['CNT_cur_disabled'] = $CNT_cur_disabled;
730
-
731
-        $country_input_types            = [
732
-            'CNT_active'      => [
733
-                'type'             => 'RADIO_BTN',
734
-                'input_name'       => "cntry[$CNT_ISO]",
735
-                'class'            => '',
736
-                'options'          => $this->_yes_no_values,
737
-                'use_desc_4_label' => true,
738
-            ],
739
-            'CNT_ISO'         => [
740
-                'type'       => 'TEXT',
741
-                'input_name' => "cntry[$CNT_ISO]",
742
-                'class'      => 'ee-input-width--small',
743
-            ],
744
-            'CNT_ISO3'        => [
745
-                'type'       => 'TEXT',
746
-                'input_name' => "cntry[$CNT_ISO]",
747
-                'class'      => 'ee-input-width--small',
748
-            ],
749
-            // 'RGN_ID'          => [
750
-            //     'type'       => 'TEXT',
751
-            //     'input_name' => "cntry[$CNT_ISO]",
752
-            //     'class'      => 'ee-input-width--small',
753
-            // ],
754
-            'CNT_name'        => [
755
-                'type'       => 'TEXT',
756
-                'input_name' => "cntry[$CNT_ISO]",
757
-                'class'      => 'ee-input-width--big',
758
-            ],
759
-            'CNT_cur_code'    => [
760
-                'type'       => 'TEXT',
761
-                'input_name' => "cntry[$CNT_ISO]",
762
-                'class'      => 'ee-input-width--small',
763
-                'disabled'   => $CNT_cur_disabled,
764
-            ],
765
-            'CNT_cur_single'  => [
766
-                'type'       => 'TEXT',
767
-                'input_name' => "cntry[$CNT_ISO]",
768
-                'class'      => 'ee-input-width--reg',
769
-                'disabled'   => $CNT_cur_disabled,
770
-            ],
771
-            'CNT_cur_plural'  => [
772
-                'type'       => 'TEXT',
773
-                'input_name' => "cntry[$CNT_ISO]",
774
-                'class'      => 'ee-input-width--reg',
775
-                'disabled'   => $CNT_cur_disabled,
776
-            ],
777
-            'CNT_cur_sign'    => [
778
-                'type'         => 'TEXT',
779
-                'input_name'   => "cntry[$CNT_ISO]",
780
-                'class'        => 'ee-input-width--small',
781
-                'htmlentities' => false,
782
-                'disabled'     => $CNT_cur_disabled,
783
-            ],
784
-            'CNT_cur_sign_b4' => [
785
-                'type'             => 'RADIO_BTN',
786
-                'input_name'       => "cntry[$CNT_ISO]",
787
-                'class'            => '',
788
-                'options'          => $this->_yes_no_values,
789
-                'use_desc_4_label' => true,
790
-                'disabled'         => $CNT_cur_disabled,
791
-            ],
792
-            'CNT_cur_dec_plc' => [
793
-                'type'       => 'RADIO_BTN',
794
-                'input_name' => "cntry[$CNT_ISO]",
795
-                'class'      => '',
796
-                'options'    => [
797
-                    ['id' => 0, 'text' => ''],
798
-                    ['id' => 1, 'text' => ''],
799
-                    ['id' => 2, 'text' => ''],
800
-                    ['id' => 3, 'text' => ''],
801
-                ],
802
-                'disabled'   => $CNT_cur_disabled,
803
-            ],
804
-            'CNT_cur_dec_mrk' => [
805
-                'type'             => 'RADIO_BTN',
806
-                'input_name'       => "cntry[$CNT_ISO]",
807
-                'class'            => '',
808
-                'options'          => [
809
-                    [
810
-                        'id'   => ',',
811
-                        'text' => esc_html__(', (comma)', 'event_espresso'),
812
-                    ],
813
-                    ['id' => '.', 'text' => esc_html__('. (decimal)', 'event_espresso')],
814
-                ],
815
-                'use_desc_4_label' => true,
816
-                'disabled'         => $CNT_cur_disabled,
817
-            ],
818
-            'CNT_cur_thsnds'  => [
819
-                'type'             => 'RADIO_BTN',
820
-                'input_name'       => "cntry[$CNT_ISO]",
821
-                'class'            => '',
822
-                'options'          => [
823
-                    [
824
-                        'id'   => ',',
825
-                        'text' => esc_html__(', (comma)', 'event_espresso'),
826
-                    ],
827
-                    [
828
-                        'id'   => '.',
829
-                        'text' => esc_html__('. (decimal)', 'event_espresso'),
830
-                    ],
831
-                    [
832
-                        'id'   => '&nbsp;',
833
-                        'text' => esc_html__('(space)', 'event_espresso'),
834
-                    ],
835
-                    [
836
-                        'id'   => '_',
837
-                        'text' => esc_html__('_ (underscore)', 'event_espresso'),
838
-                    ],
839
-                    [
840
-                        'id'   => "'",
841
-                        'text' => esc_html__("' (apostrophe)", 'event_espresso'),
842
-                    ],
843
-                    [
844
-                        'id'   => "",
845
-                        'text' => esc_html__(" (nothing)", 'event_espresso'),
846
-                    ],
847
-                ],
848
-                'use_desc_4_label' => true,
849
-                'disabled'         => $CNT_cur_disabled,
850
-            ],
851
-            'CNT_tel_code'    => [
852
-                'type'       => 'TEXT',
853
-                'input_name' => "cntry[$CNT_ISO]",
854
-                'class'      => 'ee-input-width--small',
855
-            ],
856
-            'CNT_is_EU'       => [
857
-                'type'             => 'RADIO_BTN',
858
-                'input_name'       => "cntry[$CNT_ISO]",
859
-                'class'            => '',
860
-                'options'          => $this->_yes_no_values,
861
-                'use_desc_4_label' => true,
862
-            ],
863
-        ];
864
-        $this->_template_args['inputs'] = EE_Question_Form_Input::generate_question_form_inputs_for_object(
865
-            $country,
866
-            $country_input_types
867
-        );
868
-        $country_details_settings       = EEH_Template::display_template(
869
-            GEN_SET_TEMPLATE_PATH . 'country_details_settings.template.php',
870
-            $this->_template_args,
871
-            true
872
-        );
873
-
874
-        if (defined('DOING_AJAX')) {
875
-            $notices = EE_Error::get_notices(false, false, false);
876
-            echo wp_json_encode(
877
-                [
878
-                    'return_data' => $country_details_settings,
879
-                    'success'     => $notices['success'],
880
-                    'errors'      => $notices['errors'],
881
-                ]
882
-            );
883
-            die();
884
-        }
885
-        return $country_details_settings;
886
-    }
887
-
888
-
889
-    /**
890
-     * @param string          $CNT_ISO
891
-     * @param EE_Country|null $country
892
-     * @return string
893
-     * @throws DomainException
894
-     * @throws EE_Error
895
-     * @throws InvalidArgumentException
896
-     * @throws InvalidDataTypeException
897
-     * @throws InvalidInterfaceException
898
-     * @throws ReflectionException
899
-     */
900
-    public function display_country_states(string $CNT_ISO = '', ?EE_Country $country = null): string
901
-    {
902
-        $CNT_ISO = $this->getCountryISO($CNT_ISO);
903
-        if (! $CNT_ISO) {
904
-            return '';
905
-        }
906
-        // for ajax
907
-        remove_all_filters('FHEE__EEH_Form_Fields__label_html');
908
-        remove_all_filters('FHEE__EEH_Form_Fields__input_html');
909
-        add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'state_form_field_label_wrap'], 10, 2);
910
-        add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'state_form_field_input__wrap'], 10);
911
-        $states = EEM_State::instance()->get_all_states_for_these_countries([$CNT_ISO => $CNT_ISO]);
912
-        if (empty($states)) {
913
-            /** @var EventEspresso\core\services\address\CountrySubRegionDao $countrySubRegionDao */
914
-            $countrySubRegionDao = $this->loader->getShared(
915
-                'EventEspresso\core\services\address\CountrySubRegionDao'
916
-            );
917
-            if ($countrySubRegionDao instanceof EventEspresso\core\services\address\CountrySubRegionDao) {
918
-                $country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
919
-                if ($countrySubRegionDao->saveCountrySubRegions($country)) {
920
-                    $states = EEM_State::instance()->get_all_states_for_these_countries([$CNT_ISO => $CNT_ISO]);
921
-                }
922
-            }
923
-        }
924
-        if (is_array($states)) {
925
-            foreach ($states as $STA_ID => $state) {
926
-                if ($state instanceof EE_State) {
927
-                    $inputs = EE_Question_Form_Input::generate_question_form_inputs_for_object(
928
-                        $state,
929
-                        [
930
-                            'STA_abbrev' => [
931
-                                'type'             => 'TEXT',
932
-                                'label'            => esc_html__('Code', 'event_espresso'),
933
-                                'input_name'       => "states[$STA_ID]",
934
-                                'class'            => 'ee-input-width--tiny',
935
-                                'add_mobile_label' => true,
936
-                            ],
937
-                            'STA_name'   => [
938
-                                'type'             => 'TEXT',
939
-                                'label'            => esc_html__('Name', 'event_espresso'),
940
-                                'input_name'       => "states[$STA_ID]",
941
-                                'class'            => 'ee-input-width--big',
942
-                                'add_mobile_label' => true,
943
-                            ],
944
-                            'STA_active' => [
945
-                                'type'             => 'RADIO_BTN',
946
-                                'label'            => esc_html__(
947
-                                    'State Appears in Dropdown Select Lists',
948
-                                    'event_espresso'
949
-                                ),
950
-                                'input_name'       => "states[$STA_ID]",
951
-                                'options'          => $this->_yes_no_values,
952
-                                'use_desc_4_label' => true,
953
-                                'add_mobile_label' => true,
954
-                            ],
955
-                        ]
956
-                    );
957
-
958
-                    $delete_state_url = EE_Admin_Page::add_query_args_and_nonce(
959
-                        [
960
-                            'action'     => 'delete_state',
961
-                            'STA_ID'     => $STA_ID,
962
-                            'CNT_ISO'    => $CNT_ISO,
963
-                            'STA_abbrev' => $state->abbrev(),
964
-                        ],
965
-                        GEN_SET_ADMIN_URL
966
-                    );
967
-
968
-                    $this->_template_args['states'][ $STA_ID ]['inputs']           = $inputs;
969
-                    $this->_template_args['states'][ $STA_ID ]['delete_state_url'] = $delete_state_url;
970
-                }
971
-            }
972
-        } else {
973
-            $this->_template_args['states'] = false;
974
-        }
975
-
976
-        $this->_template_args['add_new_state_url'] = EE_Admin_Page::add_query_args_and_nonce(
977
-            ['action' => 'add_new_state'],
978
-            GEN_SET_ADMIN_URL
979
-        );
980
-
981
-        $state_details_settings = EEH_Template::display_template(
982
-            GEN_SET_TEMPLATE_PATH . 'state_details_settings.template.php',
983
-            $this->_template_args,
984
-            true
985
-        );
986
-
987
-        if (defined('DOING_AJAX')) {
988
-            $notices = EE_Error::get_notices(false, false, false);
989
-            echo wp_json_encode(
990
-                [
991
-                    'return_data' => $state_details_settings,
992
-                    'success'     => $notices['success'],
993
-                    'errors'      => $notices['errors'],
994
-                ]
995
-            );
996
-            die();
997
-        }
998
-        return $state_details_settings;
999
-    }
1000
-
1001
-
1002
-    /**
1003
-     * @return void
1004
-     * @throws EE_Error
1005
-     * @throws InvalidArgumentException
1006
-     * @throws InvalidDataTypeException
1007
-     * @throws InvalidInterfaceException
1008
-     * @throws ReflectionException
1009
-     */
1010
-    public function add_new_state()
1011
-    {
1012
-        $success = true;
1013
-        $CNT_ISO = $this->getCountryISO('');
1014
-        if (! $CNT_ISO) {
1015
-            EE_Error::add_error(
1016
-                esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1017
-                __FILE__,
1018
-                __FUNCTION__,
1019
-                __LINE__
1020
-            );
1021
-            $success = false;
1022
-        }
1023
-        $STA_abbrev = $this->request->getRequestParam('STA_abbrev');
1024
-        if (! $STA_abbrev) {
1025
-            EE_Error::add_error(
1026
-                esc_html__('No State ISO code or an invalid State ISO code was received.', 'event_espresso'),
1027
-                __FILE__,
1028
-                __FUNCTION__,
1029
-                __LINE__
1030
-            );
1031
-            $success = false;
1032
-        }
1033
-        $STA_name = $this->request->getRequestParam('STA_name');
1034
-        if (! $STA_name) {
1035
-            EE_Error::add_error(
1036
-                esc_html__('No State name or an invalid State name was received.', 'event_espresso'),
1037
-                __FILE__,
1038
-                __FUNCTION__,
1039
-                __LINE__
1040
-            );
1041
-            $success = false;
1042
-        }
1043
-
1044
-        if ($success) {
1045
-            $cols_n_values = [
1046
-                'CNT_ISO'    => $CNT_ISO,
1047
-                'STA_abbrev' => $STA_abbrev,
1048
-                'STA_name'   => $STA_name,
1049
-                'STA_active' => true,
1050
-            ];
1051
-            $success       = EEM_State::instance()->insert($cols_n_values);
1052
-            EE_Error::add_success(esc_html__('The State was added successfully.', 'event_espresso'));
1053
-        }
1054
-
1055
-        if (defined('DOING_AJAX')) {
1056
-            $notices = EE_Error::get_notices(false, false, false);
1057
-            echo wp_json_encode(array_merge($notices, ['return_data' => $CNT_ISO]));
1058
-            die();
1059
-        }
1060
-        $this->_redirect_after_action(
1061
-            $success,
1062
-            esc_html__('State', 'event_espresso'),
1063
-            'added',
1064
-            ['action' => 'country_settings']
1065
-        );
1066
-    }
1067
-
1068
-
1069
-    /**
1070
-     * @return void
1071
-     * @throws EE_Error
1072
-     * @throws InvalidArgumentException
1073
-     * @throws InvalidDataTypeException
1074
-     * @throws InvalidInterfaceException
1075
-     * @throws ReflectionException
1076
-     */
1077
-    public function delete_state()
1078
-    {
1079
-        $CNT_ISO    = $this->getCountryISO();
1080
-        $STA_ID     = $this->request->getRequestParam('STA_ID');
1081
-        $STA_abbrev = $this->request->getRequestParam('STA_abbrev');
1082
-
1083
-        if (! $STA_ID) {
1084
-            EE_Error::add_error(
1085
-                esc_html__('No State ID or an invalid State ID was received.', 'event_espresso'),
1086
-                __FILE__,
1087
-                __FUNCTION__,
1088
-                __LINE__
1089
-            );
1090
-            return;
1091
-        }
1092
-
1093
-        $success = EEM_State::instance()->delete_by_ID($STA_ID);
1094
-        if ($success !== false) {
1095
-            do_action(
1096
-                'AHEE__General_Settings_Admin_Page__delete_state__state_deleted',
1097
-                $CNT_ISO,
1098
-                $STA_ID,
1099
-                ['STA_abbrev' => $STA_abbrev]
1100
-            );
1101
-            EE_Error::add_success(esc_html__('The State was deleted successfully.', 'event_espresso'));
1102
-        }
1103
-        if (defined('DOING_AJAX')) {
1104
-            $notices                = EE_Error::get_notices(false);
1105
-            $notices['return_data'] = true;
1106
-            echo wp_json_encode($notices);
1107
-            die();
1108
-        }
1109
-        $this->_redirect_after_action(
1110
-            $success,
1111
-            esc_html__('State', 'event_espresso'),
1112
-            'deleted',
1113
-            ['action' => 'country_settings']
1114
-        );
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * @return void
1120
-     * @throws EE_Error
1121
-     * @throws InvalidArgumentException
1122
-     * @throws InvalidDataTypeException
1123
-     * @throws InvalidInterfaceException
1124
-     * @throws ReflectionException
1125
-     */
1126
-    protected function _update_country_settings()
1127
-    {
1128
-        $CNT_ISO = $this->getCountryISO();
1129
-        if (! $CNT_ISO) {
1130
-            EE_Error::add_error(
1131
-                esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1132
-                __FILE__,
1133
-                __FUNCTION__,
1134
-                __LINE__
1135
-            );
1136
-            return;
1137
-        }
1138
-
1139
-        $country = $this->verifyOrGetCountryFromIso($CNT_ISO);
1140
-
1141
-        $cols_n_values                    = [];
1142
-        $cols_n_values['CNT_ISO3']        = strtoupper(
1143
-            $this->request->getRequestParam(
1144
-                "cntry[$CNT_ISO][CNT_ISO3]",
1145
-                $country->ISO3()
1146
-            )
1147
-        );
1148
-        $cols_n_values['CNT_name']        = $this->request->getRequestParam(
1149
-            "cntry[$CNT_ISO][CNT_name]",
1150
-            $country->name()
1151
-        );
1152
-        $cols_n_values['CNT_cur_code']    = strtoupper(
1153
-            $this->request->getRequestParam(
1154
-                "cntry[$CNT_ISO][CNT_cur_code]",
1155
-                $country->currency_code()
1156
-            )
1157
-        );
1158
-        $cols_n_values['CNT_cur_single']  = $this->request->getRequestParam(
1159
-            "cntry[$CNT_ISO][CNT_cur_single]",
1160
-            $country->currency_name_single()
1161
-        );
1162
-        $cols_n_values['CNT_cur_plural']  = $this->request->getRequestParam(
1163
-            "cntry[$CNT_ISO][CNT_cur_plural]",
1164
-            $country->currency_name_plural()
1165
-        );
1166
-        $cols_n_values['CNT_cur_sign']    = $this->request->getRequestParam(
1167
-            "cntry[$CNT_ISO][CNT_cur_sign]",
1168
-            $country->currency_sign()
1169
-        );
1170
-        $cols_n_values['CNT_cur_sign_b4'] = $this->request->getRequestParam(
1171
-            "cntry[$CNT_ISO][CNT_cur_sign_b4]",
1172
-            $country->currency_sign_before(),
1173
-            DataType::BOOL
1174
-        );
1175
-        $cols_n_values['CNT_cur_dec_plc'] = $this->request->getRequestParam(
1176
-            "cntry[$CNT_ISO][CNT_cur_dec_plc]",
1177
-            $country->currency_decimal_places()
1178
-        );
1179
-        $cols_n_values['CNT_cur_dec_mrk'] = $this->request->getRequestParam(
1180
-            "cntry[$CNT_ISO][CNT_cur_dec_mrk]",
1181
-            $country->currency_decimal_mark()
1182
-        );
1183
-        $cols_n_values['CNT_cur_thsnds']  = $this->request->getRequestParam(
1184
-            "cntry[$CNT_ISO][CNT_cur_thsnds]",
1185
-            $country->currency_thousands_separator()
1186
-        );
1187
-        $cols_n_values['CNT_tel_code']    = $this->request->getRequestParam(
1188
-            "cntry[$CNT_ISO][CNT_tel_code]",
1189
-            $country->telephoneCode()
1190
-        );
1191
-        $cols_n_values['CNT_active']      = $this->request->getRequestParam(
1192
-            "cntry[$CNT_ISO][CNT_active]",
1193
-            $country->isActive(),
1194
-            DataType::BOOL
1195
-        );
1196
-
1197
-        // allow filtering of country data
1198
-        $cols_n_values = apply_filters(
1199
-            'FHEE__General_Settings_Admin_Page___update_country_settings__cols_n_values',
1200
-            $cols_n_values
1201
-        );
1202
-
1203
-        // where values
1204
-        $where_cols_n_values = [['CNT_ISO' => $CNT_ISO]];
1205
-        // run the update
1206
-        $success = EEM_Country::instance()->update($cols_n_values, $where_cols_n_values);
1207
-
1208
-        // allow filtering of states data
1209
-        $states = apply_filters(
1210
-            'FHEE__General_Settings_Admin_Page___update_country_settings__states',
1211
-            $this->request->getRequestParam('states', [], DataType::STRING, true)
1212
-        );
1213
-
1214
-        if (! empty($states) && $success !== false) {
1215
-            // loop thru state data ( looks like : states[75][STA_name] )
1216
-            foreach ($states as $STA_ID => $state) {
1217
-                $cols_n_values = [
1218
-                    'CNT_ISO'    => $CNT_ISO,
1219
-                    'STA_abbrev' => sanitize_text_field($state['STA_abbrev']),
1220
-                    'STA_name'   => sanitize_text_field($state['STA_name']),
1221
-                    'STA_active' => filter_var($state['STA_active'], FILTER_VALIDATE_BOOLEAN),
1222
-                ];
1223
-                // where values
1224
-                $where_cols_n_values = [['STA_ID' => $STA_ID]];
1225
-                // run the update
1226
-                $success = EEM_State::instance()->update($cols_n_values, $where_cols_n_values);
1227
-                if ($success !== false) {
1228
-                    do_action(
1229
-                        'AHEE__General_Settings_Admin_Page__update_country_settings__state_saved',
1230
-                        $CNT_ISO,
1231
-                        $STA_ID,
1232
-                        $cols_n_values
1233
-                    );
1234
-                }
1235
-            }
1236
-        }
1237
-        // check if country being edited matches org option country, and if so, then  update EE_Config with new settings
1238
-        if (
1239
-            isset(EE_Registry::instance()->CFG->organization->CNT_ISO)
1240
-            && $CNT_ISO == EE_Registry::instance()->CFG->organization->CNT_ISO
1241
-        ) {
1242
-            EE_Registry::instance()->CFG->currency = new EE_Currency_Config($CNT_ISO);
1243
-            EE_Registry::instance()->CFG->update_espresso_config();
1244
-        }
1245
-
1246
-        if ($success !== false) {
1247
-            EE_Error::add_success(
1248
-                esc_html__('Country Settings updated successfully.', 'event_espresso')
1249
-            );
1250
-        }
1251
-        $this->_redirect_after_action(
1252
-            $success,
1253
-            '',
1254
-            '',
1255
-            ['action' => 'country_settings', 'country' => $CNT_ISO],
1256
-            true
1257
-        );
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * form_form_field_label_wrap
1263
-     *
1264
-     * @param string $label
1265
-     * @return string
1266
-     */
1267
-    public function country_form_field_label_wrap(string $label): string
1268
-    {
1269
-        return '
25
+	/**
26
+	 * @var EE_Core_Config
27
+	 */
28
+	public $core_config;
29
+
30
+
31
+	/**
32
+	 * Initialize basic properties.
33
+	 */
34
+	protected function _init_page_props()
35
+	{
36
+		$this->page_slug        = GEN_SET_PG_SLUG;
37
+		$this->page_label       = GEN_SET_LABEL;
38
+		$this->_admin_base_url  = GEN_SET_ADMIN_URL;
39
+		$this->_admin_base_path = GEN_SET_ADMIN;
40
+
41
+		$this->core_config = EE_Registry::instance()->CFG->core;
42
+	}
43
+
44
+
45
+	/**
46
+	 * Set ajax hooks
47
+	 */
48
+	protected function _ajax_hooks()
49
+	{
50
+		add_action('wp_ajax_espresso_display_country_settings', [$this, 'display_country_settings']);
51
+		add_action('wp_ajax_espresso_display_country_states', [$this, 'display_country_states']);
52
+		add_action('wp_ajax_espresso_delete_state', [$this, 'delete_state'], 10, 3);
53
+		add_action('wp_ajax_espresso_add_new_state', [$this, 'add_new_state']);
54
+	}
55
+
56
+
57
+	/**
58
+	 * More page properties initialization.
59
+	 */
60
+	protected function _define_page_props()
61
+	{
62
+		$this->_admin_page_title = GEN_SET_LABEL;
63
+		$this->_labels           = ['publishbox' => esc_html__('Update Settings', 'event_espresso')];
64
+	}
65
+
66
+
67
+	/**
68
+	 * Set page routes property.
69
+	 */
70
+	protected function _set_page_routes()
71
+	{
72
+		$this->_page_routes = [
73
+			'critical_pages'                => [
74
+				'func'       => [$this, '_espresso_page_settings'],
75
+				'capability' => 'manage_options',
76
+			],
77
+			'update_espresso_page_settings' => [
78
+				'func'       => [$this, '_update_espresso_page_settings'],
79
+				'capability' => 'manage_options',
80
+				'noheader'   => true,
81
+			],
82
+			'default'                       => [
83
+				'func'       => [$this, '_your_organization_settings'],
84
+				'capability' => 'manage_options',
85
+			],
86
+
87
+			'update_your_organization_settings' => [
88
+				'func'       => [$this, '_update_your_organization_settings'],
89
+				'capability' => 'manage_options',
90
+				'noheader'   => true,
91
+			],
92
+
93
+			'admin_option_settings' => [
94
+				'func'       => [$this, '_admin_option_settings'],
95
+				'capability' => 'manage_options',
96
+			],
97
+
98
+			'update_admin_option_settings' => [
99
+				'func'       => [$this, '_update_admin_option_settings'],
100
+				'capability' => 'manage_options',
101
+				'noheader'   => true,
102
+			],
103
+
104
+			'country_settings' => [
105
+				'func'       => [$this, '_country_settings'],
106
+				'capability' => 'manage_options',
107
+			],
108
+
109
+			'update_country_settings' => [
110
+				'func'       => [$this, '_update_country_settings'],
111
+				'capability' => 'manage_options',
112
+				'noheader'   => true,
113
+			],
114
+
115
+			'display_country_settings' => [
116
+				'func'       => [$this, 'display_country_settings'],
117
+				'capability' => 'manage_options',
118
+				'noheader'   => true,
119
+			],
120
+
121
+			'add_new_state' => [
122
+				'func'       => [$this, 'add_new_state'],
123
+				'capability' => 'manage_options',
124
+				'noheader'   => true,
125
+			],
126
+
127
+			'delete_state'            => [
128
+				'func'       => [$this, 'delete_state'],
129
+				'capability' => 'manage_options',
130
+				'noheader'   => true,
131
+			],
132
+
133
+			'privacy_settings'        => [
134
+				'func'       => [$this, 'privacySettings'],
135
+				'capability' => 'manage_options',
136
+			],
137
+
138
+			'update_privacy_settings' => [
139
+				'func'               => [$this, 'updatePrivacySettings'],
140
+				'capability'         => 'manage_options',
141
+				'noheader'           => true,
142
+				'headers_sent_route' => 'privacy_settings',
143
+			],
144
+
145
+			'set_font_size'            => [
146
+				'func'       => [$this, 'setFontSize'],
147
+				'noheader'   => true,
148
+			],
149
+		];
150
+	}
151
+
152
+
153
+	/**
154
+	 * Set page configuration property
155
+	 */
156
+	protected function _set_page_config()
157
+	{
158
+		$this->_page_config = [
159
+			'critical_pages'        => [
160
+				'nav'           => [
161
+					'label' => esc_html__('Critical Pages', 'event_espresso'),
162
+					'icon' => 'dashicons-warning',
163
+					'order' => 50,
164
+				],
165
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
166
+				'help_tabs'     => [
167
+					'general_settings_critical_pages_help_tab' => [
168
+						'title'    => esc_html__('Critical Pages', 'event_espresso'),
169
+						'filename' => 'general_settings_critical_pages',
170
+					],
171
+				],
172
+				'require_nonce' => false,
173
+			],
174
+			'default'               => [
175
+				'nav'           => [
176
+					'label' => esc_html__('Your Organization', 'event_espresso'),
177
+					'icon' => 'dashicons-admin-home',
178
+					'order' => 20,
179
+				],
180
+				'help_tabs'     => [
181
+					'general_settings_your_organization_help_tab' => [
182
+						'title'    => esc_html__('Your Organization', 'event_espresso'),
183
+						'filename' => 'general_settings_your_organization',
184
+					],
185
+				],
186
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
187
+				'require_nonce' => false,
188
+			],
189
+			'admin_option_settings' => [
190
+				'nav'           => [
191
+					'label' => esc_html__('Admin Options', 'event_espresso'),
192
+					'icon' => 'dashicons-admin-settings',
193
+					'order' => 60,
194
+				],
195
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
196
+				'help_tabs'     => [
197
+					'general_settings_admin_options_help_tab' => [
198
+						'title'    => esc_html__('Admin Options', 'event_espresso'),
199
+						'filename' => 'general_settings_admin_options',
200
+					],
201
+				],
202
+				'require_nonce' => false,
203
+			],
204
+			'country_settings'      => [
205
+				'nav'           => [
206
+					'label' => esc_html__('Countries', 'event_espresso'),
207
+					'icon' => 'dashicons-admin-site',
208
+					'order' => 70,
209
+				],
210
+				'help_tabs'     => [
211
+					'general_settings_countries_help_tab' => [
212
+						'title'    => esc_html__('Countries', 'event_espresso'),
213
+						'filename' => 'general_settings_countries',
214
+					],
215
+				],
216
+				'require_nonce' => false,
217
+			],
218
+			'privacy_settings'      => [
219
+				'nav'           => [
220
+					'label' => esc_html__('Privacy', 'event_espresso'),
221
+					'icon' => 'dashicons-privacy',
222
+					'order' => 80,
223
+				],
224
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
225
+				'require_nonce' => false,
226
+			],
227
+		];
228
+	}
229
+
230
+
231
+	protected function _add_screen_options()
232
+	{
233
+	}
234
+
235
+
236
+	protected function _add_feature_pointers()
237
+	{
238
+	}
239
+
240
+
241
+	/**
242
+	 * Enqueue global scripts and styles for all routes in the General Settings Admin Pages.
243
+	 */
244
+	public function load_scripts_styles()
245
+	{
246
+		// styles
247
+		wp_enqueue_style('espresso-ui-theme');
248
+		// scripts
249
+		wp_enqueue_script('ee_admin_js');
250
+	}
251
+
252
+
253
+	/**
254
+	 * Execute logic running on `admin_init`
255
+	 */
256
+	public function admin_init()
257
+	{
258
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = wp_strip_all_tags(
259
+			esc_html__(
260
+				'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
261
+				'event_espresso'
262
+			)
263
+		);
264
+		EE_Registry::$i18n_js_strings['error_occurred']          = wp_strip_all_tags(
265
+			esc_html__(
266
+				'An error occurred! Please refresh the page and try again.',
267
+				'event_espresso'
268
+			)
269
+		);
270
+		EE_Registry::$i18n_js_strings['confirm_delete_state']    = wp_strip_all_tags(
271
+			esc_html__(
272
+				'Are you sure you want to delete this State / Province?',
273
+				'event_espresso'
274
+			)
275
+		);
276
+		EE_Registry::$i18n_js_strings['ajax_url']                = admin_url(
277
+			'admin-ajax.php?page=espresso_general_settings',
278
+			is_ssl() ? 'https://' : 'http://'
279
+		);
280
+	}
281
+
282
+
283
+	public function admin_notices()
284
+	{
285
+	}
286
+
287
+
288
+	public function admin_footer_scripts()
289
+	{
290
+	}
291
+
292
+
293
+	/**
294
+	 * Enqueue scripts and styles for the default route.
295
+	 */
296
+	public function load_scripts_styles_default()
297
+	{
298
+		// styles
299
+		wp_enqueue_style('thickbox');
300
+		// scripts
301
+		wp_enqueue_script('media-upload');
302
+		wp_enqueue_script('thickbox');
303
+		wp_register_script(
304
+			'organization_settings',
305
+			GEN_SET_ASSETS_URL . 'your_organization_settings.js',
306
+			['jquery', 'media-upload', 'thickbox'],
307
+			EVENT_ESPRESSO_VERSION,
308
+			true
309
+		);
310
+		wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', [], EVENT_ESPRESSO_VERSION);
311
+		wp_enqueue_script('organization_settings');
312
+		wp_enqueue_style('organization-css');
313
+		$confirm_image_delete = [
314
+			'text' => wp_strip_all_tags(
315
+				esc_html__(
316
+					'Do you really want to delete this image? Please remember to save your settings to complete the removal.',
317
+					'event_espresso'
318
+				)
319
+			),
320
+		];
321
+		wp_localize_script('organization_settings', 'confirm_image_delete', $confirm_image_delete);
322
+	}
323
+
324
+
325
+	/**
326
+	 * Enqueue scripts and styles for the country settings route.
327
+	 */
328
+	public function load_scripts_styles_country_settings()
329
+	{
330
+		// scripts
331
+		wp_register_script(
332
+			'gen_settings_countries',
333
+			GEN_SET_ASSETS_URL . 'gen_settings_countries.js',
334
+			['ee_admin_js'],
335
+			EVENT_ESPRESSO_VERSION,
336
+			true
337
+		);
338
+		wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', [], EVENT_ESPRESSO_VERSION);
339
+		wp_enqueue_script('gen_settings_countries');
340
+		wp_enqueue_style('organization-css');
341
+	}
342
+
343
+
344
+	/*************        Espresso Pages        *************/
345
+	/**
346
+	 * _espresso_page_settings
347
+	 *
348
+	 * @throws EE_Error
349
+	 * @throws DomainException
350
+	 * @throws DomainException
351
+	 * @throws InvalidDataTypeException
352
+	 * @throws InvalidArgumentException
353
+	 */
354
+	protected function _espresso_page_settings()
355
+	{
356
+		// Check to make sure all of the main pages are set up properly,
357
+		// if not create the default pages and display an admin notice
358
+		EEH_Activation::verify_default_pages_exist();
359
+		$this->_transient_garbage_collection();
360
+
361
+		$this->_template_args['values'] = $this->_yes_no_values;
362
+
363
+		$this->_template_args['reg_page_id']  = $this->core_config->reg_page_id ?? null;
364
+		$this->_template_args['reg_page_obj'] = isset($this->core_config->reg_page_id)
365
+			? get_post($this->core_config->reg_page_id)
366
+			: false;
367
+
368
+		$this->_template_args['txn_page_id']  = $this->core_config->txn_page_id ?? null;
369
+		$this->_template_args['txn_page_obj'] = isset($this->core_config->txn_page_id)
370
+			? get_post($this->core_config->txn_page_id)
371
+			: false;
372
+
373
+		$this->_template_args['thank_you_page_id']  = $this->core_config->thank_you_page_id ?? null;
374
+		$this->_template_args['thank_you_page_obj'] = isset($this->core_config->thank_you_page_id)
375
+			? get_post($this->core_config->thank_you_page_id)
376
+			: false;
377
+
378
+		$this->_template_args['cancel_page_id']  = $this->core_config->cancel_page_id ?? null;
379
+		$this->_template_args['cancel_page_obj'] = isset($this->core_config->cancel_page_id)
380
+			? get_post($this->core_config->cancel_page_id)
381
+			: false;
382
+
383
+		$this->_set_add_edit_form_tags('update_espresso_page_settings');
384
+		$this->_set_publish_post_box_vars();
385
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
386
+			GEN_SET_TEMPLATE_PATH . 'espresso_page_settings.template.php',
387
+			$this->_template_args,
388
+			true
389
+		);
390
+		$this->display_admin_page_with_sidebar();
391
+	}
392
+
393
+
394
+	/**
395
+	 * Handler for updating espresso page settings.
396
+	 *
397
+	 * @throws EE_Error
398
+	 */
399
+	protected function _update_espresso_page_settings()
400
+	{
401
+		$this->core_config = EE_Registry::instance()->CFG->core;
402
+		// capture incoming request data && set page IDs
403
+		$this->core_config->reg_page_id       = $this->request->getRequestParam(
404
+			'reg_page_id',
405
+			$this->core_config->reg_page_id,
406
+			DataType::INT
407
+		);
408
+		$this->core_config->txn_page_id       = $this->request->getRequestParam(
409
+			'txn_page_id',
410
+			$this->core_config->txn_page_id,
411
+			DataType::INT
412
+		);
413
+		$this->core_config->thank_you_page_id = $this->request->getRequestParam(
414
+			'thank_you_page_id',
415
+			$this->core_config->thank_you_page_id,
416
+			DataType::INT
417
+		);
418
+		$this->core_config->cancel_page_id    = $this->request->getRequestParam(
419
+			'cancel_page_id',
420
+			$this->core_config->cancel_page_id,
421
+			DataType::INT
422
+		);
423
+
424
+		$this->core_config = apply_filters(
425
+			'FHEE__General_Settings_Admin_Page___update_espresso_page_settings__CFG_core',
426
+			$this->core_config,
427
+			$this->request->requestParams()
428
+		);
429
+
430
+		$what = esc_html__('Critical Pages & Shortcodes', 'event_espresso');
431
+		$this->_redirect_after_action(
432
+			$this->_update_espresso_configuration(
433
+				$what,
434
+				$this->core_config,
435
+				__FILE__,
436
+				__FUNCTION__,
437
+				__LINE__
438
+			),
439
+			$what,
440
+			'',
441
+			[
442
+				'action' => 'critical_pages',
443
+			],
444
+			true
445
+		);
446
+	}
447
+
448
+
449
+	/*************        Your Organization        *************/
450
+
451
+
452
+	/**
453
+	 * @throws DomainException
454
+	 * @throws EE_Error
455
+	 * @throws InvalidArgumentException
456
+	 * @throws InvalidDataTypeException
457
+	 * @throws InvalidInterfaceException
458
+	 */
459
+	protected function _your_organization_settings()
460
+	{
461
+		$this->_template_args['admin_page_content'] = '';
462
+		try {
463
+			/** @var OrganizationSettings $organization_settings_form */
464
+			$organization_settings_form = $this->loader->getShared(OrganizationSettings::class);
465
+
466
+			$this->_template_args['admin_page_content'] = EEH_HTML::div(
467
+				$organization_settings_form->display(),
468
+				'',
469
+				'padding'
470
+			);
471
+		} catch (Exception $e) {
472
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
473
+		}
474
+		$this->_set_add_edit_form_tags('update_your_organization_settings');
475
+		$this->_set_publish_post_box_vars();
476
+		$this->display_admin_page_with_sidebar();
477
+	}
478
+
479
+
480
+	/**
481
+	 * Handler for updating organization settings.
482
+	 *
483
+	 * @throws EE_Error
484
+	 */
485
+	protected function _update_your_organization_settings()
486
+	{
487
+		try {
488
+			/** @var OrganizationSettings $organization_settings_form */
489
+			$organization_settings_form = $this->loader->getShared(OrganizationSettings::class);
490
+
491
+			$success = $organization_settings_form->process($this->request->requestParams());
492
+
493
+			EE_Registry::instance()->CFG = apply_filters(
494
+				'FHEE__General_Settings_Admin_Page___update_your_organization_settings__CFG',
495
+				EE_Registry::instance()->CFG
496
+			);
497
+		} catch (Exception $e) {
498
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
499
+			$success = false;
500
+		}
501
+
502
+		if ($success) {
503
+			$success = $this->_update_espresso_configuration(
504
+				esc_html__('Your Organization Settings', 'event_espresso'),
505
+				EE_Registry::instance()->CFG,
506
+				__FILE__,
507
+				__FUNCTION__,
508
+				__LINE__
509
+			);
510
+		}
511
+
512
+		$this->_redirect_after_action($success, '', '', ['action' => 'default'], true);
513
+	}
514
+
515
+
516
+
517
+	/*************        Admin Options        *************/
518
+
519
+
520
+	/**
521
+	 * _admin_option_settings
522
+	 *
523
+	 * @throws EE_Error
524
+	 * @throws LogicException
525
+	 */
526
+	protected function _admin_option_settings()
527
+	{
528
+		$this->_template_args['admin_page_content'] = '';
529
+		try {
530
+			$admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
531
+			// still need this for the old school form in Extend_General_Settings_Admin_Page
532
+			$this->_template_args['values'] = $this->_yes_no_values;
533
+			// also need to account for the do_action that was in the old template
534
+			$admin_options_settings_form->setTemplateArgs($this->_template_args);
535
+			$this->_template_args['admin_page_content'] = EEH_HTML::div(
536
+				$admin_options_settings_form->display(),
537
+				'',
538
+				'padding'
539
+			);
540
+		} catch (Exception $e) {
541
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
542
+		}
543
+		$this->_set_add_edit_form_tags('update_admin_option_settings');
544
+		$this->_set_publish_post_box_vars();
545
+		$this->display_admin_page_with_sidebar();
546
+	}
547
+
548
+
549
+	/**
550
+	 * _update_admin_option_settings
551
+	 *
552
+	 * @throws EE_Error
553
+	 * @throws InvalidDataTypeException
554
+	 * @throws InvalidFormSubmissionException
555
+	 * @throws InvalidArgumentException
556
+	 * @throws LogicException
557
+	 */
558
+	protected function _update_admin_option_settings()
559
+	{
560
+		try {
561
+			$admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
562
+			$admin_options_settings_form->process(
563
+				$this->request->getRequestParam(
564
+					$admin_options_settings_form->slug(),
565
+					[],
566
+					DataType::STRING,
567
+					true
568
+				)
569
+			);
570
+			EE_Registry::instance()->CFG->admin = apply_filters(
571
+				'FHEE__General_Settings_Admin_Page___update_admin_option_settings__CFG_admin',
572
+				EE_Registry::instance()->CFG->admin
573
+			);
574
+		} catch (Exception $e) {
575
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
576
+		}
577
+		$this->_redirect_after_action(
578
+			apply_filters(
579
+				'FHEE__General_Settings_Admin_Page___update_admin_option_settings__success',
580
+				$this->_update_espresso_configuration(
581
+					esc_html__('Admin Options', 'event_espresso'),
582
+					EE_Registry::instance()->CFG->admin,
583
+					__FILE__,
584
+					__FUNCTION__,
585
+					__LINE__
586
+				)
587
+			),
588
+			esc_html__('Admin Options', 'event_espresso'),
589
+			'updated',
590
+			['action' => 'admin_option_settings']
591
+		);
592
+	}
593
+
594
+
595
+	/*************        Countries        *************/
596
+
597
+
598
+	/**
599
+	 * @param string|null $default
600
+	 * @return string
601
+	 */
602
+	protected function getCountryISO(?string $default = null): string
603
+	{
604
+		$default = $default ?? $this->getCountryIsoForSite();
605
+		$CNT_ISO = $this->request->getRequestParam('country', $default);
606
+		$CNT_ISO = $this->request->getRequestParam('CNT_ISO', $CNT_ISO);
607
+		return strtoupper($CNT_ISO);
608
+	}
609
+
610
+
611
+	/**
612
+	 * @return string
613
+	 */
614
+	protected function getCountryIsoForSite(): string
615
+	{
616
+		return ! empty(EE_Registry::instance()->CFG->organization->CNT_ISO)
617
+			? EE_Registry::instance()->CFG->organization->CNT_ISO
618
+			: 'US';
619
+	}
620
+
621
+
622
+	/**
623
+	 * @param string          $CNT_ISO
624
+	 * @param EE_Country|null $country
625
+	 * @return EE_Base_Class|EE_Country
626
+	 * @throws EE_Error
627
+	 * @throws InvalidArgumentException
628
+	 * @throws InvalidDataTypeException
629
+	 * @throws InvalidInterfaceException
630
+	 * @throws ReflectionException
631
+	 */
632
+	protected function verifyOrGetCountryFromIso(string $CNT_ISO, ?EE_Country $country = null)
633
+	{
634
+		/** @var EE_Country $country */
635
+		return $country instanceof EE_Country && $country->ID() === $CNT_ISO
636
+			? $country
637
+			: EEM_Country::instance()->get_one_by_ID($CNT_ISO);
638
+	}
639
+
640
+
641
+	/**
642
+	 * Output Country Settings view.
643
+	 *
644
+	 * @throws DomainException
645
+	 * @throws EE_Error
646
+	 * @throws InvalidArgumentException
647
+	 * @throws InvalidDataTypeException
648
+	 * @throws InvalidInterfaceException
649
+	 * @throws ReflectionException
650
+	 */
651
+	protected function _country_settings()
652
+	{
653
+		$CNT_ISO = $this->getCountryISO();
654
+
655
+		$this->_template_args['values']    = $this->_yes_no_values;
656
+		$this->_template_args['countries'] = new EE_Question_Form_Input(
657
+			EE_Question::new_instance(
658
+				[
659
+				  'QST_ID'           => 0,
660
+				  'QST_display_text' => esc_html__('Select Country', 'event_espresso'),
661
+				  'QST_system'       => 'admin-country',
662
+				]
663
+			),
664
+			EE_Answer::new_instance(
665
+				[
666
+					'ANS_ID'    => 0,
667
+					'ANS_value' => $CNT_ISO,
668
+				]
669
+			),
670
+			[
671
+				'input_id'       => 'country',
672
+				'input_name'     => 'country',
673
+				'input_prefix'   => '',
674
+				'append_qstn_id' => false,
675
+			]
676
+		);
677
+
678
+		$country = $this->verifyOrGetCountryFromIso($CNT_ISO);
679
+		add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'country_form_field_label_wrap'], 10);
680
+		add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'country_form_field_input__wrap'], 10);
681
+		$this->_template_args['country_details_settings'] = $this->display_country_settings(
682
+			$country->ID(),
683
+			$country
684
+		);
685
+		$this->_template_args['country_states_settings']  = $this->display_country_states(
686
+			$country->ID(),
687
+			$country
688
+		);
689
+		$this->_template_args['CNT_name_for_site']        = $country->name();
690
+
691
+		$this->_set_add_edit_form_tags('update_country_settings');
692
+		$this->_set_publish_post_box_vars();
693
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
694
+			GEN_SET_TEMPLATE_PATH . 'countries_settings.template.php',
695
+			$this->_template_args,
696
+			true
697
+		);
698
+		$this->display_admin_page_with_no_sidebar();
699
+	}
700
+
701
+
702
+	/**
703
+	 * @param string          $CNT_ISO
704
+	 * @param EE_Country|null $country
705
+	 * @return string
706
+	 * @throws DomainException
707
+	 * @throws EE_Error
708
+	 * @throws InvalidArgumentException
709
+	 * @throws InvalidDataTypeException
710
+	 * @throws InvalidInterfaceException
711
+	 * @throws ReflectionException
712
+	 */
713
+	public function display_country_settings(string $CNT_ISO = '', ?EE_Country $country = null): string
714
+	{
715
+		$CNT_ISO          = $this->getCountryISO($CNT_ISO);
716
+		$CNT_ISO_for_site = $this->getCountryIsoForSite();
717
+
718
+		if (! $CNT_ISO) {
719
+			return '';
720
+		}
721
+
722
+		// for ajax
723
+		remove_all_filters('FHEE__EEH_Form_Fields__label_html');
724
+		remove_all_filters('FHEE__EEH_Form_Fields__input_html');
725
+		add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'country_form_field_label_wrap'], 10, 2);
726
+		add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'country_form_field_input__wrap'], 10, 2);
727
+		$country                                  = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
728
+		$CNT_cur_disabled                         = $CNT_ISO !== $CNT_ISO_for_site;
729
+		$this->_template_args['CNT_cur_disabled'] = $CNT_cur_disabled;
730
+
731
+		$country_input_types            = [
732
+			'CNT_active'      => [
733
+				'type'             => 'RADIO_BTN',
734
+				'input_name'       => "cntry[$CNT_ISO]",
735
+				'class'            => '',
736
+				'options'          => $this->_yes_no_values,
737
+				'use_desc_4_label' => true,
738
+			],
739
+			'CNT_ISO'         => [
740
+				'type'       => 'TEXT',
741
+				'input_name' => "cntry[$CNT_ISO]",
742
+				'class'      => 'ee-input-width--small',
743
+			],
744
+			'CNT_ISO3'        => [
745
+				'type'       => 'TEXT',
746
+				'input_name' => "cntry[$CNT_ISO]",
747
+				'class'      => 'ee-input-width--small',
748
+			],
749
+			// 'RGN_ID'          => [
750
+			//     'type'       => 'TEXT',
751
+			//     'input_name' => "cntry[$CNT_ISO]",
752
+			//     'class'      => 'ee-input-width--small',
753
+			// ],
754
+			'CNT_name'        => [
755
+				'type'       => 'TEXT',
756
+				'input_name' => "cntry[$CNT_ISO]",
757
+				'class'      => 'ee-input-width--big',
758
+			],
759
+			'CNT_cur_code'    => [
760
+				'type'       => 'TEXT',
761
+				'input_name' => "cntry[$CNT_ISO]",
762
+				'class'      => 'ee-input-width--small',
763
+				'disabled'   => $CNT_cur_disabled,
764
+			],
765
+			'CNT_cur_single'  => [
766
+				'type'       => 'TEXT',
767
+				'input_name' => "cntry[$CNT_ISO]",
768
+				'class'      => 'ee-input-width--reg',
769
+				'disabled'   => $CNT_cur_disabled,
770
+			],
771
+			'CNT_cur_plural'  => [
772
+				'type'       => 'TEXT',
773
+				'input_name' => "cntry[$CNT_ISO]",
774
+				'class'      => 'ee-input-width--reg',
775
+				'disabled'   => $CNT_cur_disabled,
776
+			],
777
+			'CNT_cur_sign'    => [
778
+				'type'         => 'TEXT',
779
+				'input_name'   => "cntry[$CNT_ISO]",
780
+				'class'        => 'ee-input-width--small',
781
+				'htmlentities' => false,
782
+				'disabled'     => $CNT_cur_disabled,
783
+			],
784
+			'CNT_cur_sign_b4' => [
785
+				'type'             => 'RADIO_BTN',
786
+				'input_name'       => "cntry[$CNT_ISO]",
787
+				'class'            => '',
788
+				'options'          => $this->_yes_no_values,
789
+				'use_desc_4_label' => true,
790
+				'disabled'         => $CNT_cur_disabled,
791
+			],
792
+			'CNT_cur_dec_plc' => [
793
+				'type'       => 'RADIO_BTN',
794
+				'input_name' => "cntry[$CNT_ISO]",
795
+				'class'      => '',
796
+				'options'    => [
797
+					['id' => 0, 'text' => ''],
798
+					['id' => 1, 'text' => ''],
799
+					['id' => 2, 'text' => ''],
800
+					['id' => 3, 'text' => ''],
801
+				],
802
+				'disabled'   => $CNT_cur_disabled,
803
+			],
804
+			'CNT_cur_dec_mrk' => [
805
+				'type'             => 'RADIO_BTN',
806
+				'input_name'       => "cntry[$CNT_ISO]",
807
+				'class'            => '',
808
+				'options'          => [
809
+					[
810
+						'id'   => ',',
811
+						'text' => esc_html__(', (comma)', 'event_espresso'),
812
+					],
813
+					['id' => '.', 'text' => esc_html__('. (decimal)', 'event_espresso')],
814
+				],
815
+				'use_desc_4_label' => true,
816
+				'disabled'         => $CNT_cur_disabled,
817
+			],
818
+			'CNT_cur_thsnds'  => [
819
+				'type'             => 'RADIO_BTN',
820
+				'input_name'       => "cntry[$CNT_ISO]",
821
+				'class'            => '',
822
+				'options'          => [
823
+					[
824
+						'id'   => ',',
825
+						'text' => esc_html__(', (comma)', 'event_espresso'),
826
+					],
827
+					[
828
+						'id'   => '.',
829
+						'text' => esc_html__('. (decimal)', 'event_espresso'),
830
+					],
831
+					[
832
+						'id'   => '&nbsp;',
833
+						'text' => esc_html__('(space)', 'event_espresso'),
834
+					],
835
+					[
836
+						'id'   => '_',
837
+						'text' => esc_html__('_ (underscore)', 'event_espresso'),
838
+					],
839
+					[
840
+						'id'   => "'",
841
+						'text' => esc_html__("' (apostrophe)", 'event_espresso'),
842
+					],
843
+					[
844
+						'id'   => "",
845
+						'text' => esc_html__(" (nothing)", 'event_espresso'),
846
+					],
847
+				],
848
+				'use_desc_4_label' => true,
849
+				'disabled'         => $CNT_cur_disabled,
850
+			],
851
+			'CNT_tel_code'    => [
852
+				'type'       => 'TEXT',
853
+				'input_name' => "cntry[$CNT_ISO]",
854
+				'class'      => 'ee-input-width--small',
855
+			],
856
+			'CNT_is_EU'       => [
857
+				'type'             => 'RADIO_BTN',
858
+				'input_name'       => "cntry[$CNT_ISO]",
859
+				'class'            => '',
860
+				'options'          => $this->_yes_no_values,
861
+				'use_desc_4_label' => true,
862
+			],
863
+		];
864
+		$this->_template_args['inputs'] = EE_Question_Form_Input::generate_question_form_inputs_for_object(
865
+			$country,
866
+			$country_input_types
867
+		);
868
+		$country_details_settings       = EEH_Template::display_template(
869
+			GEN_SET_TEMPLATE_PATH . 'country_details_settings.template.php',
870
+			$this->_template_args,
871
+			true
872
+		);
873
+
874
+		if (defined('DOING_AJAX')) {
875
+			$notices = EE_Error::get_notices(false, false, false);
876
+			echo wp_json_encode(
877
+				[
878
+					'return_data' => $country_details_settings,
879
+					'success'     => $notices['success'],
880
+					'errors'      => $notices['errors'],
881
+				]
882
+			);
883
+			die();
884
+		}
885
+		return $country_details_settings;
886
+	}
887
+
888
+
889
+	/**
890
+	 * @param string          $CNT_ISO
891
+	 * @param EE_Country|null $country
892
+	 * @return string
893
+	 * @throws DomainException
894
+	 * @throws EE_Error
895
+	 * @throws InvalidArgumentException
896
+	 * @throws InvalidDataTypeException
897
+	 * @throws InvalidInterfaceException
898
+	 * @throws ReflectionException
899
+	 */
900
+	public function display_country_states(string $CNT_ISO = '', ?EE_Country $country = null): string
901
+	{
902
+		$CNT_ISO = $this->getCountryISO($CNT_ISO);
903
+		if (! $CNT_ISO) {
904
+			return '';
905
+		}
906
+		// for ajax
907
+		remove_all_filters('FHEE__EEH_Form_Fields__label_html');
908
+		remove_all_filters('FHEE__EEH_Form_Fields__input_html');
909
+		add_filter('FHEE__EEH_Form_Fields__label_html', [$this, 'state_form_field_label_wrap'], 10, 2);
910
+		add_filter('FHEE__EEH_Form_Fields__input_html', [$this, 'state_form_field_input__wrap'], 10);
911
+		$states = EEM_State::instance()->get_all_states_for_these_countries([$CNT_ISO => $CNT_ISO]);
912
+		if (empty($states)) {
913
+			/** @var EventEspresso\core\services\address\CountrySubRegionDao $countrySubRegionDao */
914
+			$countrySubRegionDao = $this->loader->getShared(
915
+				'EventEspresso\core\services\address\CountrySubRegionDao'
916
+			);
917
+			if ($countrySubRegionDao instanceof EventEspresso\core\services\address\CountrySubRegionDao) {
918
+				$country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
919
+				if ($countrySubRegionDao->saveCountrySubRegions($country)) {
920
+					$states = EEM_State::instance()->get_all_states_for_these_countries([$CNT_ISO => $CNT_ISO]);
921
+				}
922
+			}
923
+		}
924
+		if (is_array($states)) {
925
+			foreach ($states as $STA_ID => $state) {
926
+				if ($state instanceof EE_State) {
927
+					$inputs = EE_Question_Form_Input::generate_question_form_inputs_for_object(
928
+						$state,
929
+						[
930
+							'STA_abbrev' => [
931
+								'type'             => 'TEXT',
932
+								'label'            => esc_html__('Code', 'event_espresso'),
933
+								'input_name'       => "states[$STA_ID]",
934
+								'class'            => 'ee-input-width--tiny',
935
+								'add_mobile_label' => true,
936
+							],
937
+							'STA_name'   => [
938
+								'type'             => 'TEXT',
939
+								'label'            => esc_html__('Name', 'event_espresso'),
940
+								'input_name'       => "states[$STA_ID]",
941
+								'class'            => 'ee-input-width--big',
942
+								'add_mobile_label' => true,
943
+							],
944
+							'STA_active' => [
945
+								'type'             => 'RADIO_BTN',
946
+								'label'            => esc_html__(
947
+									'State Appears in Dropdown Select Lists',
948
+									'event_espresso'
949
+								),
950
+								'input_name'       => "states[$STA_ID]",
951
+								'options'          => $this->_yes_no_values,
952
+								'use_desc_4_label' => true,
953
+								'add_mobile_label' => true,
954
+							],
955
+						]
956
+					);
957
+
958
+					$delete_state_url = EE_Admin_Page::add_query_args_and_nonce(
959
+						[
960
+							'action'     => 'delete_state',
961
+							'STA_ID'     => $STA_ID,
962
+							'CNT_ISO'    => $CNT_ISO,
963
+							'STA_abbrev' => $state->abbrev(),
964
+						],
965
+						GEN_SET_ADMIN_URL
966
+					);
967
+
968
+					$this->_template_args['states'][ $STA_ID ]['inputs']           = $inputs;
969
+					$this->_template_args['states'][ $STA_ID ]['delete_state_url'] = $delete_state_url;
970
+				}
971
+			}
972
+		} else {
973
+			$this->_template_args['states'] = false;
974
+		}
975
+
976
+		$this->_template_args['add_new_state_url'] = EE_Admin_Page::add_query_args_and_nonce(
977
+			['action' => 'add_new_state'],
978
+			GEN_SET_ADMIN_URL
979
+		);
980
+
981
+		$state_details_settings = EEH_Template::display_template(
982
+			GEN_SET_TEMPLATE_PATH . 'state_details_settings.template.php',
983
+			$this->_template_args,
984
+			true
985
+		);
986
+
987
+		if (defined('DOING_AJAX')) {
988
+			$notices = EE_Error::get_notices(false, false, false);
989
+			echo wp_json_encode(
990
+				[
991
+					'return_data' => $state_details_settings,
992
+					'success'     => $notices['success'],
993
+					'errors'      => $notices['errors'],
994
+				]
995
+			);
996
+			die();
997
+		}
998
+		return $state_details_settings;
999
+	}
1000
+
1001
+
1002
+	/**
1003
+	 * @return void
1004
+	 * @throws EE_Error
1005
+	 * @throws InvalidArgumentException
1006
+	 * @throws InvalidDataTypeException
1007
+	 * @throws InvalidInterfaceException
1008
+	 * @throws ReflectionException
1009
+	 */
1010
+	public function add_new_state()
1011
+	{
1012
+		$success = true;
1013
+		$CNT_ISO = $this->getCountryISO('');
1014
+		if (! $CNT_ISO) {
1015
+			EE_Error::add_error(
1016
+				esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1017
+				__FILE__,
1018
+				__FUNCTION__,
1019
+				__LINE__
1020
+			);
1021
+			$success = false;
1022
+		}
1023
+		$STA_abbrev = $this->request->getRequestParam('STA_abbrev');
1024
+		if (! $STA_abbrev) {
1025
+			EE_Error::add_error(
1026
+				esc_html__('No State ISO code or an invalid State ISO code was received.', 'event_espresso'),
1027
+				__FILE__,
1028
+				__FUNCTION__,
1029
+				__LINE__
1030
+			);
1031
+			$success = false;
1032
+		}
1033
+		$STA_name = $this->request->getRequestParam('STA_name');
1034
+		if (! $STA_name) {
1035
+			EE_Error::add_error(
1036
+				esc_html__('No State name or an invalid State name was received.', 'event_espresso'),
1037
+				__FILE__,
1038
+				__FUNCTION__,
1039
+				__LINE__
1040
+			);
1041
+			$success = false;
1042
+		}
1043
+
1044
+		if ($success) {
1045
+			$cols_n_values = [
1046
+				'CNT_ISO'    => $CNT_ISO,
1047
+				'STA_abbrev' => $STA_abbrev,
1048
+				'STA_name'   => $STA_name,
1049
+				'STA_active' => true,
1050
+			];
1051
+			$success       = EEM_State::instance()->insert($cols_n_values);
1052
+			EE_Error::add_success(esc_html__('The State was added successfully.', 'event_espresso'));
1053
+		}
1054
+
1055
+		if (defined('DOING_AJAX')) {
1056
+			$notices = EE_Error::get_notices(false, false, false);
1057
+			echo wp_json_encode(array_merge($notices, ['return_data' => $CNT_ISO]));
1058
+			die();
1059
+		}
1060
+		$this->_redirect_after_action(
1061
+			$success,
1062
+			esc_html__('State', 'event_espresso'),
1063
+			'added',
1064
+			['action' => 'country_settings']
1065
+		);
1066
+	}
1067
+
1068
+
1069
+	/**
1070
+	 * @return void
1071
+	 * @throws EE_Error
1072
+	 * @throws InvalidArgumentException
1073
+	 * @throws InvalidDataTypeException
1074
+	 * @throws InvalidInterfaceException
1075
+	 * @throws ReflectionException
1076
+	 */
1077
+	public function delete_state()
1078
+	{
1079
+		$CNT_ISO    = $this->getCountryISO();
1080
+		$STA_ID     = $this->request->getRequestParam('STA_ID');
1081
+		$STA_abbrev = $this->request->getRequestParam('STA_abbrev');
1082
+
1083
+		if (! $STA_ID) {
1084
+			EE_Error::add_error(
1085
+				esc_html__('No State ID or an invalid State ID was received.', 'event_espresso'),
1086
+				__FILE__,
1087
+				__FUNCTION__,
1088
+				__LINE__
1089
+			);
1090
+			return;
1091
+		}
1092
+
1093
+		$success = EEM_State::instance()->delete_by_ID($STA_ID);
1094
+		if ($success !== false) {
1095
+			do_action(
1096
+				'AHEE__General_Settings_Admin_Page__delete_state__state_deleted',
1097
+				$CNT_ISO,
1098
+				$STA_ID,
1099
+				['STA_abbrev' => $STA_abbrev]
1100
+			);
1101
+			EE_Error::add_success(esc_html__('The State was deleted successfully.', 'event_espresso'));
1102
+		}
1103
+		if (defined('DOING_AJAX')) {
1104
+			$notices                = EE_Error::get_notices(false);
1105
+			$notices['return_data'] = true;
1106
+			echo wp_json_encode($notices);
1107
+			die();
1108
+		}
1109
+		$this->_redirect_after_action(
1110
+			$success,
1111
+			esc_html__('State', 'event_espresso'),
1112
+			'deleted',
1113
+			['action' => 'country_settings']
1114
+		);
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * @return void
1120
+	 * @throws EE_Error
1121
+	 * @throws InvalidArgumentException
1122
+	 * @throws InvalidDataTypeException
1123
+	 * @throws InvalidInterfaceException
1124
+	 * @throws ReflectionException
1125
+	 */
1126
+	protected function _update_country_settings()
1127
+	{
1128
+		$CNT_ISO = $this->getCountryISO();
1129
+		if (! $CNT_ISO) {
1130
+			EE_Error::add_error(
1131
+				esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1132
+				__FILE__,
1133
+				__FUNCTION__,
1134
+				__LINE__
1135
+			);
1136
+			return;
1137
+		}
1138
+
1139
+		$country = $this->verifyOrGetCountryFromIso($CNT_ISO);
1140
+
1141
+		$cols_n_values                    = [];
1142
+		$cols_n_values['CNT_ISO3']        = strtoupper(
1143
+			$this->request->getRequestParam(
1144
+				"cntry[$CNT_ISO][CNT_ISO3]",
1145
+				$country->ISO3()
1146
+			)
1147
+		);
1148
+		$cols_n_values['CNT_name']        = $this->request->getRequestParam(
1149
+			"cntry[$CNT_ISO][CNT_name]",
1150
+			$country->name()
1151
+		);
1152
+		$cols_n_values['CNT_cur_code']    = strtoupper(
1153
+			$this->request->getRequestParam(
1154
+				"cntry[$CNT_ISO][CNT_cur_code]",
1155
+				$country->currency_code()
1156
+			)
1157
+		);
1158
+		$cols_n_values['CNT_cur_single']  = $this->request->getRequestParam(
1159
+			"cntry[$CNT_ISO][CNT_cur_single]",
1160
+			$country->currency_name_single()
1161
+		);
1162
+		$cols_n_values['CNT_cur_plural']  = $this->request->getRequestParam(
1163
+			"cntry[$CNT_ISO][CNT_cur_plural]",
1164
+			$country->currency_name_plural()
1165
+		);
1166
+		$cols_n_values['CNT_cur_sign']    = $this->request->getRequestParam(
1167
+			"cntry[$CNT_ISO][CNT_cur_sign]",
1168
+			$country->currency_sign()
1169
+		);
1170
+		$cols_n_values['CNT_cur_sign_b4'] = $this->request->getRequestParam(
1171
+			"cntry[$CNT_ISO][CNT_cur_sign_b4]",
1172
+			$country->currency_sign_before(),
1173
+			DataType::BOOL
1174
+		);
1175
+		$cols_n_values['CNT_cur_dec_plc'] = $this->request->getRequestParam(
1176
+			"cntry[$CNT_ISO][CNT_cur_dec_plc]",
1177
+			$country->currency_decimal_places()
1178
+		);
1179
+		$cols_n_values['CNT_cur_dec_mrk'] = $this->request->getRequestParam(
1180
+			"cntry[$CNT_ISO][CNT_cur_dec_mrk]",
1181
+			$country->currency_decimal_mark()
1182
+		);
1183
+		$cols_n_values['CNT_cur_thsnds']  = $this->request->getRequestParam(
1184
+			"cntry[$CNT_ISO][CNT_cur_thsnds]",
1185
+			$country->currency_thousands_separator()
1186
+		);
1187
+		$cols_n_values['CNT_tel_code']    = $this->request->getRequestParam(
1188
+			"cntry[$CNT_ISO][CNT_tel_code]",
1189
+			$country->telephoneCode()
1190
+		);
1191
+		$cols_n_values['CNT_active']      = $this->request->getRequestParam(
1192
+			"cntry[$CNT_ISO][CNT_active]",
1193
+			$country->isActive(),
1194
+			DataType::BOOL
1195
+		);
1196
+
1197
+		// allow filtering of country data
1198
+		$cols_n_values = apply_filters(
1199
+			'FHEE__General_Settings_Admin_Page___update_country_settings__cols_n_values',
1200
+			$cols_n_values
1201
+		);
1202
+
1203
+		// where values
1204
+		$where_cols_n_values = [['CNT_ISO' => $CNT_ISO]];
1205
+		// run the update
1206
+		$success = EEM_Country::instance()->update($cols_n_values, $where_cols_n_values);
1207
+
1208
+		// allow filtering of states data
1209
+		$states = apply_filters(
1210
+			'FHEE__General_Settings_Admin_Page___update_country_settings__states',
1211
+			$this->request->getRequestParam('states', [], DataType::STRING, true)
1212
+		);
1213
+
1214
+		if (! empty($states) && $success !== false) {
1215
+			// loop thru state data ( looks like : states[75][STA_name] )
1216
+			foreach ($states as $STA_ID => $state) {
1217
+				$cols_n_values = [
1218
+					'CNT_ISO'    => $CNT_ISO,
1219
+					'STA_abbrev' => sanitize_text_field($state['STA_abbrev']),
1220
+					'STA_name'   => sanitize_text_field($state['STA_name']),
1221
+					'STA_active' => filter_var($state['STA_active'], FILTER_VALIDATE_BOOLEAN),
1222
+				];
1223
+				// where values
1224
+				$where_cols_n_values = [['STA_ID' => $STA_ID]];
1225
+				// run the update
1226
+				$success = EEM_State::instance()->update($cols_n_values, $where_cols_n_values);
1227
+				if ($success !== false) {
1228
+					do_action(
1229
+						'AHEE__General_Settings_Admin_Page__update_country_settings__state_saved',
1230
+						$CNT_ISO,
1231
+						$STA_ID,
1232
+						$cols_n_values
1233
+					);
1234
+				}
1235
+			}
1236
+		}
1237
+		// check if country being edited matches org option country, and if so, then  update EE_Config with new settings
1238
+		if (
1239
+			isset(EE_Registry::instance()->CFG->organization->CNT_ISO)
1240
+			&& $CNT_ISO == EE_Registry::instance()->CFG->organization->CNT_ISO
1241
+		) {
1242
+			EE_Registry::instance()->CFG->currency = new EE_Currency_Config($CNT_ISO);
1243
+			EE_Registry::instance()->CFG->update_espresso_config();
1244
+		}
1245
+
1246
+		if ($success !== false) {
1247
+			EE_Error::add_success(
1248
+				esc_html__('Country Settings updated successfully.', 'event_espresso')
1249
+			);
1250
+		}
1251
+		$this->_redirect_after_action(
1252
+			$success,
1253
+			'',
1254
+			'',
1255
+			['action' => 'country_settings', 'country' => $CNT_ISO],
1256
+			true
1257
+		);
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * form_form_field_label_wrap
1263
+	 *
1264
+	 * @param string $label
1265
+	 * @return string
1266
+	 */
1267
+	public function country_form_field_label_wrap(string $label): string
1268
+	{
1269
+		return '
1270 1270
 			<tr>
1271 1271
 				<th>
1272 1272
 					' . $label . '
1273 1273
 				</th>';
1274
-    }
1275
-
1276
-
1277
-    /**
1278
-     * form_form_field_input__wrap
1279
-     *
1280
-     * @param string $input
1281
-     * @return string
1282
-     */
1283
-    public function country_form_field_input__wrap(string $input): string
1284
-    {
1285
-        return '
1274
+	}
1275
+
1276
+
1277
+	/**
1278
+	 * form_form_field_input__wrap
1279
+	 *
1280
+	 * @param string $input
1281
+	 * @return string
1282
+	 */
1283
+	public function country_form_field_input__wrap(string $input): string
1284
+	{
1285
+		return '
1286 1286
 				<td class="general-settings-country-input-td">
1287 1287
 					' . $input . '
1288 1288
 				</td>
1289 1289
 			</tr>';
1290
-    }
1291
-
1292
-
1293
-    /**
1294
-     * form_form_field_label_wrap
1295
-     *
1296
-     * @param string $label
1297
-     * @param string $required_text
1298
-     * @return string
1299
-     */
1300
-    public function state_form_field_label_wrap(string $label, string $required_text): string
1301
-    {
1302
-        return $required_text;
1303
-    }
1304
-
1305
-
1306
-    /**
1307
-     * form_form_field_input__wrap
1308
-     *
1309
-     * @param string $input
1310
-     * @return string
1311
-     */
1312
-    public function state_form_field_input__wrap(string $input): string
1313
-    {
1314
-        return '
1290
+	}
1291
+
1292
+
1293
+	/**
1294
+	 * form_form_field_label_wrap
1295
+	 *
1296
+	 * @param string $label
1297
+	 * @param string $required_text
1298
+	 * @return string
1299
+	 */
1300
+	public function state_form_field_label_wrap(string $label, string $required_text): string
1301
+	{
1302
+		return $required_text;
1303
+	}
1304
+
1305
+
1306
+	/**
1307
+	 * form_form_field_input__wrap
1308
+	 *
1309
+	 * @param string $input
1310
+	 * @return string
1311
+	 */
1312
+	public function state_form_field_input__wrap(string $input): string
1313
+	{
1314
+		return '
1315 1315
 				<td class="general-settings-country-state-input-td">
1316 1316
 					' . $input . '
1317 1317
 				</td>';
1318
-    }
1319
-
1320
-
1321
-    /***********/
1322
-
1323
-
1324
-    /**
1325
-     * displays edit and view links for critical EE pages
1326
-     *
1327
-     * @param int $ee_page_id
1328
-     * @return string
1329
-     */
1330
-    public static function edit_view_links(int $ee_page_id): string
1331
-    {
1332
-        $edit_url = add_query_arg(
1333
-            ['post' => $ee_page_id, 'action' => 'edit'],
1334
-            admin_url('post.php')
1335
-        );
1336
-        $links    = '<a href="' . esc_url_raw($edit_url) . '" >' . esc_html__('Edit', 'event_espresso') . '</a>';
1337
-        $links    .= ' &nbsp;|&nbsp; ';
1338
-        $links    .= '<a href="' . get_permalink($ee_page_id) . '" >' . esc_html__('View', 'event_espresso') . '</a>';
1339
-
1340
-        return $links;
1341
-    }
1342
-
1343
-
1344
-    /**
1345
-     * displays page and shortcode status for critical EE pages
1346
-     *
1347
-     * @param WP_Post $ee_page
1348
-     * @param string  $shortcode
1349
-     * @return string
1350
-     */
1351
-    public static function page_and_shortcode_status(WP_Post $ee_page, string $shortcode): string
1352
-    {
1353
-        // page status
1354
-        if (isset($ee_page->post_status) && $ee_page->post_status == 'publish') {
1355
-            $pg_class  = 'ee-status-bg--success';
1356
-            $pg_status = sprintf(esc_html__('Page%sStatus%sOK', 'event_espresso'), '&nbsp;', '&nbsp;');
1357
-        } else {
1358
-            $pg_class  = 'ee-status-bg--error';
1359
-            $pg_status = sprintf(esc_html__('Page%sVisibility%sProblem', 'event_espresso'), '&nbsp;', '&nbsp;');
1360
-        }
1361
-
1362
-        // shortcode status
1363
-        if (isset($ee_page->post_content) && strpos($ee_page->post_content, $shortcode) !== false) {
1364
-            $sc_class  = 'ee-status-bg--success';
1365
-            $sc_status = sprintf(esc_html__('Shortcode%sOK', 'event_espresso'), '&nbsp;');
1366
-        } else {
1367
-            $sc_class  = 'ee-status-bg--error';
1368
-            $sc_status = sprintf(esc_html__('Shortcode%sProblem', 'event_espresso'), '&nbsp;');
1369
-        }
1370
-
1371
-        return '
1318
+	}
1319
+
1320
+
1321
+	/***********/
1322
+
1323
+
1324
+	/**
1325
+	 * displays edit and view links for critical EE pages
1326
+	 *
1327
+	 * @param int $ee_page_id
1328
+	 * @return string
1329
+	 */
1330
+	public static function edit_view_links(int $ee_page_id): string
1331
+	{
1332
+		$edit_url = add_query_arg(
1333
+			['post' => $ee_page_id, 'action' => 'edit'],
1334
+			admin_url('post.php')
1335
+		);
1336
+		$links    = '<a href="' . esc_url_raw($edit_url) . '" >' . esc_html__('Edit', 'event_espresso') . '</a>';
1337
+		$links    .= ' &nbsp;|&nbsp; ';
1338
+		$links    .= '<a href="' . get_permalink($ee_page_id) . '" >' . esc_html__('View', 'event_espresso') . '</a>';
1339
+
1340
+		return $links;
1341
+	}
1342
+
1343
+
1344
+	/**
1345
+	 * displays page and shortcode status for critical EE pages
1346
+	 *
1347
+	 * @param WP_Post $ee_page
1348
+	 * @param string  $shortcode
1349
+	 * @return string
1350
+	 */
1351
+	public static function page_and_shortcode_status(WP_Post $ee_page, string $shortcode): string
1352
+	{
1353
+		// page status
1354
+		if (isset($ee_page->post_status) && $ee_page->post_status == 'publish') {
1355
+			$pg_class  = 'ee-status-bg--success';
1356
+			$pg_status = sprintf(esc_html__('Page%sStatus%sOK', 'event_espresso'), '&nbsp;', '&nbsp;');
1357
+		} else {
1358
+			$pg_class  = 'ee-status-bg--error';
1359
+			$pg_status = sprintf(esc_html__('Page%sVisibility%sProblem', 'event_espresso'), '&nbsp;', '&nbsp;');
1360
+		}
1361
+
1362
+		// shortcode status
1363
+		if (isset($ee_page->post_content) && strpos($ee_page->post_content, $shortcode) !== false) {
1364
+			$sc_class  = 'ee-status-bg--success';
1365
+			$sc_status = sprintf(esc_html__('Shortcode%sOK', 'event_espresso'), '&nbsp;');
1366
+		} else {
1367
+			$sc_class  = 'ee-status-bg--error';
1368
+			$sc_status = sprintf(esc_html__('Shortcode%sProblem', 'event_espresso'), '&nbsp;');
1369
+		}
1370
+
1371
+		return '
1372 1372
         <span class="ee-page-status ' . $pg_class . '"><strong>' . $pg_status . '</strong></span>
1373 1373
         <span class="ee-page-status ' . $sc_class . '"><strong>' . $sc_status . '</strong></span>';
1374
-    }
1375
-
1376
-
1377
-    /**
1378
-     * generates a dropdown of all parent pages - copied from WP core
1379
-     *
1380
-     * @param int  $default
1381
-     * @param int  $parent
1382
-     * @param int  $level
1383
-     * @param bool $echo
1384
-     * @return string;
1385
-     */
1386
-    public static function page_settings_dropdown(
1387
-        int $default = 0,
1388
-        int $parent = 0,
1389
-        int $level = 0,
1390
-        bool $echo = true
1391
-    ): string {
1392
-        global $wpdb;
1393
-        $items  = $wpdb->get_results(
1394
-            $wpdb->prepare(
1395
-                "SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status != 'trash' ORDER BY menu_order",
1396
-                $parent
1397
-            )
1398
-        );
1399
-        $output = '';
1400
-
1401
-        if ($items) {
1402
-            $level = absint($level);
1403
-            foreach ($items as $item) {
1404
-                $ID         = absint($item->ID);
1405
-                $post_title = wp_strip_all_tags($item->post_title);
1406
-                $pad        = str_repeat('&nbsp;', $level * 3);
1407
-                $option     = "\n\t";
1408
-                $option     .= '<option class="level-' . $level . '" ';
1409
-                $option     .= 'value="' . $ID . '" ';
1410
-                $option     .= $ID === absint($default) ? ' selected' : '';
1411
-                $option     .= '>';
1412
-                $option     .= "$pad {$post_title}";
1413
-                $option     .= '</option>';
1414
-                $output     .= $option;
1415
-                ob_start();
1416
-                parent_dropdown($default, $item->ID, $level + 1);
1417
-                $output .= ob_get_clean();
1418
-            }
1419
-        }
1420
-        if ($echo) {
1421
-            echo wp_kses($output, AllowedTags::getWithFormTags());
1422
-            return '';
1423
-        }
1424
-        return $output;
1425
-    }
1426
-
1427
-
1428
-    /**
1429
-     * Loads the scripts for the privacy settings form
1430
-     */
1431
-    public function load_scripts_styles_privacy_settings()
1432
-    {
1433
-        $form_handler = $this->loader->getShared(
1434
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1435
-        );
1436
-        $form_handler->enqueueStylesAndScripts();
1437
-    }
1438
-
1439
-
1440
-    /**
1441
-     * display the privacy settings form
1442
-     *
1443
-     * @throws EE_Error
1444
-     */
1445
-    public function privacySettings()
1446
-    {
1447
-        $this->_set_add_edit_form_tags('update_privacy_settings');
1448
-        $this->_set_publish_post_box_vars();
1449
-        $form_handler                               = $this->loader->getShared(
1450
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1451
-        );
1452
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
1453
-            $form_handler->display(),
1454
-            '',
1455
-            'padding'
1456
-        );
1457
-        $this->display_admin_page_with_sidebar();
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * Update the privacy settings from form data
1463
-     *
1464
-     * @throws EE_Error
1465
-     */
1466
-    public function updatePrivacySettings()
1467
-    {
1468
-        $form_handler = $this->loader->getShared(
1469
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1470
-        );
1471
-        $success      = $form_handler->process($this->get_request_data());
1472
-        $this->_redirect_after_action(
1473
-            $success,
1474
-            esc_html__('Registration Form Options', 'event_espresso'),
1475
-            'updated',
1476
-            ['action' => 'privacy_settings']
1477
-        );
1478
-    }
1479
-
1480
-
1481
-    public function setFontSize()
1482
-    {
1483
-        AdminFontSize::setAdminFontSize(
1484
-            $this->request->getRequestParam('font_size', AdminFontSize::FONT_SIZE_DEFAULT)
1485
-        );
1486
-        wp_safe_redirect($this->request->getServerParam('HTTP_REFERER'));
1487
-    }
1374
+	}
1375
+
1376
+
1377
+	/**
1378
+	 * generates a dropdown of all parent pages - copied from WP core
1379
+	 *
1380
+	 * @param int  $default
1381
+	 * @param int  $parent
1382
+	 * @param int  $level
1383
+	 * @param bool $echo
1384
+	 * @return string;
1385
+	 */
1386
+	public static function page_settings_dropdown(
1387
+		int $default = 0,
1388
+		int $parent = 0,
1389
+		int $level = 0,
1390
+		bool $echo = true
1391
+	): string {
1392
+		global $wpdb;
1393
+		$items  = $wpdb->get_results(
1394
+			$wpdb->prepare(
1395
+				"SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status != 'trash' ORDER BY menu_order",
1396
+				$parent
1397
+			)
1398
+		);
1399
+		$output = '';
1400
+
1401
+		if ($items) {
1402
+			$level = absint($level);
1403
+			foreach ($items as $item) {
1404
+				$ID         = absint($item->ID);
1405
+				$post_title = wp_strip_all_tags($item->post_title);
1406
+				$pad        = str_repeat('&nbsp;', $level * 3);
1407
+				$option     = "\n\t";
1408
+				$option     .= '<option class="level-' . $level . '" ';
1409
+				$option     .= 'value="' . $ID . '" ';
1410
+				$option     .= $ID === absint($default) ? ' selected' : '';
1411
+				$option     .= '>';
1412
+				$option     .= "$pad {$post_title}";
1413
+				$option     .= '</option>';
1414
+				$output     .= $option;
1415
+				ob_start();
1416
+				parent_dropdown($default, $item->ID, $level + 1);
1417
+				$output .= ob_get_clean();
1418
+			}
1419
+		}
1420
+		if ($echo) {
1421
+			echo wp_kses($output, AllowedTags::getWithFormTags());
1422
+			return '';
1423
+		}
1424
+		return $output;
1425
+	}
1426
+
1427
+
1428
+	/**
1429
+	 * Loads the scripts for the privacy settings form
1430
+	 */
1431
+	public function load_scripts_styles_privacy_settings()
1432
+	{
1433
+		$form_handler = $this->loader->getShared(
1434
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1435
+		);
1436
+		$form_handler->enqueueStylesAndScripts();
1437
+	}
1438
+
1439
+
1440
+	/**
1441
+	 * display the privacy settings form
1442
+	 *
1443
+	 * @throws EE_Error
1444
+	 */
1445
+	public function privacySettings()
1446
+	{
1447
+		$this->_set_add_edit_form_tags('update_privacy_settings');
1448
+		$this->_set_publish_post_box_vars();
1449
+		$form_handler                               = $this->loader->getShared(
1450
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1451
+		);
1452
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
1453
+			$form_handler->display(),
1454
+			'',
1455
+			'padding'
1456
+		);
1457
+		$this->display_admin_page_with_sidebar();
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * Update the privacy settings from form data
1463
+	 *
1464
+	 * @throws EE_Error
1465
+	 */
1466
+	public function updatePrivacySettings()
1467
+	{
1468
+		$form_handler = $this->loader->getShared(
1469
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler'
1470
+		);
1471
+		$success      = $form_handler->process($this->get_request_data());
1472
+		$this->_redirect_after_action(
1473
+			$success,
1474
+			esc_html__('Registration Form Options', 'event_espresso'),
1475
+			'updated',
1476
+			['action' => 'privacy_settings']
1477
+		);
1478
+	}
1479
+
1480
+
1481
+	public function setFontSize()
1482
+	{
1483
+		AdminFontSize::setAdminFontSize(
1484
+			$this->request->getRequestParam('font_size', AdminFontSize::FONT_SIZE_DEFAULT)
1485
+		);
1486
+		wp_safe_redirect($this->request->getServerParam('HTTP_REFERER'));
1487
+	}
1488 1488
 }
Please login to merge, or discard this patch.
templates/txn_admin_details_main_meta_box_txn_details.template.php 1 patch
Indentation   +200 added lines, -200 removed lines patch added patch discarded remove patch
@@ -84,21 +84,21 @@  discard block
 block discarded – undo
84 84
     </div>
85 85
     <br class="clear" />
86 86
     <?php
87
-    $no_payments = $grand_raw_total > 0
88
-                   || $TXN_status !== EEM_Transaction::complete_status_code
89
-                   || ! empty($payments);
90
-    ?>
87
+	$no_payments = $grand_raw_total > 0
88
+				   || $TXN_status !== EEM_Transaction::complete_status_code
89
+				   || ! empty($payments);
90
+	?>
91 91
     <?php if ($attendee instanceof EE_Attendee && $no_payments) : ?>
92 92
         <?php $no_payment_text = $can_edit_payments
93
-            ? esc_html__(
94
-                'No payments have been applied to this transaction yet. Click "Apply Payment" below to make a payment.',
95
-                'event_espresso'
96
-            )
97
-            : esc_html__(
98
-                'No payments have been applied to this transaction yet.',
99
-                'event_espresso'
100
-            );
101
-        ?>
93
+			? esc_html__(
94
+				'No payments have been applied to this transaction yet. Click "Apply Payment" below to make a payment.',
95
+				'event_espresso'
96
+			)
97
+			: esc_html__(
98
+				'No payments have been applied to this transaction yet.',
99
+				'event_espresso'
100
+			);
101
+		?>
102 102
 
103 103
         <h3 class="admin-primary-mbox-h4 hdr-has-icon">
104 104
             <?php esc_html_e('Payment Details', 'event_espresso'); ?>
@@ -141,92 +141,92 @@  discard block
 block discarded – undo
141 141
                 </thead>
142 142
                 <tbody>
143 143
                     <?php if ($payments) :
144
-                        $payment_total = 0;
145
-                        foreach ($payments as $PAY_ID => $payment) :
146
-                            if (! $payment instanceof EE_Payment) {
147
-                                continue;
148
-                            }
149
-                            $existing_reg_payment_json = isset($existing_reg_payments[ $PAY_ID ])
150
-                                ? wp_json_encode($existing_reg_payments[ $PAY_ID ])
151
-                                : '{}';
152
-                            ?>
144
+						$payment_total = 0;
145
+						foreach ($payments as $PAY_ID => $payment) :
146
+							if (! $payment instanceof EE_Payment) {
147
+								continue;
148
+							}
149
+							$existing_reg_payment_json = isset($existing_reg_payments[ $PAY_ID ])
150
+								? wp_json_encode($existing_reg_payments[ $PAY_ID ])
151
+								: '{}';
152
+							?>
153 153
                             <tr id="txn-admin-payment-tr-<?php echo absint($PAY_ID); ?>" class=' jst-cntr'>
154 154
                                 <td class="jst-cntr no-pad">
155 155
                                     <span id="payment-status-<?php echo absint($PAY_ID); ?>"
156 156
                                         class="ee-status-dot ee-status-bg--<?php echo esc_attr($payment->STS_ID()); ?>" ></span>
157 157
                                     <div id="payment-STS_ID-<?php echo absint($PAY_ID); ?>" class="hidden"><?php
158
-                                    echo esc_html($payment->STS_ID());
159
-                                    ?></div>
158
+									echo esc_html($payment->STS_ID());
159
+									?></div>
160 160
                                     <div id="reg-payments-<?php echo absint($PAY_ID); ?>" class="hidden"><?php
161
-                                    echo esc_html($existing_reg_payment_json);
162
-                                    ?></div>
161
+									echo esc_html($existing_reg_payment_json);
162
+									?></div>
163 163
                                 </td>
164 164
                                 <td class=" jst-rght">
165 165
                                     <div id="payment-id-<?php echo absint($PAY_ID); ?>"><?php
166
-                                    echo esc_html($PAY_ID);
167
-                                    ?></div>
166
+									echo esc_html($PAY_ID);
167
+									?></div>
168 168
                                 </td>
169 169
                                 <td class=" jst-left">
170 170
                                     <div id="payment-date-<?php echo absint($PAY_ID); ?>" class="payment-date-dv"><?php
171
-                                    echo esc_html($payment->timestamp('Y-m-d', 'g:i a'));
172
-                                    ?></div>
171
+									echo esc_html($payment->timestamp('Y-m-d', 'g:i a'));
172
+									?></div>
173 173
                                 </td>
174 174
                                 <td class='payment-method-gateway-td jst-left'>
175 175
                                     <span id="payment-method-<?php echo absint($PAY_ID); ?>"><?php
176
-                                    echo esc_html($payment->source());
177
-                                    ?></span>
176
+									echo esc_html($payment->source());
177
+									?></span>
178 178
                                     <span class="ee-status--ignore">&raquo;</span>
179 179
                                     <span id="payment-gateway-<?php echo absint($PAY_ID); ?>"><?php
180
-                                        echo esc_html(
181
-                                            $payment->payment_method() instanceof EE_Payment_Method
182
-                                                ? $payment->payment_method()->admin_name()
183
-                                                : __("Unknown", 'event_espresso')
184
-                                        ); ?></span>
180
+										echo esc_html(
181
+											$payment->payment_method() instanceof EE_Payment_Method
182
+												? $payment->payment_method()->admin_name()
183
+												: __("Unknown", 'event_espresso')
184
+										); ?></span>
185 185
                                     <span id="payment-gateway-id-<?php echo absint($PAY_ID); ?>" class="hidden"><?php
186
-                                        echo esc_html(
187
-                                            $payment->payment_method() instanceof EE_Payment_Method
188
-                                                ? $payment->payment_method()->ID()
189
-                                                : 0
190
-                                        ); ?></span>
186
+										echo esc_html(
187
+											$payment->payment_method() instanceof EE_Payment_Method
188
+												? $payment->payment_method()->ID()
189
+												: 0
190
+										); ?></span>
191 191
                                 </td>
192 192
                                 <td class=' jst-rght'>
193 193
                                     <?php
194
-                                    $payment_class = $payment->amount() > 0
195
-                                        ? 'txn-admin-payment-status-' . $payment->STS_ID()
196
-                                        : 'txn-admin-payment-status-PDC';
197
-                                    ?>
194
+									$payment_class = $payment->amount() > 0
195
+										? 'txn-admin-payment-status-' . $payment->STS_ID()
196
+										: 'txn-admin-payment-status-PDC';
197
+									?>
198 198
                                     <span class="<?php echo esc_attr($payment_class); ?>">
199 199
                                         <span id="payment-amount-<?php echo absint($PAY_ID); ?>"
200 200
                                               style="display:inline;"
201 201
                                         ><?php echo wp_kses(
202
-                                            EEH_Template::format_currency(
203
-                                                $payment->amount(),
204
-                                                false,
205
-                                                false
206
-                                            ),
207
-                                            AllowedTags::getAllowedTags()
208
-                                        ); ?></span>
202
+											EEH_Template::format_currency(
203
+												$payment->amount(),
204
+												false,
205
+												false
206
+											),
207
+											AllowedTags::getAllowedTags()
208
+										); ?></span>
209 209
                                     </span>
210 210
                                 </td>
211 211
                                 <td class=" jst-left">
212 212
                                     <div id="payment-response-<?php echo absint($PAY_ID); ?>"><?php
213
-                                    echo esc_html($payment->gateway_response());
214
-                                    ?></div>
213
+									echo esc_html($payment->gateway_response());
214
+									?></div>
215 215
                                 </td>
216 216
                                 <td class=" jst-left payment-txn-id-chq-nmbr">
217 217
                                     <div id="payment-txn-id-chq-nmbr-<?php echo absint($PAY_ID); ?>"><?php
218
-                                    echo esc_html($payment->txn_id_chq_nmbr());
219
-                                    ?></div>
218
+									echo esc_html($payment->txn_id_chq_nmbr());
219
+									?></div>
220 220
                                 </td>
221 221
                                 <td class=" jst-left">
222 222
                                     <div id="payment-po-nmbr-<?php echo absint($PAY_ID); ?>"><?php
223
-                                    echo esc_html($payment->po_number());
224
-                                    ?></div>
223
+									echo esc_html($payment->po_number());
224
+									?></div>
225 225
                                 </td>
226 226
                                 <td class=" jst-left">
227 227
                                     <div id="payment-accntng-<?php echo absint($PAY_ID); ?>"><?php
228
-                                    echo esc_html($payment->extra_accntng());
229
-                                    ?></div>
228
+									echo esc_html($payment->extra_accntng());
229
+									?></div>
230 230
                                 </td>
231 231
                                 <td class='jst-left'>
232 232
                                     <div class='txn-overview-actions ee-list-table-actions'>
@@ -256,14 +256,14 @@  discard block
 block discarded – undo
256 256
                             <?php $payment_total += $payment->STS_ID() == 'PAP' ? $payment->amount() : 0; ?>
257 257
                         <?php endforeach; ?>
258 258
                         <?php $pay_totals_class = $payment_total > $grand_raw_total
259
-                            ? ' important-notice'
260
-                            : '';
261
-                        ?>
259
+							? ' important-notice'
260
+							: '';
261
+						?>
262 262
                     <tr id="txn-admin-no-payments-tr" class="admin-primary-mbox-total-tr hidden">
263 263
                         <td class=" jst-rght" colspan="10">
264 264
                             <span class="important-notice"><?php
265
-                                echo wp_kses($no_payment_text, AllowedTags::getAllowedTags());
266
-                            ?></span>
265
+								echo wp_kses($no_payment_text, AllowedTags::getAllowedTags());
266
+							?></span>
267 267
                         </td>
268 268
                     </tr>
269 269
                     <tr id="txn-admin-payments-total-tr"
@@ -271,45 +271,45 @@  discard block
 block discarded – undo
271 271
                     >
272 272
                         <th class=" jst-rght" colspan="9">
273 273
                             <span id="payments-total-spn"><?php
274
-                            $overpaid = $payment_total > $grand_raw_total
275
-                                ? '<span id="overpaid">'
276
-                                  . __('This transaction has been overpaid ! ', 'event_espresso')
277
-                                  . '</span>'
278
-                                : '';
279
-                            echo wp_kses(
280
-                                $overpaid
281
-                                . sprintf(
282
-                                    __('Payments Total %s', 'event_espresso'),
283
-                                    '(' . EE_Registry::instance()->CFG->currency->code . ')'
284
-                                ),
285
-                                AllowedTags::getAllowedTags()
286
-                            ); ?></span>
274
+							$overpaid = $payment_total > $grand_raw_total
275
+								? '<span id="overpaid">'
276
+								  . __('This transaction has been overpaid ! ', 'event_espresso')
277
+								  . '</span>'
278
+								: '';
279
+							echo wp_kses(
280
+								$overpaid
281
+								. sprintf(
282
+									__('Payments Total %s', 'event_espresso'),
283
+									'(' . EE_Registry::instance()->CFG->currency->code . ')'
284
+								),
285
+								AllowedTags::getAllowedTags()
286
+							); ?></span>
287 287
                         </th>
288 288
                         <th class=" jst-rght">
289 289
                             <span id="txn-admin-payment-total" data-total="<?php echo esc_attr($payment_total); ?>"><?php
290
-                            echo wp_kses(
291
-                                EEH_Template::format_currency(
292
-                                    $payment_total,
293
-                                    false,
294
-                                    false
295
-                                ),
296
-                                AllowedTags::getAllowedTags()
297
-                            ); ?></span>
290
+							echo wp_kses(
291
+								EEH_Template::format_currency(
292
+									$payment_total,
293
+									false,
294
+									false
295
+								),
296
+								AllowedTags::getAllowedTags()
297
+							); ?></span>
298 298
                         </th>
299 299
                     </tr>
300 300
                     <?php else : ?>
301 301
                     <tr id="txn-admin-no-payments-tr" class="admin-primary-mbox-total-tr">
302 302
                         <td class=" jst-rght" colspan="10">
303 303
                             <span class="important-notice"><?php
304
-                                echo wp_kses($no_payment_text, AllowedTags::getAllowedTags());
305
-                            ?></span>
304
+								echo wp_kses($no_payment_text, AllowedTags::getAllowedTags());
305
+							?></span>
306 306
                         </td>
307 307
                     </tr>
308 308
                     <tr id="txn-admin-payments-total-tr" class="admin-primary-mbox-total-tr hidden">
309 309
                         <th class=" jst-rght" colspan="9">
310 310
                             <span id="payments-total-spn"><?php
311
-                            echo esc_html__('Payments Total', 'event_espresso');
312
-                            ?></span>
311
+							echo esc_html__('Payments Total', 'event_espresso');
312
+							?></span>
313 313
                         </th>
314 314
                         <th class=" jst-rght">
315 315
                             <span id="txn-admin-payment-total" data-total="0"></span>
@@ -395,15 +395,15 @@  discard block
 block discarded – undo
395 395
                 </span>
396 396
             <?php endif; ?>
397 397
             <?php
398
-            // Allows extend the fields at actions area.
399
-            ob_start();
400
-            do_action(
401
-                'AHEE__txn_admin_details_main_meta_box_txn_details__after_actions_buttons',
402
-                $can_edit_payments
403
-            );
404
-            $extra_actions = ob_get_clean();
405
-            echo str_replace(['<li', '</li>'], ['<span', '</span>'], $extra_actions);
406
-            ?>
398
+			// Allows extend the fields at actions area.
399
+			ob_start();
400
+			do_action(
401
+				'AHEE__txn_admin_details_main_meta_box_txn_details__after_actions_buttons',
402
+				$can_edit_payments
403
+			);
404
+			$extra_actions = ob_get_clean();
405
+			echo str_replace(['<li', '</li>'], ['<span', '</span>'], $extra_actions);
406
+			?>
407 407
         </div>
408 408
 
409 409
         <div id="txn-admin-apply-payment-dv" class="txn-admin-payment-option auto-hide" style="display: none;">
@@ -419,23 +419,23 @@  discard block
 block discarded – undo
419 419
                 style="display:none;"
420 420
             >
421 421
                 <?php
422
-                printf(
423
-                    esc_html__('Edit Payment #%s for Transaction #%s', 'event_espresso'),
424
-                    '<span class="ee-admin-payment-id"></span>',
425
-                    $txn_nmbr['value']
426
-                );
427
-                ?>
422
+				printf(
423
+					esc_html__('Edit Payment #%s for Transaction #%s', 'event_espresso'),
424
+					'<span class="ee-admin-payment-id"></span>',
425
+					$txn_nmbr['value']
426
+				);
427
+				?>
428 428
                 <span class='dashicons dashicons-money-alt'></span>
429 429
             </h2>
430 430
 
431 431
             <h2 id="admin-modal-dialog-edit-refund-h2" class="admin-modal-dialog-h2 hdr-has-icon" style="display:none;">
432 432
                 <?php
433
-                printf(
434
-                    esc_html__('Edit Refund #%s for Transaction #%s', 'event_espresso'),
435
-                    '<span class="ee-admin-payment-id"></span>',
436
-                    $txn_nmbr['value']
437
-                );
438
-                ?>
433
+				printf(
434
+					esc_html__('Edit Refund #%s for Transaction #%s', 'event_espresso'),
435
+					'<span class="ee-admin-payment-id"></span>',
436
+					$txn_nmbr['value']
437
+				);
438
+				?>
439 439
                 <span class='dashicons dashicons-money-alt'></span>
440 440
             </h2>
441 441
 
@@ -443,9 +443,9 @@  discard block
 block discarded – undo
443 443
                 style="display:none;"
444 444
             >
445 445
                 <?php
446
-                echo esc_html__('Apply a Refund to Transaction #', 'event_espresso');
447
-                echo esc_html($txn_nmbr['value']);
448
-                ?>
446
+				echo esc_html__('Apply a Refund to Transaction #', 'event_espresso');
447
+				echo esc_html($txn_nmbr['value']);
448
+				?>
449 449
                 <span class='dashicons dashicons-money-alt'></span>
450 450
             </h2>
451 451
 
@@ -559,20 +559,20 @@  discard block
 block discarded – undo
559 559
                                             <?php echo esc_attr($selected); ?>
560 560
                                         >
561 561
                                             <?php
562
-                                            echo esc_html(
563
-                                                sanitize_key($method->admin_desc())
564
-                                                    ? substr($method->admin_desc(), 0, 128)
565
-                                                    : $method->admin_name()
566
-                                            );
567
-                                            ?>&nbsp;&nbsp;
562
+											echo esc_html(
563
+												sanitize_key($method->admin_desc())
564
+													? substr($method->admin_desc(), 0, 128)
565
+													: $method->admin_name()
566
+											);
567
+											?>&nbsp;&nbsp;
568 568
                                         </option>
569 569
                                     <?php endforeach; ?>
570 570
                                 </select>
571 571
                                 <p class="description">
572 572
                                     <?php esc_html_e(
573
-                                        'Whether the payment was made via PayPal, Credit Card, Cheque, or Cash',
574
-                                        'event_espresso'
575
-                                    ); ?>
573
+										'Whether the payment was made via PayPal, Credit Card, Cheque, or Cash',
574
+										'event_espresso'
575
+									); ?>
576 576
                                 </p>
577 577
                             </div>
578 578
                         </div>
@@ -581,9 +581,9 @@  discard block
 block discarded – undo
581 581
                         admin-modal-dialog-row ee-layout-row">
582 582
                             <label for="txn-admin-payment-txn-id-chq-nmbr-inp" class="">
583 583
                                 <?php esc_html_e(
584
-                                    'TXN ID / CHQ #',
585
-                                    'event_espresso'
586
-                                ); ?>
584
+									'TXN ID / CHQ #',
585
+									'event_espresso'
586
+								); ?>
587 587
                             </label>
588 588
                             <div class='ee-layout-stack'>
589 589
                                 <input name="txn_admin_payment[txn_id_chq_nmbr]"
@@ -593,9 +593,9 @@  discard block
 block discarded – undo
593 593
                                 />
594 594
                                 <p class="description">
595 595
                                     <?php esc_html_e(
596
-                                        'The Transaction ID sent back from the payment gateway, or the Cheque #',
597
-                                        'event_espresso'
598
-                                    ); ?>
596
+										'The Transaction ID sent back from the payment gateway, or the Cheque #',
597
+										'event_espresso'
598
+									); ?>
599 599
                                 </p>
600 600
                             </div>
601 601
                         </div>
@@ -613,9 +613,9 @@  discard block
 block discarded – undo
613 613
                                 />
614 614
                                 <p class="description">
615 615
                                     <?php esc_html_e(
616
-                                        'The gateway response string (optional)',
617
-                                        'event_espresso'
618
-                                    ); ?>
616
+										'The gateway response string (optional)',
617
+										'event_espresso'
618
+									); ?>
619 619
                                 </p>
620 620
                             </div>
621 621
                         </div>
@@ -624,9 +624,9 @@  discard block
 block discarded – undo
624 624
                             ee-layout-row">
625 625
                             <label for="txn-admin-payment-status-slct" class="">
626 626
                                 <?php esc_html_e(
627
-                                    'Payment Status',
628
-                                    'event_espresso'
629
-                                ); ?>
627
+									'Payment Status',
628
+									'event_espresso'
629
+								); ?>
630 630
                             </label>
631 631
                             <div class='ee-layout-stack'>
632 632
                                 <select name="txn_admin_payment[status]"
@@ -636,10 +636,10 @@  discard block
 block discarded – undo
636 636
                                 >
637 637
                                     <?php foreach ($payment_status as $STS_ID => $STS_code) : ?>
638 638
                                         <?php
639
-                                        $selected = $STS_ID == 'PAP'
640
-                                            ? 'selected'
641
-                                            : '';
642
-                                        ?>
639
+										$selected = $STS_ID == 'PAP'
640
+											? 'selected'
641
+											: '';
642
+										?>
643 643
                                         <option id="payment-status-opt-<?php echo esc_attr($STS_ID); ?>"
644 644
                                                 value="<?php echo esc_attr($STS_ID); ?>"
645 645
                                             <?php echo esc_attr($selected); ?>
@@ -650,10 +650,10 @@  discard block
 block discarded – undo
650 650
                                 </select>
651 651
                                 <p class="description">
652 652
                                     <?php
653
-                                    esc_html_e(
654
-                                        'Whether the payment was approved, cancelled, declined or failed after submission to the gateway',
655
-                                        'event_espresso'
656
-                                    ); ?>
653
+									esc_html_e(
654
+										'Whether the payment was approved, cancelled, declined or failed after submission to the gateway',
655
+										'event_espresso'
656
+									); ?>
657 657
                                 </p>
658 658
                             </div>
659 659
                         </div>
@@ -671,9 +671,9 @@  discard block
 block discarded – undo
671 671
                                 />
672 672
                                 <p class="description">
673 673
                                     <?php esc_html_e(
674
-                                        'The Purchase or Sales Order Number if any (optional)',
675
-                                        'event_espresso'
676
-                                    ); ?>
674
+										'The Purchase or Sales Order Number if any (optional)',
675
+										'event_espresso'
676
+									); ?>
677 677
                                 </p>
678 678
                             </div>
679 679
                         </div>
@@ -696,9 +696,9 @@  discard block
 block discarded – undo
696 696
                                 />
697 697
                                 <p class="description">
698 698
                                     <?php esc_html_e(
699
-                                        'An extra field you may use for accounting purposes or simple notes. Defaults to the primary registrant\'s registration code.',
700
-                                        'event_espresso'
701
-                                    ); ?>
699
+										'An extra field you may use for accounting purposes or simple notes. Defaults to the primary registrant\'s registration code.',
700
+										'event_espresso'
701
+									); ?>
702 702
                                 </p>
703 703
                             </div>
704 704
                         </div>
@@ -737,9 +737,9 @@  discard block
 block discarded – undo
737 737
                                 <?php echo wp_kses($status_change_select, AllowedTags::getWithFormTags()); ?>
738 738
                                 <p class="description">
739 739
                                     <?php esc_html_e(
740
-                                        'If you wish to change the status for the registrations selected above, then select which status from this dropdown.',
741
-                                        'event_espresso'
742
-                                    ); ?>
740
+										'If you wish to change the status for the registrations selected above, then select which status from this dropdown.',
741
+										'event_espresso'
742
+									); ?>
743 743
                                 </p>
744 744
                             </div>
745 745
                         </div>
@@ -770,14 +770,14 @@  discard block
 block discarded – undo
770 770
                                 <br class="clear-float" />
771 771
                                 <p class="description">
772 772
                                     <?php printf(
773
-                                        esc_html__(
774
-                                            'By default %1$sa payment message is sent to the primary registrant%2$s after submitting this form.%3$sHowever, if you check the "Registration Messages" box, the system will also send any related messages matching the status of the registrations to %1$seach registration for this transaction%2$s.',
775
-                                            'event_espresso'
776
-                                        ),
777
-                                        '<strong>',
778
-                                        '</strong>',
779
-                                        '<br />'
780
-                                    ); ?>
773
+										esc_html__(
774
+											'By default %1$sa payment message is sent to the primary registrant%2$s after submitting this form.%3$sHowever, if you check the "Registration Messages" box, the system will also send any related messages matching the status of the registrations to %1$seach registration for this transaction%2$s.',
775
+											'event_espresso'
776
+										),
777
+										'<strong>',
778
+										'</strong>',
779
+										'<br />'
780
+									); ?>
781 781
                                 </p>
782 782
                             </div>
783 783
                         </div>
@@ -832,10 +832,10 @@  discard block
 block discarded – undo
832 832
                 style="display:none;"
833 833
             >
834 834
                 <?php printf(
835
-                    esc_html__('Delete Payment/Refund for Transaction #', 'event_espresso'),
836
-                    $txn_nmbr['value']
837
-                );
838
-                ?>
835
+					esc_html__('Delete Payment/Refund for Transaction #', 'event_espresso'),
836
+					$txn_nmbr['value']
837
+				);
838
+				?>
839 839
                 <span class='dashicons dashicons-money-alt'></span>
840 840
             </h2>
841 841
 
@@ -874,13 +874,13 @@  discard block
 block discarded – undo
874 874
                                 <?php echo wp_kses($delete_status_change_select, AllowedTags::getWithFormTags()); ?>
875 875
                                 <p class="description">
876 876
                                     <?php printf(
877
-                                        esc_html__(
878
-                                            'If you wish to change the status of all the registrations associated with this transaction after deleting this payment/refund, then select which status from this dropdown. %sNote: ALL registrations associated with this transaction will be updated to this new status.%s',
879
-                                            'event_espresso'
880
-                                        ),
881
-                                        '<strong>',
882
-                                        '</strong>'
883
-                                    ); ?>
877
+										esc_html__(
878
+											'If you wish to change the status of all the registrations associated with this transaction after deleting this payment/refund, then select which status from this dropdown. %sNote: ALL registrations associated with this transaction will be updated to this new status.%s',
879
+											'event_espresso'
880
+										),
881
+										'<strong>',
882
+										'</strong>'
883
+									); ?>
884 884
                                 </p>
885 885
                             </div>
886 886
                         </div>
@@ -897,10 +897,10 @@  discard block
 block discarded – undo
897 897
                                 />
898 898
                                 <p class="description">
899 899
                                     <?php
900
-                                    esc_html_e(
901
-                                        'If you check this box, the system will send any related registration messages matching the status of the registrations to each registration for this transaction. No Payment notifications are sent when deleting a payment.',
902
-                                        'event_espresso'
903
-                                    ); ?>
900
+									esc_html_e(
901
+										'If you check this box, the system will send any related registration messages matching the status of the registrations to each registration for this transaction. No Payment notifications are sent when deleting a payment.',
902
+										'event_espresso'
903
+									); ?>
904 904
                                 </p>
905 905
                             </div>
906 906
                         </div>
@@ -928,8 +928,8 @@  discard block
 block discarded – undo
928 928
     <?php endif; // $grand_raw_total > 0?>
929 929
 
930 930
     <?php if (WP_DEBUG) {
931
-        $delivered_messages = get_option('EED_Messages__payment', []);
932
-        if (isset($delivered_messages[ $TXN_ID ])) { ?>
931
+		$delivered_messages = get_option('EED_Messages__payment', []);
932
+		if (isset($delivered_messages[ $TXN_ID ])) { ?>
933 933
             <h4 class="admin-primary-mbox-h4 hdr-has-icon">
934 934
                 <?php esc_html_e('Messages Sent to Primary Registrant', 'event_espresso'); ?>
935 935
                 <span class="dashicons dashicons-email-alt"></span>
@@ -941,39 +941,39 @@  discard block
 block discarded – undo
941 941
                             <th class="jst-left"><?php esc_html_e('Date & Time', 'event_espresso'); ?></th>
942 942
                             <th class="jst-left"><?php esc_html_e('Message Type', 'event_espresso'); ?></th>
943 943
                             <th class="jst-left"><?php esc_html_e(
944
-                                'Payment Status Upon Sending',
945
-                                'event_espresso'
946
-                            ); ?></th>
944
+								'Payment Status Upon Sending',
945
+								'event_espresso'
946
+							); ?></th>
947 947
                             <th class="jst-left"><?php esc_html_e('TXN Status Upon Sending', 'event_espresso'); ?></th>
948 948
                         </tr>
949 949
                     </thead>
950 950
                     <tbody>
951 951
                         <?php
952
-                        foreach ($delivered_messages[ $TXN_ID ] as $timestamp => $delivered_message) :
953
-                            ?>
952
+						foreach ($delivered_messages[ $TXN_ID ] as $timestamp => $delivered_message) :
953
+							?>
954 954
                             <tr>
955 955
                                 <td class="jst-left">
956 956
                                     <?php echo esc_html(
957
-                                        date(
958
-                                            get_option('date_format') . ' ' . get_option('time_format'),
959
-                                            ($timestamp + (get_option('gmt_offset') * HOUR_IN_SECONDS))
960
-                                        )
961
-                                    ); ?>
957
+										date(
958
+											get_option('date_format') . ' ' . get_option('time_format'),
959
+											($timestamp + (get_option('gmt_offset') * HOUR_IN_SECONDS))
960
+										)
961
+									); ?>
962 962
                                 </td>
963 963
                                 <td class="jst-left"><?php
964
-                                    echo isset($delivered_message['message_type'])
965
-                                        ? esc_html($delivered_message['message_type'])
966
-                                        : ''; ?>
964
+									echo isset($delivered_message['message_type'])
965
+										? esc_html($delivered_message['message_type'])
966
+										: ''; ?>
967 967
                                 </td>
968 968
                                 <td class="jst-left"><?php
969
-                                    echo isset($delivered_message['pay_status'])
970
-                                        ? esc_html($delivered_message['pay_status'])
971
-                                        : ''; ?>
969
+									echo isset($delivered_message['pay_status'])
970
+										? esc_html($delivered_message['pay_status'])
971
+										: ''; ?>
972 972
                                 </td>
973 973
                                 <td class="jst-left"><?php
974
-                                    echo isset($delivered_message['txn_status'])
975
-                                        ? esc_html($delivered_message['txn_status'])
976
-                                        : ''; ?>
974
+									echo isset($delivered_message['txn_status'])
975
+										? esc_html($delivered_message['txn_status'])
976
+										: ''; ?>
977 977
                                 </td>
978 978
                             </tr>
979 979
                         <?php endforeach; // $delivered_messages?>
@@ -981,7 +981,7 @@  discard block
 block discarded – undo
981 981
                 </table>
982 982
             </div>
983 983
             <?php
984
-        }
985
-    }
986
-    ?>
984
+		}
985
+	}
986
+	?>
987 987
 </div>
Please login to merge, or discard this patch.
admin_pages/transactions/Transactions_Admin_Page.core.php 1 patch
Indentation   +2548 added lines, -2548 removed lines patch added patch discarded remove patch
@@ -13,2552 +13,2552 @@
 block discarded – undo
13 13
  */
14 14
 class Transactions_Admin_Page extends EE_Admin_Page
15 15
 {
16
-    /**
17
-     * @var EE_Transaction
18
-     */
19
-    private $_transaction;
20
-
21
-    /**
22
-     * @var EE_Session
23
-     */
24
-    private $_session;
25
-
26
-    /**
27
-     * @var array $_txn_status
28
-     */
29
-    private static $_txn_status;
30
-
31
-    /**
32
-     * @var array $_pay_status
33
-     */
34
-    private static $_pay_status;
35
-
36
-    /**
37
-     * @var array $_existing_reg_payment_REG_IDs
38
-     */
39
-    protected $_existing_reg_payment_REG_IDs;
40
-
41
-
42
-    /**
43
-     *    _init_page_props
44
-     *
45
-     * @return void
46
-     */
47
-    protected function _init_page_props()
48
-    {
49
-        $this->page_slug        = TXN_PG_SLUG;
50
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
51
-        $this->_admin_base_url  = TXN_ADMIN_URL;
52
-        $this->_admin_base_path = TXN_ADMIN;
53
-    }
54
-
55
-
56
-    /**
57
-     *    _ajax_hooks
58
-     *
59
-     * @return void
60
-     */
61
-    protected function _ajax_hooks()
62
-    {
63
-        // add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
-        // add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
-        // add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
-    }
67
-
68
-
69
-    /**
70
-     *    _define_page_props
71
-     *
72
-     * @return void
73
-     */
74
-    protected function _define_page_props()
75
-    {
76
-        $this->_admin_page_title = $this->page_label;
77
-        $this->_labels           = [
78
-            'buttons' => [
79
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
-            ],
83
-        ];
84
-    }
85
-
86
-
87
-    /**
88
-     *        grab url requests and route them
89
-     *
90
-     * @access private
91
-     * @return void
92
-     * @throws EE_Error
93
-     * @throws InvalidArgumentException
94
-     * @throws InvalidDataTypeException
95
-     * @throws InvalidInterfaceException
96
-     * @throws ReflectionException
97
-     */
98
-    public function _set_page_routes()
99
-    {
100
-        $this->_set_transaction_status_array();
101
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
-
103
-        $this->_page_routes = [
104
-
105
-            'default' => [
106
-                'func'       => '_transactions_overview_list_table',
107
-                'capability' => 'ee_read_transactions',
108
-            ],
109
-
110
-            'view_transaction' => [
111
-                'func'       => '_transaction_details',
112
-                'capability' => 'ee_read_transaction',
113
-                'obj_id'     => $TXN_ID,
114
-            ],
115
-
116
-            'send_payment_reminder' => [
117
-                'func'       => '_send_payment_reminder',
118
-                'noheader'   => true,
119
-                'capability' => 'ee_send_message',
120
-            ],
121
-
122
-            'espresso_apply_payment' => [
123
-                'func'       => [$this, 'apply_payments_or_refunds'],
124
-                'noheader'   => true,
125
-                'capability' => 'ee_edit_payments',
126
-            ],
127
-
128
-            'espresso_apply_refund' => [
129
-                'func'       => [$this, 'apply_payments_or_refunds'],
130
-                'noheader'   => true,
131
-                'capability' => 'ee_edit_payments',
132
-            ],
133
-
134
-            'espresso_delete_payment' => [
135
-                'func'       => [$this, 'delete_payment'],
136
-                'noheader'   => true,
137
-                'capability' => 'ee_delete_payments',
138
-            ],
139
-
140
-            'espresso_recalculate_line_items' => [
141
-                'func'       => 'recalculateLineItems',
142
-                'noheader'   => true,
143
-                'capability' => 'ee_edit_payments',
144
-            ],
145
-
146
-        ];
147
-    }
148
-
149
-
150
-    protected function _set_page_config()
151
-    {
152
-        $TXN_ID             = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
-        $this->_page_config = [
154
-            'default'          => [
155
-                'nav'           => [
156
-                    'label' => esc_html__('Overview', 'event_espresso'),
157
-                    'icon'  => 'dashicons-list-view',
158
-                    'order' => 10,
159
-                ],
160
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
161
-                'help_tabs'     => [
162
-                    'transactions_overview_help_tab'                       => [
163
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
164
-                        'filename' => 'transactions_overview',
165
-                    ],
166
-                    'transactions_overview_table_column_headings_help_tab' => [
167
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
168
-                        'filename' => 'transactions_overview_table_column_headings',
169
-                    ],
170
-                    'transactions_overview_views_filters_help_tab'         => [
171
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
172
-                        'filename' => 'transactions_overview_views_filters_search',
173
-                    ],
174
-                ],
175
-                'require_nonce' => false,
176
-            ],
177
-            'view_transaction' => [
178
-                'nav'       => [
179
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
180
-                    'icon'       => 'dashicons-cart',
181
-                    'order'      => 5,
182
-                    'url'        => $TXN_ID
183
-                        ? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
184
-                        : $this->_admin_base_url,
185
-                    'persistent' => false,
186
-                ],
187
-                'help_tabs' => [
188
-                    'transactions_view_transaction_help_tab'                                              => [
189
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
190
-                        'filename' => 'transactions_view_transaction',
191
-                    ],
192
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => [
193
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
194
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
195
-                    ],
196
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => [
197
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
198
-                        'filename' => 'transactions_view_transaction_attendees_registered',
199
-                    ],
200
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
201
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
202
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
203
-                    ],
204
-                ],
205
-                'qtips'     => ['Transaction_Details_Tips'],
206
-                'metaboxes' => ['_transaction_details_metaboxes'],
207
-
208
-                'require_nonce' => false,
209
-            ],
210
-        ];
211
-    }
212
-
213
-
214
-    /**
215
-     * The below methods aren't used by this class currently
216
-     */
217
-    protected function _add_screen_options()
218
-    {
219
-        // noop
220
-    }
221
-
222
-
223
-    protected function _add_feature_pointers()
224
-    {
225
-        // noop
226
-    }
227
-
228
-
229
-    public function admin_init()
230
-    {
231
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
232
-        $event_name    = $this->request->getRequestParam('event_name');
233
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
234
-        // IF a registration was JUST added via the admin...
235
-        if ($EVT_ID && $event_name && $redirect_from) {
236
-            // then set a cookie so that we can block any attempts to use
237
-            // the back button as a way to enter another registration.
238
-            setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
239
-            // and update the global
240
-            $_COOKIE['ee_registration_added'] = $EVT_ID;
241
-        }
242
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
243
-            'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
244
-            'event_espresso'
245
-        );
246
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
247
-            'An error occurred! Please refresh the page and try again.',
248
-            'event_espresso'
249
-        );
250
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
251
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
252
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
253
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
254
-            'This transaction has been overpaid ! Payments Total',
255
-            'event_espresso'
256
-        );
257
-    }
258
-
259
-
260
-    public function admin_notices()
261
-    {
262
-        // noop
263
-    }
264
-
265
-
266
-    public function admin_footer_scripts()
267
-    {
268
-        // noop
269
-    }
270
-
271
-
272
-    /**
273
-     * _set_transaction_status_array
274
-     * sets list of transaction statuses
275
-     *
276
-     * @access private
277
-     * @return void
278
-     * @throws EE_Error
279
-     * @throws InvalidArgumentException
280
-     * @throws InvalidDataTypeException
281
-     * @throws InvalidInterfaceException
282
-     * @throws ReflectionException
283
-     */
284
-    private function _set_transaction_status_array()
285
-    {
286
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
287
-    }
288
-
289
-
290
-    /**
291
-     * get_transaction_status_array
292
-     * return the transaction status array for wp_list_table
293
-     *
294
-     * @access public
295
-     * @return array
296
-     */
297
-    public function get_transaction_status_array()
298
-    {
299
-        return self::$_txn_status;
300
-    }
301
-
302
-
303
-    /**
304
-     *    get list of payment statuses
305
-     *
306
-     * @access private
307
-     * @return void
308
-     * @throws EE_Error
309
-     * @throws InvalidArgumentException
310
-     * @throws InvalidDataTypeException
311
-     * @throws InvalidInterfaceException
312
-     * @throws ReflectionException
313
-     */
314
-    private function _get_payment_status_array()
315
-    {
316
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
317
-        $this->_template_args['payment_status'] = self::$_pay_status;
318
-    }
319
-
320
-
321
-    /**
322
-     *    _add_screen_options_default
323
-     *
324
-     * @access protected
325
-     * @return void
326
-     * @throws InvalidArgumentException
327
-     * @throws InvalidDataTypeException
328
-     * @throws InvalidInterfaceException
329
-     */
330
-    protected function _add_screen_options_default()
331
-    {
332
-        $this->_per_page_screen_option();
333
-    }
334
-
335
-
336
-    /**
337
-     * load_scripts_styles
338
-     *
339
-     * @access public
340
-     * @return void
341
-     */
342
-    public function load_scripts_styles()
343
-    {
344
-        // enqueue style
345
-        wp_register_style(
346
-            'espresso_txn',
347
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
348
-            [],
349
-            EVENT_ESPRESSO_VERSION
350
-        );
351
-        wp_enqueue_style('espresso_txn');
352
-        // scripts
353
-        wp_register_script(
354
-            'espresso_txn',
355
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
356
-            [
357
-                'ee_admin_js',
358
-                'ee-datepicker',
359
-                'jquery-ui-datepicker',
360
-                'jquery-ui-draggable',
361
-                'ee-dialog',
362
-                'ee-accounting',
363
-                'ee-serialize-full-array',
364
-            ],
365
-            EVENT_ESPRESSO_VERSION,
366
-            true
367
-        );
368
-        wp_enqueue_script('espresso_txn');
369
-    }
370
-
371
-
372
-    /**
373
-     *    load_scripts_styles_view_transaction
374
-     *
375
-     * @access public
376
-     * @return void
377
-     */
378
-    public function load_scripts_styles_view_transaction()
379
-    {
380
-        // styles
381
-        wp_enqueue_style('espresso-ui-theme');
382
-    }
383
-
384
-
385
-    /**
386
-     *    load_scripts_styles_default
387
-     *
388
-     * @access public
389
-     * @return void
390
-     */
391
-    public function load_scripts_styles_default()
392
-    {
393
-        // styles
394
-        wp_enqueue_style('espresso-ui-theme');
395
-    }
396
-
397
-
398
-    /**
399
-     *    _set_list_table_views_default
400
-     *
401
-     * @access protected
402
-     * @return void
403
-     */
404
-    protected function _set_list_table_views_default()
405
-    {
406
-        $this->_views = [
407
-            'all'        => [
408
-                'slug'  => 'all',
409
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
410
-                'count' => 0,
411
-            ],
412
-            'abandoned'  => [
413
-                'slug'  => 'abandoned',
414
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
415
-                'count' => 0,
416
-            ],
417
-            'incomplete' => [
418
-                'slug'  => 'incomplete',
419
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
420
-                'count' => 0,
421
-            ],
422
-        ];
423
-        if (
424
-            /**
425
-             * Filters whether a link to the "Failed Transactions" list table
426
-             * appears on the Transactions Admin Page list table.
427
-             * List display can be turned back on via the following:
428
-             * add_filter(
429
-             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
430
-             *     '__return_true'
431
-             * );
432
-             *
433
-             * @param boolean                 $display_failed_txns_list
434
-             * @param Transactions_Admin_Page $this
435
-             * @since 4.9.70.p
436
-             */
437
-        apply_filters(
438
-            'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
439
-            false,
440
-            $this
441
-        )
442
-        ) {
443
-            $this->_views['failed'] = [
444
-                'slug'  => 'failed',
445
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
446
-                'count' => 0,
447
-            ];
448
-        }
449
-    }
450
-
451
-
452
-    /**
453
-     * _set_transaction_object
454
-     * This sets the _transaction property for the transaction details screen
455
-     *
456
-     * @access private
457
-     * @return void
458
-     * @throws EE_Error
459
-     * @throws InvalidArgumentException
460
-     * @throws RuntimeException
461
-     * @throws InvalidDataTypeException
462
-     * @throws InvalidInterfaceException
463
-     * @throws ReflectionException
464
-     */
465
-    private function _set_transaction_object()
466
-    {
467
-        if ($this->_transaction instanceof EE_Transaction) {
468
-            return;
469
-        } //get out we've already set the object
470
-
471
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
472
-
473
-        // get transaction object
474
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
475
-        $this->_session     = $this->_transaction instanceof EE_Transaction
476
-            ? $this->_transaction->session_data()
477
-            : null;
478
-        if ($this->_transaction instanceof EE_Transaction) {
479
-            $this->_transaction->verify_abandoned_transaction_status();
480
-        }
481
-
482
-        if (! $this->_transaction instanceof EE_Transaction) {
483
-            $error_msg = sprintf(
484
-                esc_html__(
485
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
486
-                    'event_espresso'
487
-                ),
488
-                $TXN_ID
489
-            );
490
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
491
-        }
492
-    }
493
-
494
-
495
-    /**
496
-     *    _transaction_legend_items
497
-     *
498
-     * @access protected
499
-     * @return array
500
-     * @throws EE_Error
501
-     * @throws InvalidArgumentException
502
-     * @throws ReflectionException
503
-     * @throws InvalidDataTypeException
504
-     * @throws InvalidInterfaceException
505
-     */
506
-    protected function _transaction_legend_items()
507
-    {
508
-        EE_Registry::instance()->load_helper('MSG_Template');
509
-        $items = [];
510
-
511
-        if (
512
-            $this->capabilities->current_user_can(
513
-                'ee_read_global_messages',
514
-                'view_filtered_messages'
515
-            )
516
-        ) {
517
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
518
-            if (
519
-                is_array($related_for_icon)
520
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
521
-            ) {
522
-                $items['view_related_messages'] = [
523
-                    'class' => $related_for_icon['css_class'],
524
-                    'desc'  => $related_for_icon['label'],
525
-                ];
526
-            }
527
-        }
528
-
529
-        $items = apply_filters(
530
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
531
-            array_merge(
532
-                $items,
533
-                [
534
-                    'view_details'          => [
535
-                        'class' => 'dashicons dashicons-cart',
536
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
537
-                    ],
538
-                    'view_invoice'          => [
539
-                        'class' => 'dashicons dashicons-media-spreadsheet',
540
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
541
-                    ],
542
-                    'view_receipt'          => [
543
-                        'class' => 'dashicons dashicons-text-page',
544
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
545
-                    ],
546
-                    'view_registration'     => [
547
-                        'class' => 'dashicons dashicons-clipboard',
548
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
549
-                    ],
550
-                    'payment_overview_link' => [
551
-                        'class' => 'dashicons dashicons-money',
552
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
553
-                    ],
554
-                ]
555
-            )
556
-        );
557
-
558
-        if (
559
-            EEH_MSG_Template::is_mt_active('payment_reminder')
560
-            && $this->capabilities->current_user_can(
561
-                'ee_send_message',
562
-                'espresso_transactions_send_payment_reminder'
563
-            )
564
-        ) {
565
-            $items['send_payment_reminder'] = [
566
-                'class' => 'dashicons dashicons-email-alt',
567
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
568
-            ];
569
-        } else {
570
-            $items['blank*'] = [
571
-                'class' => '',
572
-                'desc'  => '',
573
-            ];
574
-        }
575
-        $more_items = apply_filters(
576
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
577
-            [
578
-                'overpaid'   => [
579
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
580
-                    'desc'  => EEH_Template::pretty_status(
581
-                        EEM_Transaction::overpaid_status_code,
582
-                        false,
583
-                        'sentence'
584
-                    ),
585
-                ],
586
-                'complete'   => [
587
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
588
-                    'desc'  => EEH_Template::pretty_status(
589
-                        EEM_Transaction::complete_status_code,
590
-                        false,
591
-                        'sentence'
592
-                    ),
593
-                ],
594
-                'incomplete' => [
595
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
596
-                    'desc'  => EEH_Template::pretty_status(
597
-                        EEM_Transaction::incomplete_status_code,
598
-                        false,
599
-                        'sentence'
600
-                    ),
601
-                ],
602
-                'abandoned'  => [
603
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
604
-                    'desc'  => EEH_Template::pretty_status(
605
-                        EEM_Transaction::abandoned_status_code,
606
-                        false,
607
-                        'sentence'
608
-                    ),
609
-                ],
610
-                'failed'     => [
611
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
612
-                    'desc'  => EEH_Template::pretty_status(
613
-                        EEM_Transaction::failed_status_code,
614
-                        false,
615
-                        'sentence'
616
-                    ),
617
-                ],
618
-            ]
619
-        );
620
-
621
-        return array_merge($items, $more_items);
622
-    }
623
-
624
-
625
-    /**
626
-     *    _transactions_overview_list_table
627
-     *
628
-     * @access protected
629
-     * @return void
630
-     * @throws DomainException
631
-     * @throws EE_Error
632
-     * @throws InvalidArgumentException
633
-     * @throws InvalidDataTypeException
634
-     * @throws InvalidInterfaceException
635
-     * @throws ReflectionException
636
-     */
637
-    protected function _transactions_overview_list_table()
638
-    {
639
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
640
-
641
-        $EVT_ID                                    = $this->request->getRequestParam('EVT_ID', 0, 'int');
642
-        $event                                     = EEM_Event::instance()->get_one_by_ID($EVT_ID);
643
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
644
-            ? sprintf(
645
-                esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
646
-                '<h3>',
647
-                '<a href="'
648
-                . EE_Admin_Page::add_query_args_and_nonce(
649
-                    ['action' => 'edit', 'post' => $event->ID()],
650
-                    EVENTS_ADMIN_URL
651
-                )
652
-                . '" aria-label="'
653
-                . esc_attr__('Click to Edit event', 'event_espresso')
654
-                . '">' . $event->name() . '</a>',
655
-                '</h3>'
656
-            )
657
-            : '';
658
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
659
-        $this->display_admin_list_table_page_with_no_sidebar();
660
-    }
661
-
662
-
663
-    /**
664
-     *    _transaction_details
665
-     * generates HTML for the View Transaction Details Admin page
666
-     *
667
-     * @access protected
668
-     * @return void
669
-     * @throws DomainException
670
-     * @throws EE_Error
671
-     * @throws InvalidArgumentException
672
-     * @throws InvalidDataTypeException
673
-     * @throws InvalidInterfaceException
674
-     * @throws RuntimeException
675
-     * @throws ReflectionException
676
-     */
677
-    protected function _transaction_details()
678
-    {
679
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
680
-
681
-        $this->_set_transaction_status_array();
682
-
683
-        $this->_template_args                      = [];
684
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
685
-
686
-        $this->_set_transaction_object();
687
-
688
-        if (! $this->_transaction instanceof EE_Transaction) {
689
-            return;
690
-        }
691
-
692
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
693
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
694
-
695
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
696
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
697
-
698
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
699
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
700
-        $this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
701
-
702
-        $txn_total  = $this->_transaction->total();
703
-        $total_paid = $this->_transaction->paid();
704
-        $amount_due = $txn_total - $total_paid;
705
-
706
-        $this->_template_args['grand_total'] = $txn_total;
707
-        $this->_template_args['total_paid']  = $total_paid;
708
-
709
-        $this->_template_args['amount_due']     = EEH_Template::format_currency($amount_due, false, false);
710
-        $this->_template_args['amount_due_raw'] = $amount_due;
711
-
712
-        $this->_template_args['amount_due_class'] = '';
713
-
714
-        if ($txn_total === (float) 0) {
715
-            // free event
716
-            $this->_template_args['amount_due'] = false;
717
-        } elseif ($amount_due < (float) 0) {
718
-            // overpaid
719
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
720
-        } elseif ($amount_due > (float) 0) {
721
-            // monies owing
722
-            $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
723
-        } elseif ($total_paid === (float) 0) {
724
-            // no payments made yet
725
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
726
-        }
727
-
728
-        $payment_method = $this->_transaction->payment_method();
729
-
730
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
731
-            ? $payment_method->admin_name()
732
-            : esc_html__('Unknown', 'event_espresso');
733
-
734
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
735
-        // link back to overview
736
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
737
-            'HTTP_REFERER',
738
-            TXN_ADMIN_URL
739
-        );
740
-
741
-
742
-        // next link
743
-        $next_txn                                 = $this->_transaction->next(
744
-            null,
745
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
746
-            'TXN_ID'
747
-        );
748
-        $this->_template_args['next_transaction'] = $next_txn
749
-            ? $this->_next_link(
750
-                EE_Admin_Page::add_query_args_and_nonce(
751
-                    ['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
752
-                    TXN_ADMIN_URL
753
-                ),
754
-                'dashicons dashicons-arrow-right ee-icon-size-22'
755
-            )
756
-            : '';
757
-        // previous link
758
-        $previous_txn                                 = $this->_transaction->previous(
759
-            null,
760
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
761
-            'TXN_ID'
762
-        );
763
-        $this->_template_args['previous_transaction'] = $previous_txn
764
-            ? $this->_previous_link(
765
-                EE_Admin_Page::add_query_args_and_nonce(
766
-                    ['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
767
-                    TXN_ADMIN_URL
768
-                ),
769
-                'dashicons dashicons-arrow-left ee-icon-size-22'
770
-            )
771
-            : '';
772
-
773
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
774
-        $event_name    = $this->request->getRequestParam('event_name');
775
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
776
-
777
-        // were we just redirected here after adding a new registration ???
778
-        if ($EVT_ID && $event_name && $redirect_from) {
779
-            if (
780
-                $this->capabilities->current_user_can(
781
-                    'ee_edit_registrations',
782
-                    'espresso_registrations_new_registration',
783
-                    $EVT_ID
784
-                )
785
-            ) {
786
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
787
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
788
-                    [
789
-                        'page'     => 'espresso_registrations',
790
-                        'action'   => 'new_registration',
791
-                        'return'   => 'default',
792
-                        'TXN_ID'   => $this->_transaction->ID(),
793
-                        'event_id' => $EVT_ID,
794
-                    ],
795
-                    REG_ADMIN_URL
796
-                );
797
-                $this->_admin_page_title .= '">';
798
-
799
-                $this->_admin_page_title .= sprintf(
800
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
801
-                    htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
802
-                );
803
-                $this->_admin_page_title .= '</a>';
804
-            }
805
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
806
-        }
807
-        // grab messages at the last second
808
-        $this->_template_args['notices'] = EE_Error::get_notices();
809
-        // path to template
810
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
811
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
812
-            $template_path,
813
-            $this->_template_args,
814
-            true
815
-        );
816
-
817
-        // the details template wrapper
818
-        $this->display_admin_page_with_sidebar();
819
-    }
820
-
821
-
822
-    /**
823
-     *        _transaction_details_metaboxes
824
-     *
825
-     * @access protected
826
-     * @return void
827
-     * @throws EE_Error
828
-     * @throws InvalidArgumentException
829
-     * @throws InvalidDataTypeException
830
-     * @throws InvalidInterfaceException
831
-     * @throws RuntimeException
832
-     * @throws ReflectionException
833
-     */
834
-    protected function _transaction_details_metaboxes()
835
-    {
836
-        $this->_set_transaction_object();
837
-
838
-        if (! $this->_transaction instanceof EE_Transaction) {
839
-            return;
840
-        }
841
-        $this->addMetaBox(
842
-            'edit-txn-details-mbox',
843
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
844
-            . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
845
-            [$this, 'txn_details_meta_box'],
846
-            $this->_wp_page_slug
847
-        );
848
-        $this->addMetaBox(
849
-            'edit-txn-attendees-mbox',
850
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
851
-            . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
852
-            [$this, 'txn_attendees_meta_box'],
853
-            $this->_wp_page_slug,
854
-            'normal',
855
-            'high',
856
-            ['TXN_ID' => $this->_transaction->ID()]
857
-        );
858
-        $this->addMetaBox(
859
-            'edit-txn-registrant-mbox',
860
-            esc_html__('Primary Contact', 'event_espresso'),
861
-            [$this, 'txn_registrant_side_meta_box'],
862
-            $this->_wp_page_slug,
863
-            'side'
864
-        );
865
-        $this->addMetaBox(
866
-            'edit-txn-billing-info-mbox',
867
-            esc_html__('Billing Information', 'event_espresso'),
868
-            [$this, 'txn_billing_info_side_meta_box'],
869
-            $this->_wp_page_slug,
870
-            'side'
871
-        );
872
-    }
873
-
874
-
875
-    /**
876
-     * Callback for transaction actions metabox.
877
-     *
878
-     * @param EE_Transaction|null $transaction
879
-     * @return string
880
-     * @throws DomainException
881
-     * @throws EE_Error
882
-     * @throws InvalidArgumentException
883
-     * @throws InvalidDataTypeException
884
-     * @throws InvalidInterfaceException
885
-     * @throws ReflectionException
886
-     * @throws RuntimeException
887
-     */
888
-    public function getActionButtons(EE_Transaction $transaction = null)
889
-    {
890
-        $content = '';
891
-        $actions = [];
892
-        if (! $transaction instanceof EE_Transaction) {
893
-            return $content;
894
-        }
895
-        /** @var EE_Registration $primary_registration */
896
-        $primary_registration = $transaction->primary_registration();
897
-        $attendee             = $primary_registration instanceof EE_Registration
898
-            ? $primary_registration->attendee()
899
-            : null;
900
-
901
-        if (
902
-            $attendee instanceof EE_Attendee
903
-            && $this->capabilities->current_user_can(
904
-                'ee_send_message',
905
-                'espresso_transactions_send_payment_reminder'
906
-            )
907
-        ) {
908
-            $actions['payment_reminder'] =
909
-                EEH_MSG_Template::is_mt_active('payment_reminder')
910
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
911
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
912
-                    ? EEH_Template::get_button_or_link(
913
-                    EE_Admin_Page::add_query_args_and_nonce(
914
-                        [
915
-                            'action'      => 'send_payment_reminder',
916
-                            'TXN_ID'      => $this->_transaction->ID(),
917
-                            'redirect_to' => 'view_transaction',
918
-                        ],
919
-                        TXN_ADMIN_URL
920
-                    ),
921
-                    esc_html__(' Send Payment Reminder', 'event_espresso'),
922
-                    'button button--secondary',
923
-                    'dashicons dashicons-email-alt'
924
-                )
925
-                    : '';
926
-        }
927
-
928
-        if (
929
-            $this->capabilities->current_user_can(
930
-                'ee_edit_payments',
931
-                'espresso_transactions_recalculate_line_items'
932
-            )
933
-        ) {
934
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
935
-                EE_Admin_Page::add_query_args_and_nonce(
936
-                    [
937
-                        'action'      => 'espresso_recalculate_line_items',
938
-                        'TXN_ID'      => $this->_transaction->ID(),
939
-                        'redirect_to' => 'view_transaction',
940
-                    ],
941
-                    TXN_ADMIN_URL
942
-                ),
943
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
944
-                'button button--secondary',
945
-                'dashicons dashicons-update'
946
-            );
947
-        }
948
-
949
-        if (
950
-            $primary_registration instanceof EE_Registration
951
-            && EEH_MSG_Template::is_mt_active('receipt')
952
-        ) {
953
-            $actions['receipt'] = EEH_Template::get_button_or_link(
954
-                $primary_registration->receipt_url(),
955
-                esc_html__('View Receipt', 'event_espresso'),
956
-                'button button--secondary',
957
-                'dashicons dashicons-text-page'
958
-            );
959
-        }
960
-
961
-        if (
962
-            $primary_registration instanceof EE_Registration
963
-            && EEH_MSG_Template::is_mt_active('invoice')
964
-        ) {
965
-            $actions['invoice'] = EEH_Template::get_button_or_link(
966
-                $primary_registration->invoice_url(),
967
-                esc_html__('View Invoice', 'event_espresso'),
968
-                'button button--secondary',
969
-                'dashicons dashicons-media-spreadsheet'
970
-            );
971
-        }
972
-        $actions = array_filter(
973
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
974
-        );
975
-        if ($actions) {
976
-            $content .= implode('', $actions);
977
-        }
978
-        return $content;
979
-    }
980
-
981
-
982
-    /**
983
-     * txn_details_meta_box
984
-     * generates HTML for the Transaction main meta box
985
-     *
986
-     * @return void
987
-     * @throws DomainException
988
-     * @throws EE_Error
989
-     * @throws InvalidArgumentException
990
-     * @throws InvalidDataTypeException
991
-     * @throws InvalidInterfaceException
992
-     * @throws RuntimeException
993
-     * @throws ReflectionException
994
-     */
995
-    public function txn_details_meta_box()
996
-    {
997
-        $this->_set_transaction_object();
998
-        $this->_template_args['TXN_ID']              = $this->_transaction->ID();
999
-        $this->_template_args['attendee']            =
1000
-            $this->_transaction->primary_registration() instanceof EE_Registration
1001
-                ? $this->_transaction->primary_registration()->attendee()
1002
-                : null;
1003
-        $this->_template_args['can_edit_payments']   = $this->capabilities->current_user_can(
1004
-            'ee_edit_payments',
1005
-            'apply_payment_or_refund_from_registration_details'
1006
-        );
1007
-        $this->_template_args['can_delete_payments'] = $this->capabilities->current_user_can(
1008
-            'ee_delete_payments',
1009
-            'delete_payment_from_registration_details'
1010
-        );
1011
-
1012
-        // get line table
1013
-        EEH_Autoloader::register_line_item_display_autoloaders();
1014
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1015
-            'admin_table',
1016
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1017
-        );
1018
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1019
-            $this->_transaction->total_line_item()
1020
-        );
1021
-        $this->_template_args['REG_code']        =
1022
-            $this->_transaction->primary_registration() instanceof EE_Registration
1023
-                ? $this->_transaction->primary_registration()->reg_code()
1024
-                : null;
1025
-        // process taxes
1026
-        $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1027
-        $this->_template_args['taxes'] = ! empty($taxes)
1028
-            ? $taxes
1029
-            : false;
1030
-
1031
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1032
-            $this->_transaction->total(),
1033
-            false,
1034
-            false
1035
-        );
1036
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1037
-        $this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1038
-
1039
-        // process payment details
1040
-        $payments = $this->_transaction->payments();
1041
-        if (! empty($payments)) {
1042
-            $this->_template_args['payments']              = $payments;
1043
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1044
-        } else {
1045
-            $this->_template_args['payments']              = false;
1046
-            $this->_template_args['existing_reg_payments'] = [];
1047
-        }
1048
-
1049
-        $this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1050
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1051
-            ['action' => 'espresso_delete_payment'],
1052
-            TXN_ADMIN_URL
1053
-        );
1054
-
1055
-        if (isset($txn_details['invoice_number'])) {
1056
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1057
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1058
-                'Invoice Number',
1059
-                'event_espresso'
1060
-            );
1061
-        }
1062
-
1063
-        $this->_template_args['txn_details']['registration_session']['value'] =
1064
-            $this->_transaction->primary_registration() instanceof EE_Registration
1065
-                ? $this->_transaction->primary_registration()->session_ID()
1066
-                : null;
1067
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1068
-            'Registration Session',
1069
-            'event_espresso'
1070
-        );
1071
-
1072
-        $this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1073
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1074
-            'Transaction placed from IP',
1075
-            'event_espresso'
1076
-        );
1077
-
1078
-        $this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1079
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1080
-            'Registrant User Agent',
1081
-            'event_espresso'
1082
-        );
1083
-
1084
-        $reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1085
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1086
-            if ($reg_step_status === true) {
1087
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1088
-                              . sprintf(
1089
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1090
-                                  ucwords(str_replace('_', ' ', $reg_step))
1091
-                              )
1092
-                              . '</div>';
1093
-            } elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1094
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1095
-                              . sprintf(
1096
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1097
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1098
-                                  date(
1099
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1100
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1101
-                                  )
1102
-                              )
1103
-                              . '</div>';
1104
-            } else {
1105
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1106
-                              . sprintf(
1107
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1108
-                                  ucwords(str_replace('_', ' ', $reg_step))
1109
-                              )
1110
-                              . '</div>';
1111
-            }
1112
-        }
1113
-        $reg_steps                                                 .= '</ul>';
1114
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1115
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1116
-            'Registration Step Progress',
1117
-            'event_espresso'
1118
-        );
1119
-
1120
-
1121
-        $this->_get_registrations_to_apply_payment_to();
1122
-        $this->_get_payment_methods($payments);
1123
-        $this->_get_payment_status_array();
1124
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1125
-
1126
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1127
-            [
1128
-                'action'  => 'edit_transaction',
1129
-                'process' => 'transaction',
1130
-            ],
1131
-            TXN_ADMIN_URL
1132
-        );
1133
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1134
-            [
1135
-                'page'   => 'espresso_transactions',
1136
-                'action' => 'espresso_apply_payment',
1137
-            ],
1138
-            TXN_ADMIN_URL
1139
-        );
1140
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1141
-            [
1142
-                'page'   => 'espresso_transactions',
1143
-                'action' => 'espresso_delete_payment',
1144
-            ],
1145
-            TXN_ADMIN_URL
1146
-        );
1147
-
1148
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1149
-
1150
-        // 'espresso_delete_payment_nonce'
1151
-
1152
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1153
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1154
-    }
1155
-
1156
-
1157
-    /**
1158
-     * _get_registration_payment_IDs
1159
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1160
-     *
1161
-     * @access protected
1162
-     * @param EE_Payment[] $payments
1163
-     * @return array
1164
-     * @throws EE_Error
1165
-     * @throws InvalidArgumentException
1166
-     * @throws InvalidDataTypeException
1167
-     * @throws InvalidInterfaceException
1168
-     * @throws ReflectionException
1169
-     */
1170
-    protected function _get_registration_payment_IDs($payments = [])
1171
-    {
1172
-        $existing_reg_payments = [];
1173
-        // get all reg payments for these payments
1174
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1175
-            [
1176
-                [
1177
-                    'PAY_ID' => [
1178
-                        'IN',
1179
-                        array_keys($payments),
1180
-                    ],
1181
-                ],
1182
-            ]
1183
-        );
1184
-        if (! empty($reg_payments)) {
1185
-            foreach ($payments as $payment) {
1186
-                if (! $payment instanceof EE_Payment) {
1187
-                    continue;
1188
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1189
-                    $existing_reg_payments[ $payment->ID() ] = [];
1190
-                }
1191
-                foreach ($reg_payments as $reg_payment) {
1192
-                    if (
1193
-                        $reg_payment instanceof EE_Registration_Payment
1194
-                        && $reg_payment->payment_ID() === $payment->ID()
1195
-                    ) {
1196
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1197
-                    }
1198
-                }
1199
-            }
1200
-        }
1201
-
1202
-        return $existing_reg_payments;
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * _get_registrations_to_apply_payment_to
1208
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1209
-     * which allows the admin to only apply the payment to the specific registrations
1210
-     *
1211
-     * @access protected
1212
-     * @return void
1213
-     * @throws EE_Error
1214
-     * @throws InvalidArgumentException
1215
-     * @throws InvalidDataTypeException
1216
-     * @throws InvalidInterfaceException
1217
-     * @throws ReflectionException
1218
-     */
1219
-    protected function _get_registrations_to_apply_payment_to()
1220
-    {
1221
-        // we want any registration with an active status (ie: not deleted or cancelled)
1222
-        $query_params                      = [
1223
-            [
1224
-                'STS_ID' => [
1225
-                    'IN',
1226
-                    [
1227
-                        EEM_Registration::status_id_approved,
1228
-                        EEM_Registration::status_id_pending_payment,
1229
-                        EEM_Registration::status_id_not_approved,
1230
-                    ],
1231
-                ],
1232
-            ],
1233
-        ];
1234
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1235
-                '',
1236
-                'txn-admin-apply-payment-to-registrations-dv',
1237
-                '',
1238
-                'clear: both; margin: 1.5em 0 0; display: none;'
1239
-            );
1240
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1241
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1242
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1243
-            EEH_HTML::tr(
1244
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1245
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1246
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1247
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1248
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1249
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1250
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1251
-            )
1252
-        );
1253
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1254
-        // get registrations for TXN
1255
-        $registrations         = $this->_transaction->registrations($query_params);
1256
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1257
-        foreach ($registrations as $registration) {
1258
-            if ($registration instanceof EE_Registration) {
1259
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
1260
-                    ? $registration->attendee()->full_name()
1261
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1262
-                $owing                             = $registration->final_price() - $registration->paid();
1263
-                $taxable                           = $registration->ticket()->taxable()
1264
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1265
-                    : '';
1266
-                $checked                           = empty($existing_reg_payments)
1267
-                                                     || in_array($registration->ID(), $existing_reg_payments, true)
1268
-                    ? ' checked'
1269
-                    : '';
1270
-                $disabled                          = $registration->final_price() > 0
1271
-                    ? ''
1272
-                    : ' disabled';
1273
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1274
-                    EEH_HTML::td($registration->ID()) .
1275
-                    EEH_HTML::td($attendee_name) .
1276
-                    EEH_HTML::td(
1277
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1278
-                    ) .
1279
-                    EEH_HTML::td($registration->event_name()) .
1280
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1281
-                    EEH_HTML::td(
1282
-                        EEH_Template::format_currency($owing),
1283
-                        '',
1284
-                        'txn-admin-payment-owing-td jst-cntr'
1285
-                    ) .
1286
-                    EEH_HTML::td(
1287
-                        '<input type="checkbox" value="' . $registration->ID()
1288
-                        . '" name="txn_admin_payment[registrations]"'
1289
-                        . $checked . $disabled . '>',
1290
-                        '',
1291
-                        'jst-cntr'
1292
-                    ),
1293
-                    'apply-payment-registration-row-' . $registration->ID()
1294
-                );
1295
-            }
1296
-        }
1297
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1298
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1299
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1300
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1301
-            esc_html__(
1302
-                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1303
-                'event_espresso'
1304
-            ),
1305
-            '',
1306
-            'clear description'
1307
-        );
1308
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1309
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1310
-    }
1311
-
1312
-
1313
-    /**
1314
-     * _get_reg_status_selection
1315
-     *
1316
-     * @return void
1317
-     * @throws EE_Error
1318
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1319
-     *         instead of events.
1320
-     * @access protected
1321
-     */
1322
-    protected function _get_reg_status_selection()
1323
-    {
1324
-        // first get all possible statuses
1325
-        $statuses = EEM_Registration::reg_status_array([], true);
1326
-        // let's add a "don't change" option.
1327
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1328
-        $status_array                                        = array_merge($status_array, $statuses);
1329
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1330
-            'txn_reg_status_change[reg_status]',
1331
-            $status_array,
1332
-            'NAN',
1333
-            'id="txn-admin-payment-reg-status-inp"',
1334
-            'txn-reg-status-change-reg-status'
1335
-        );
1336
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1337
-            'delete_txn_reg_status_change[reg_status]',
1338
-            $status_array,
1339
-            'NAN',
1340
-            'delete-txn-admin-payment-reg-status-inp',
1341
-            'delete-txn-reg-status-change-reg-status'
1342
-        );
1343
-    }
1344
-
1345
-
1346
-    /**
1347
-     *    _get_payment_methods
1348
-     * Gets all the payment methods available generally, or the ones that are already
1349
-     * selected on these payments (in case their payment methods are no longer active).
1350
-     * Has the side-effect of updating the template args' payment_methods item
1351
-     *
1352
-     * @access private
1353
-     * @param EE_Payment[] to show on this page
1354
-     * @return void
1355
-     * @throws EE_Error
1356
-     * @throws InvalidArgumentException
1357
-     * @throws InvalidDataTypeException
1358
-     * @throws InvalidInterfaceException
1359
-     * @throws ReflectionException
1360
-     */
1361
-    private function _get_payment_methods($payments = [])
1362
-    {
1363
-        $payment_methods_of_payments = [];
1364
-        foreach ($payments as $payment) {
1365
-            if ($payment instanceof EE_Payment) {
1366
-                $payment_methods_of_payments[] = $payment->ID();
1367
-            }
1368
-        }
1369
-        if ($payment_methods_of_payments) {
1370
-            $query_args = [
1371
-                [
1372
-                    'OR*payment_method_for_payment' => [
1373
-                        'PMD_ID'    => ['IN', $payment_methods_of_payments],
1374
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1375
-                    ],
1376
-                ],
1377
-            ];
1378
-        } else {
1379
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1380
-        }
1381
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1382
-    }
1383
-
1384
-
1385
-    /**
1386
-     * txn_attendees_meta_box
1387
-     *    generates HTML for the Attendees Transaction main meta box
1388
-     *
1389
-     * @access public
1390
-     * @param WP_Post $post
1391
-     * @param array   $metabox
1392
-     * @return void
1393
-     * @throws DomainException
1394
-     * @throws EE_Error
1395
-     * @throws InvalidArgumentException
1396
-     * @throws InvalidDataTypeException
1397
-     * @throws InvalidInterfaceException
1398
-     * @throws ReflectionException
1399
-     */
1400
-    public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1401
-    {
1402
-        /** @noinspection NonSecureExtractUsageInspection */
1403
-        extract($metabox['args']);
1404
-        $this->_template_args['post']            = $post;
1405
-        $this->_template_args['event_attendees'] = [];
1406
-        // process items in cart
1407
-        $line_items = $this->_transaction->get_many_related(
1408
-            'Line_Item',
1409
-            [['LIN_type' => 'line-item']]
1410
-        );
1411
-        if (! empty($line_items)) {
1412
-            foreach ($line_items as $item) {
1413
-                if ($item instanceof EE_Line_Item) {
1414
-                    switch ($item->OBJ_type()) {
1415
-                        case 'Event':
1416
-                            break;
1417
-                        case 'Ticket':
1418
-                            $ticket = $item->ticket();
1419
-                            // right now we're only handling tickets here.
1420
-                            // Cause its expected that only tickets will have attendees right?
1421
-                            if (! $ticket instanceof EE_Ticket) {
1422
-                                break;
1423
-                            }
1424
-                            try {
1425
-                                $event_name = $ticket->get_event_name();
1426
-                            } catch (Exception $e) {
1427
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1428
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1429
-                            }
1430
-                            $event_name   .= ' - ' . $item->name();
1431
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1432
-                            // now get all of the registrations for this transaction that use this ticket
1433
-                            $registrations = $ticket->registrations(
1434
-                                [['TXN_ID' => $this->_transaction->ID()]]
1435
-                            );
1436
-                            foreach ($registrations as $registration) {
1437
-                                if (! $registration instanceof EE_Registration) {
1438
-                                    break;
1439
-                                }
1440
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1441
-                                    = $registration->status_ID();
1442
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1443
-                                    = $registration->count();
1444
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1445
-                                    = $event_name;
1446
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1447
-                                    = $ticket_price;
1448
-                                // attendee info
1449
-                                $attendee = $registration->get_first_related('Attendee');
1450
-                                if ($attendee instanceof EE_Attendee) {
1451
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1452
-                                        = $attendee->ID();
1453
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1454
-                                        = $attendee->full_name();
1455
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1456
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1457
-                                          . esc_html__(
1458
-                                              ' Event',
1459
-                                              'event_espresso'
1460
-                                          )
1461
-                                          . '">' . $attendee->email() . '</a>';
1462
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1463
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1464
-                                } else {
1465
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1466
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1467
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1468
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1469
-                                }
1470
-                            }
1471
-                            break;
1472
-                    }
1473
-                }
1474
-            }
1475
-
1476
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1477
-                [
1478
-                    'action'  => 'edit_transaction',
1479
-                    'process' => 'attendees',
1480
-                ],
1481
-                TXN_ADMIN_URL
1482
-            );
1483
-            echo EEH_Template::display_template(
1484
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1485
-                $this->_template_args,
1486
-                true
1487
-            );
1488
-        } else {
1489
-            printf(
1490
-                esc_html__(
1491
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1492
-                    'event_espresso'
1493
-                ),
1494
-                '<p class="important-notice">',
1495
-                '</p>'
1496
-            );
1497
-        }
1498
-    }
1499
-
1500
-
1501
-    /**
1502
-     * txn_registrant_side_meta_box
1503
-     * generates HTML for the Edit Transaction side meta box
1504
-     *
1505
-     * @access public
1506
-     * @return void
1507
-     * @throws DomainException
1508
-     * @throws EE_Error
1509
-     * @throws InvalidArgumentException
1510
-     * @throws InvalidDataTypeException
1511
-     * @throws InvalidInterfaceException
1512
-     * @throws ReflectionException
1513
-     */
1514
-    public function txn_registrant_side_meta_box()
1515
-    {
1516
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1517
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1518
-            : null;
1519
-        if (! $primary_att instanceof EE_Attendee) {
1520
-            $this->_template_args['no_attendee_message'] = esc_html__(
1521
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1522
-                'event_espresso'
1523
-            );
1524
-            $primary_att                                 = EEM_Attendee::instance()->create_default_object();
1525
-        }
1526
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1527
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1528
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1529
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1530
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1531
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1532
-            [
1533
-                'action' => 'edit_attendee',
1534
-                'post'   => $primary_att->ID(),
1535
-            ],
1536
-            REG_ADMIN_URL
1537
-        );
1538
-        // get formatted address for registrant
1539
-        $formatted_address                         = EEH_Address::format($primary_att);
1540
-        $formatted_address                         =
1541
-            $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1542
-                ? $formatted_address
1543
-                : '';
1544
-        $this->_template_args['formatted_address'] = $formatted_address;
1545
-        echo EEH_Template::display_template(
1546
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1547
-            $this->_template_args,
1548
-            true
1549
-        );
1550
-    }
1551
-
1552
-
1553
-    /**
1554
-     * txn_billing_info_side_meta_box
1555
-     *    generates HTML for the Edit Transaction side meta box
1556
-     *
1557
-     * @access public
1558
-     * @return void
1559
-     * @throws DomainException
1560
-     * @throws EE_Error
1561
-     * @throws ReflectionException
1562
-     */
1563
-    public function txn_billing_info_side_meta_box()
1564
-    {
1565
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1566
-        $this->_template_args['billing_form_url'] = add_query_arg(
1567
-            ['action' => 'edit_transaction', 'process' => 'billing'],
1568
-            TXN_ADMIN_URL
1569
-        );
1570
-
1571
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1572
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1573
-    }
1574
-
1575
-
1576
-    /**
1577
-     * apply_payments_or_refunds
1578
-     *    registers a payment or refund made towards a transaction
1579
-     *
1580
-     * @access public
1581
-     * @return void
1582
-     * @throws EE_Error
1583
-     * @throws InvalidArgumentException
1584
-     * @throws ReflectionException
1585
-     * @throws RuntimeException
1586
-     * @throws InvalidDataTypeException
1587
-     * @throws InvalidInterfaceException
1588
-     */
1589
-    public function apply_payments_or_refunds()
1590
-    {
1591
-        $valid_data = $this->_validate_payment_request_data();
1592
-        $has_access = $this->capabilities->current_user_can(
1593
-            'ee_edit_payments',
1594
-            'apply_payment_or_refund_from_registration_details'
1595
-        );
1596
-        $TXD_ID     = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1597
-        $amount     = 0;
1598
-        if (! empty($valid_data) && $has_access) {
1599
-            $PAY_ID = $valid_data['PAY_ID'];
1600
-            // save  the new payment
1601
-            $payment = $this->_create_payment_from_request_data($valid_data);
1602
-            $amount  = $payment->amount();
1603
-            // get the TXN for this payment
1604
-            $transaction = $payment->transaction();
1605
-            // verify transaction
1606
-            if ($transaction instanceof EE_Transaction) {
1607
-                // calculate_total_payments_and_update_status
1608
-                $this->_process_transaction_payments($transaction);
1609
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1610
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1611
-                // apply payment to registrations (if applicable)
1612
-                if (! empty($REG_IDs)) {
1613
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1614
-                    $this->_maybe_send_notifications();
1615
-                    // now process status changes for the same registrations
1616
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1617
-                }
1618
-                $this->_maybe_send_notifications($payment);
1619
-                // prepare to render page
1620
-                do_action(
1621
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1622
-                    $transaction,
1623
-                    $payment
1624
-                );
1625
-            } else {
1626
-                EE_Error::add_error(
1627
-                    esc_html__(
1628
-                        'A valid Transaction for this payment could not be retrieved.',
1629
-                        'event_espresso'
1630
-                    ),
1631
-                    __FILE__,
1632
-                    __FUNCTION__,
1633
-                    __LINE__
1634
-                );
1635
-            }
1636
-        } elseif ($has_access) {
1637
-            EE_Error::add_error(
1638
-                esc_html__(
1639
-                    'The payment form data could not be processed. Please try again.',
1640
-                    'event_espresso'
1641
-                ),
1642
-                __FILE__,
1643
-                __FUNCTION__,
1644
-                __LINE__
1645
-            );
1646
-        } else {
1647
-            EE_Error::add_error(
1648
-                esc_html__(
1649
-                    'You do not have access to apply payments or refunds to a registration.',
1650
-                    'event_espresso'
1651
-                ),
1652
-                __FILE__,
1653
-                __FUNCTION__,
1654
-                __LINE__
1655
-            );
1656
-        }
1657
-        $query_args = [
1658
-            'page'   => 'espresso_transactions',
1659
-            'action' => 'view_transaction',
1660
-            'TXN_ID' => $TXD_ID,
1661
-        ];
1662
-
1663
-        $this->_redirect_after_action(
1664
-            ! EE_Error::has_error(),
1665
-            $amount > 0
1666
-                ? esc_html__('payment', 'event_espresso')
1667
-                : esc_html__('refund', 'event_espresso'),
1668
-            esc_html__('processed', 'event_espresso'),
1669
-            $query_args
1670
-        );
1671
-    }
1672
-
1673
-
1674
-    /**
1675
-     * _validate_payment_request_data
1676
-     *
1677
-     * @return array
1678
-     * @throws EE_Error
1679
-     * @throws InvalidArgumentException
1680
-     * @throws InvalidDataTypeException
1681
-     * @throws InvalidInterfaceException
1682
-     */
1683
-    protected function _validate_payment_request_data()
1684
-    {
1685
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1686
-            return [];
1687
-        }
1688
-        $payment_form = $this->_generate_payment_form_section();
1689
-        try {
1690
-            if ($payment_form->was_submitted()) {
1691
-                $payment_form->receive_form_submission();
1692
-                if (! $payment_form->is_valid()) {
1693
-                    $submission_error_messages = [];
1694
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1695
-                        if ($validation_error instanceof EE_Validation_Error) {
1696
-                            $form_input                  = $validation_error->get_form_section();
1697
-                            $submission_error_messages[] = sprintf(
1698
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1699
-                                $form_input instanceof EE_Form_Input_Base
1700
-                                    ? $form_input->html_label_text()
1701
-                                    : '',
1702
-                                $validation_error->getMessage()
1703
-                            );
1704
-                        }
1705
-                    }
1706
-                    EE_Error::add_error(
1707
-                        implode('<br />', $submission_error_messages),
1708
-                        __FILE__,
1709
-                        __FUNCTION__,
1710
-                        __LINE__
1711
-                    );
1712
-                    return [];
1713
-                }
1714
-            }
1715
-        } catch (EE_Error $e) {
1716
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1717
-            return [];
1718
-        }
1719
-
1720
-        return $payment_form->valid_data();
1721
-    }
1722
-
1723
-
1724
-    /**
1725
-     * _generate_payment_form_section
1726
-     *
1727
-     * @return EE_Form_Section_Proper
1728
-     * @throws EE_Error
1729
-     */
1730
-    protected function _generate_payment_form_section()
1731
-    {
1732
-        return new EE_Form_Section_Proper(
1733
-            [
1734
-                'name'        => 'txn_admin_payment',
1735
-                'subsections' => [
1736
-                    'PAY_ID'          => new EE_Text_Input(
1737
-                        [
1738
-                            'default'               => 0,
1739
-                            'required'              => false,
1740
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1741
-                            'validation_strategies' => [new EE_Int_Normalization()],
1742
-                        ]
1743
-                    ),
1744
-                    'TXN_ID'          => new EE_Text_Input(
1745
-                        [
1746
-                            'default'               => 0,
1747
-                            'required'              => true,
1748
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1749
-                            'validation_strategies' => [new EE_Int_Normalization()],
1750
-                        ]
1751
-                    ),
1752
-                    'type'            => new EE_Text_Input(
1753
-                        [
1754
-                            'default'               => 1,
1755
-                            'required'              => true,
1756
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1757
-                            'validation_strategies' => [new EE_Int_Normalization()],
1758
-                        ]
1759
-                    ),
1760
-                    'amount'          => new EE_Text_Input(
1761
-                        [
1762
-                            'default'               => 0,
1763
-                            'required'              => true,
1764
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1765
-                            'validation_strategies' => [new EE_Float_Normalization()],
1766
-                        ]
1767
-                    ),
1768
-                    'status'          => new EE_Text_Input(
1769
-                        [
1770
-                            'default'         => EEM_Payment::status_id_approved,
1771
-                            'required'        => true,
1772
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1773
-                        ]
1774
-                    ),
1775
-                    'PMD_ID'          => new EE_Text_Input(
1776
-                        [
1777
-                            'default'               => 2,
1778
-                            'required'              => true,
1779
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1780
-                            'validation_strategies' => [new EE_Int_Normalization()],
1781
-                        ]
1782
-                    ),
1783
-                    'date'            => new EE_Text_Input(
1784
-                        [
1785
-                            'default'         => time(),
1786
-                            'required'        => true,
1787
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1788
-                        ]
1789
-                    ),
1790
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1791
-                        [
1792
-                            'default'               => '',
1793
-                            'required'              => false,
1794
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1795
-                            'validation_strategies' => [
1796
-                                new EE_Max_Length_Validation_Strategy(
1797
-                                    esc_html__('Input too long', 'event_espresso'),
1798
-                                    100
1799
-                                ),
1800
-                            ],
1801
-                        ]
1802
-                    ),
1803
-                    'po_number'       => new EE_Text_Input(
1804
-                        [
1805
-                            'default'               => '',
1806
-                            'required'              => false,
1807
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1808
-                            'validation_strategies' => [
1809
-                                new EE_Max_Length_Validation_Strategy(
1810
-                                    esc_html__('Input too long', 'event_espresso'),
1811
-                                    100
1812
-                                ),
1813
-                            ],
1814
-                        ]
1815
-                    ),
1816
-                    'accounting'      => new EE_Text_Input(
1817
-                        [
1818
-                            'default'               => '',
1819
-                            'required'              => false,
1820
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1821
-                            'validation_strategies' => [
1822
-                                new EE_Max_Length_Validation_Strategy(
1823
-                                    esc_html__('Input too long', 'event_espresso'),
1824
-                                    100
1825
-                                ),
1826
-                            ],
1827
-                        ]
1828
-                    ),
1829
-                ],
1830
-            ]
1831
-        );
1832
-    }
1833
-
1834
-
1835
-    /**
1836
-     * _create_payment_from_request_data
1837
-     *
1838
-     * @param array $valid_data
1839
-     * @return EE_Payment
1840
-     * @throws EE_Error
1841
-     * @throws InvalidArgumentException
1842
-     * @throws InvalidDataTypeException
1843
-     * @throws InvalidInterfaceException
1844
-     * @throws ReflectionException
1845
-     */
1846
-    protected function _create_payment_from_request_data($valid_data)
1847
-    {
1848
-        $PAY_ID = $valid_data['PAY_ID'];
1849
-        // get payment amount
1850
-        $amount = $valid_data['amount']
1851
-            ? EEH_Money::strip_localized_money_formatting($valid_data['amount'])
1852
-            : 0;
1853
-        // payments have a type value of 1 and refunds have a type value of -1
1854
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1855
-        $amount = $valid_data['type'] < 0
1856
-            ? $amount * -1
1857
-            : $amount;
1858
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1859
-        $date    = $valid_data['date']
1860
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1861
-            : date('Y-m-d g:i a', current_time('timestamp'));
1862
-        $payment = EE_Payment::new_instance(
1863
-            [
1864
-                'TXN_ID'              => $valid_data['TXN_ID'],
1865
-                'STS_ID'              => $valid_data['status'],
1866
-                'PAY_timestamp'       => $date,
1867
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1868
-                'PMD_ID'              => $valid_data['PMD_ID'],
1869
-                'PAY_amount'          => $amount,
1870
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1871
-                'PAY_po_number'       => $valid_data['po_number'],
1872
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1873
-                'PAY_details'         => $valid_data,
1874
-                'PAY_ID'              => $PAY_ID,
1875
-            ],
1876
-            '',
1877
-            ['Y-m-d', 'g:i a']
1878
-        );
1879
-
1880
-        if (! $payment->save()) {
1881
-            EE_Error::add_error(
1882
-                sprintf(
1883
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1884
-                    $payment->ID()
1885
-                ),
1886
-                __FILE__,
1887
-                __FUNCTION__,
1888
-                __LINE__
1889
-            );
1890
-        }
1891
-
1892
-        return $payment;
1893
-    }
1894
-
1895
-
1896
-    /**
1897
-     * _process_transaction_payments
1898
-     *
1899
-     * @param EE_Transaction $transaction
1900
-     * @return void
1901
-     * @throws EE_Error
1902
-     * @throws InvalidArgumentException
1903
-     * @throws ReflectionException
1904
-     * @throws InvalidDataTypeException
1905
-     * @throws InvalidInterfaceException
1906
-     */
1907
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1908
-    {
1909
-        /** @type EE_Transaction_Payments $transaction_payments */
1910
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1911
-        // update the transaction with this payment
1912
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1913
-            EE_Error::add_success(
1914
-                esc_html__(
1915
-                    'The payment has been processed successfully.',
1916
-                    'event_espresso'
1917
-                ),
1918
-                __FILE__,
1919
-                __FUNCTION__,
1920
-                __LINE__
1921
-            );
1922
-        } else {
1923
-            EE_Error::add_error(
1924
-                esc_html__(
1925
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1926
-                    'event_espresso'
1927
-                ),
1928
-                __FILE__,
1929
-                __FUNCTION__,
1930
-                __LINE__
1931
-            );
1932
-        }
1933
-    }
1934
-
1935
-
1936
-    /**
1937
-     * _get_REG_IDs_to_apply_payment_to
1938
-     * returns a list of registration IDs that the payment will apply to
1939
-     *
1940
-     * @param EE_Payment $payment
1941
-     * @return array
1942
-     * @throws EE_Error
1943
-     * @throws InvalidArgumentException
1944
-     * @throws InvalidDataTypeException
1945
-     * @throws InvalidInterfaceException
1946
-     * @throws ReflectionException
1947
-     */
1948
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1949
-    {
1950
-        // grab array of IDs for specific registrations to apply changes to
1951
-        $apply_to_all = $this->request->getRequestParam(
1952
-            'txn_admin_payment[apply_to_all_registrations]',
1953
-            false,
1954
-            DataType::BOOL
1955
-        );
1956
-        $REG_IDs      = ! $apply_to_all
1957
-            ? $this->request->getRequestParam(
1958
-                'txn_admin_payment[registrations]',
1959
-                [],
1960
-                DataType::INT,
1961
-                true
1962
-            )
1963
-            : [];
1964
-        // nothing specified ? then get all reg IDs
1965
-        if ($apply_to_all || empty($REG_IDs)) {
1966
-            $registrations = $payment->transaction()->registrations(
1967
-                [
1968
-                    [
1969
-                        'STS_ID' => [
1970
-                            'NOT_IN', [ EEM_Registration::status_id_cancelled ]
1971
-                        ]
1972
-                    ]
1973
-                ]
1974
-            );
1975
-            $REG_IDs       = ! empty($registrations)
1976
-                ? array_keys($registrations)
1977
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1978
-        }
1979
-        // ensure that REG_IDs are integers and NOT strings
1980
-        return array_map('absint', $REG_IDs);
1981
-    }
1982
-
1983
-
1984
-    /**
1985
-     * @return array
1986
-     */
1987
-    public function existing_reg_payment_REG_IDs()
1988
-    {
1989
-        return $this->_existing_reg_payment_REG_IDs;
1990
-    }
1991
-
1992
-
1993
-    /**
1994
-     * @param array $existing_reg_payment_REG_IDs
1995
-     */
1996
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1997
-    {
1998
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1999
-    }
2000
-
2001
-
2002
-    /**
2003
-     * _get_existing_reg_payment_REG_IDs
2004
-     * returns a list of registration IDs that the payment is currently related to
2005
-     * as recorded in the database
2006
-     *
2007
-     * @param EE_Payment $payment
2008
-     * @return array
2009
-     * @throws EE_Error
2010
-     * @throws InvalidArgumentException
2011
-     * @throws InvalidDataTypeException
2012
-     * @throws InvalidInterfaceException
2013
-     * @throws ReflectionException
2014
-     */
2015
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2016
-    {
2017
-        if ($this->existing_reg_payment_REG_IDs() === null) {
2018
-            // let's get any existing reg payment records for this payment
2019
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2020
-            // but we only want the REG IDs, so grab the array keys
2021
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2022
-                ? array_keys($existing_reg_payment_REG_IDs)
2023
-                : [];
2024
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2025
-        }
2026
-
2027
-        return $this->existing_reg_payment_REG_IDs();
2028
-    }
2029
-
2030
-
2031
-    /**
2032
-     * _remove_existing_registration_payments
2033
-     * this calculates the difference between existing relations
2034
-     * to the supplied payment and the new list registration IDs,
2035
-     * removes any related registrations that no longer apply,
2036
-     * and then updates the registration paid fields
2037
-     *
2038
-     * @param EE_Payment $payment
2039
-     * @param int        $PAY_ID
2040
-     * @return bool;
2041
-     * @throws EE_Error
2042
-     * @throws InvalidArgumentException
2043
-     * @throws ReflectionException
2044
-     * @throws InvalidDataTypeException
2045
-     * @throws InvalidInterfaceException
2046
-     */
2047
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2048
-    {
2049
-        // newly created payments will have nothing recorded for $PAY_ID
2050
-        if (absint($PAY_ID) === 0) {
2051
-            return false;
2052
-        }
2053
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2054
-        if (empty($existing_reg_payment_REG_IDs)) {
2055
-            return false;
2056
-        }
2057
-        /** @type EE_Transaction_Payments $transaction_payments */
2058
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2059
-
2060
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2061
-            $payment,
2062
-            [
2063
-                [
2064
-                    'PAY_ID' => $payment->ID(),
2065
-                    'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2066
-                ],
2067
-            ]
2068
-        );
2069
-    }
2070
-
2071
-
2072
-    /**
2073
-     * _update_registration_payments
2074
-     * this applies the payments to the selected registrations
2075
-     * but only if they have not already been paid for
2076
-     *
2077
-     * @param EE_Transaction $transaction
2078
-     * @param EE_Payment     $payment
2079
-     * @param array          $REG_IDs
2080
-     * @return void
2081
-     * @throws EE_Error
2082
-     * @throws InvalidArgumentException
2083
-     * @throws ReflectionException
2084
-     * @throws RuntimeException
2085
-     * @throws InvalidDataTypeException
2086
-     * @throws InvalidInterfaceException
2087
-     */
2088
-    protected function _update_registration_payments(
2089
-        EE_Transaction $transaction,
2090
-        EE_Payment $payment,
2091
-        $REG_IDs = []
2092
-    ) {
2093
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2094
-        // so let's do that using our set of REG_IDs from the form
2095
-        $registration_query_where_params = [
2096
-            'REG_ID' => ['IN', $REG_IDs],
2097
-        ];
2098
-        // but add in some conditions regarding payment,
2099
-        // so that we don't apply payments to registrations that are free or have already been paid for
2100
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2101
-        if (! $payment->is_a_refund()) {
2102
-            $registration_query_where_params['REG_final_price']  = ['!=', 0];
2103
-            $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2104
-        }
2105
-        $registrations = $transaction->registrations([$registration_query_where_params]);
2106
-        if (! empty($registrations)) {
2107
-            /** @type EE_Payment_Processor $payment_processor */
2108
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2109
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2110
-        }
2111
-    }
2112
-
2113
-
2114
-    /**
2115
-     * _process_registration_status_change
2116
-     * This processes requested registration status changes for all the registrations
2117
-     * on a given transaction and (optionally) sends out notifications for the changes.
2118
-     *
2119
-     * @param EE_Transaction $transaction
2120
-     * @param array          $REG_IDs
2121
-     * @return bool
2122
-     * @throws EE_Error
2123
-     * @throws InvalidArgumentException
2124
-     * @throws ReflectionException
2125
-     * @throws InvalidDataTypeException
2126
-     * @throws InvalidInterfaceException
2127
-     */
2128
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2129
-    {
2130
-        // first if there is no change in status then we get out.
2131
-        $reg_status = $reg_status
2132
-            ?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2133
-        if ($reg_status === 'NAN') {
2134
-            // no error message, no change requested, just nothing to do man.
2135
-            return false;
2136
-        }
2137
-        /** @type EE_Transaction_Processor $transaction_processor */
2138
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2139
-
2140
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2141
-        return $transaction_processor->manually_update_registration_statuses(
2142
-            $transaction,
2143
-            $reg_status,
2144
-            [['REG_ID' => ['IN', $REG_IDs]]]
2145
-        );
2146
-    }
2147
-
2148
-
2149
-    /**
2150
-     * _build_payment_json_response
2151
-     *
2152
-     * @access public
2153
-     * @param EE_Payment  $payment
2154
-     * @param array       $REG_IDs
2155
-     * @param bool | null $delete_txn_reg_status_change
2156
-     * @return array
2157
-     * @throws EE_Error
2158
-     * @throws InvalidArgumentException
2159
-     * @throws InvalidDataTypeException
2160
-     * @throws InvalidInterfaceException
2161
-     * @throws ReflectionException
2162
-     */
2163
-    protected function _build_payment_json_response(
2164
-        EE_Payment $payment,
2165
-        $REG_IDs = [],
2166
-        $delete_txn_reg_status_change = null
2167
-    ) {
2168
-        // was the payment deleted ?
2169
-        if (is_bool($delete_txn_reg_status_change)) {
2170
-            return [
2171
-                'PAY_ID'                       => $payment->ID(),
2172
-                'amount'                       => $payment->amount(),
2173
-                'total_paid'                   => $payment->transaction()->paid(),
2174
-                'txn_status'                   => $payment->transaction()->status_ID(),
2175
-                'pay_status'                   => $payment->STS_ID(),
2176
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2177
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2178
-            ];
2179
-        }
2180
-
2181
-        $this->_get_payment_status_array();
2182
-        $payment_method = $payment->payment_method();
2183
-        return [
2184
-            'amount'           => $payment->amount(),
2185
-            'total_paid'       => $payment->transaction()->paid(),
2186
-            'txn_status'       => $payment->transaction()->status_ID(),
2187
-            'pay_status'       => $payment->STS_ID(),
2188
-            'PAY_ID'           => $payment->ID(),
2189
-            'STS_ID'           => $payment->STS_ID(),
2190
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2191
-            'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2192
-            'method'           => strtoupper($payment->source()),
2193
-            'PM_ID'            => $payment_method instanceof EE_Payment_Method
2194
-                ? $payment_method->ID()
2195
-                : 1,
2196
-            'gateway'          => $payment_method instanceof EE_Payment_Method
2197
-                ? $payment_method->admin_name()
2198
-                : esc_html__('Unknown', 'event_espresso'),
2199
-            'gateway_response' => $payment->gateway_response(),
2200
-            'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2201
-            'po_number'        => $payment->po_number(),
2202
-            'extra_accntng'    => $payment->extra_accntng(),
2203
-            'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2204
-        ];
2205
-    }
2206
-
2207
-
2208
-    /**
2209
-     * delete_payment
2210
-     *    delete a payment or refund made towards a transaction
2211
-     *
2212
-     * @access public
2213
-     * @return void
2214
-     * @throws EE_Error
2215
-     * @throws InvalidArgumentException
2216
-     * @throws ReflectionException
2217
-     * @throws InvalidDataTypeException
2218
-     * @throws InvalidInterfaceException
2219
-     */
2220
-    public function delete_payment()
2221
-    {
2222
-        $TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2223
-        // $json_response_data = ['return_data' => false];
2224
-        $PAY_ID     = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2225
-        $amount     = 0;
2226
-        $can_delete = $this->capabilities->current_user_can(
2227
-            'ee_delete_payments',
2228
-            'delete_payment_from_registration_details'
2229
-        );
2230
-        if ($PAY_ID && $can_delete) {
2231
-            $delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2232
-            $payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2233
-            if ($payment instanceof EE_Payment) {
2234
-                $amount  = $payment->amount();
2235
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2236
-                /** @type EE_Transaction_Payments $transaction_payments */
2237
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2238
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2239
-                    if ($delete_txn_reg_status_change) {
2240
-                        $this->_maybe_send_notifications();
2241
-                        $this->_process_registration_status_change(
2242
-                            $payment->transaction(),
2243
-                            $REG_IDs,
2244
-                            $delete_txn_reg_status_change
2245
-                        );
2246
-                    }
2247
-                }
2248
-            } else {
2249
-                EE_Error::add_error(
2250
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2251
-                    __FILE__,
2252
-                    __FUNCTION__,
2253
-                    __LINE__
2254
-                );
2255
-            }
2256
-        } elseif ($can_delete) {
2257
-            EE_Error::add_error(
2258
-                esc_html__(
2259
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2260
-                    'event_espresso'
2261
-                ),
2262
-                __FILE__,
2263
-                __FUNCTION__,
2264
-                __LINE__
2265
-            );
2266
-        } else {
2267
-            EE_Error::add_error(
2268
-                esc_html__(
2269
-                    'You do not have access to delete a payment.',
2270
-                    'event_espresso'
2271
-                ),
2272
-                __FILE__,
2273
-                __FUNCTION__,
2274
-                __LINE__
2275
-            );
2276
-        }
2277
-        $query_args = [
2278
-            'page'   => 'espresso_transactions',
2279
-            'action' => 'view_transaction',
2280
-            'TXN_ID' => $TXD_ID,
2281
-        ];
2282
-        $this->_redirect_after_action(
2283
-            ! EE_Error::has_error(),
2284
-            $amount > 0
2285
-                ? esc_html__('payment', 'event_espresso')
2286
-                : esc_html__('refund', 'event_espresso'),
2287
-            esc_html__('deleted', 'event_espresso'),
2288
-            $query_args
2289
-        );
2290
-    }
2291
-
2292
-
2293
-    /**
2294
-     * _registration_payment_data_array
2295
-     * adds info for 'owing' and 'paid' for each registration to the json response
2296
-     *
2297
-     * @access protected
2298
-     * @param array $REG_IDs
2299
-     * @return array
2300
-     * @throws EE_Error
2301
-     * @throws InvalidArgumentException
2302
-     * @throws InvalidDataTypeException
2303
-     * @throws InvalidInterfaceException
2304
-     * @throws ReflectionException
2305
-     */
2306
-    protected function _registration_payment_data_array($REG_IDs)
2307
-    {
2308
-        $registration_payment_data = [];
2309
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2310
-        if (! empty($REG_IDs)) {
2311
-            $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2312
-            foreach ($registrations as $registration) {
2313
-                if ($registration instanceof EE_Registration) {
2314
-                    $registration_payment_data[ $registration->ID() ] = [
2315
-                        'paid'  => $registration->pretty_paid(),
2316
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2317
-                    ];
2318
-                }
2319
-            }
2320
-        }
2321
-
2322
-        return $registration_payment_data;
2323
-    }
2324
-
2325
-
2326
-    /**
2327
-     * _maybe_send_notifications
2328
-     * determines whether or not the admin has indicated that notifications should be sent.
2329
-     * If so, will toggle a filter switch for delivering registration notices.
2330
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2331
-     *
2332
-     * @access protected
2333
-     * @param EE_Payment | null $payment
2334
-     */
2335
-    protected function _maybe_send_notifications($payment = null)
2336
-    {
2337
-        switch ($payment instanceof EE_Payment) {
2338
-            // payment notifications
2339
-            case true:
2340
-                if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2341
-                    $this->_process_payment_notification($payment);
2342
-                }
2343
-                break;
2344
-            // registration notifications
2345
-            case false:
2346
-                if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2347
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2348
-                }
2349
-                break;
2350
-        }
2351
-    }
2352
-
2353
-
2354
-    /**
2355
-     * _send_payment_reminder
2356
-     *    generates HTML for the View Transaction Details Admin page
2357
-     *
2358
-     * @access protected
2359
-     * @return void
2360
-     * @throws EE_Error
2361
-     * @throws InvalidArgumentException
2362
-     * @throws InvalidDataTypeException
2363
-     * @throws InvalidInterfaceException
2364
-     */
2365
-    protected function _send_payment_reminder()
2366
-    {
2367
-        $TXN_ID      = $this->request->getRequestParam('TXN_ID', 0, 'int');
2368
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2369
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2370
-        $query_args  = $redirect_to
2371
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2372
-            : [];
2373
-        do_action(
2374
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2375
-            $transaction
2376
-        );
2377
-        $this->_redirect_after_action(
2378
-            false,
2379
-            esc_html__('payment reminder', 'event_espresso'),
2380
-            esc_html__('sent', 'event_espresso'),
2381
-            $query_args,
2382
-            true
2383
-        );
2384
-    }
2385
-
2386
-
2387
-    /**
2388
-     *  get_transactions
2389
-     *    get transactions for given parameters (used by list table)
2390
-     *
2391
-     * @param int     $per_page how many transactions displayed per page
2392
-     * @param boolean $count    return the count or objects
2393
-     * @param string  $view
2394
-     * @return EE_Transaction[]|int int = count || array of transaction objects
2395
-     * @throws EE_Error
2396
-     * @throws InvalidArgumentException
2397
-     * @throws InvalidDataTypeException
2398
-     * @throws InvalidInterfaceException
2399
-     * @throws ReflectionException
2400
-     */
2401
-    public function get_transactions($per_page, $count = false, $view = '')
2402
-    {
2403
-        $start_date = wp_strip_all_tags(
2404
-            $this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2405
-        );
2406
-        $end_date   = wp_strip_all_tags(
2407
-            $this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2408
-        );
2409
-
2410
-        // make sure our timestamps start and end right at the boundaries for each day
2411
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2412
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2413
-
2414
-
2415
-        // convert to timestamps
2416
-        $start_date = strtotime($start_date);
2417
-        $end_date   = strtotime($end_date);
2418
-
2419
-        // makes sure start date is the lowest value and vice versa
2420
-        $start_date = min($start_date, $end_date);
2421
-        $end_date   = max($start_date, $end_date);
2422
-
2423
-        // convert to correct format for query
2424
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2425
-            'TXN_timestamp',
2426
-            date('Y-m-d H:i:s', $start_date),
2427
-            'Y-m-d H:i:s'
2428
-        );
2429
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2430
-            'TXN_timestamp',
2431
-            date('Y-m-d H:i:s', $end_date),
2432
-            'Y-m-d H:i:s'
2433
-        );
2434
-
2435
-
2436
-        // set orderby
2437
-        $orderby = $this->request->getRequestParam('orderby');
2438
-
2439
-        switch ($orderby) {
2440
-            case 'TXN_ID':
2441
-                break;
2442
-            case 'ATT_fname':
2443
-                $orderby = 'Registration.Attendee.ATT_fname';
2444
-                break;
2445
-            case 'event_name':
2446
-                $orderby = 'Registration.Event.EVT_name';
2447
-                break;
2448
-            default: // 'TXN_timestamp'
2449
-                $orderby = 'TXN_timestamp';
2450
-        }
2451
-
2452
-        $sort         = $this->request->getRequestParam('order', 'DESC');
2453
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
2454
-
2455
-        $per_page = absint($per_page)
2456
-            ? $per_page
2457
-            : 10;
2458
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2459
-
2460
-        $offset = ($current_page - 1) * $per_page;
2461
-        $limit  = [$offset, $per_page];
2462
-
2463
-        $_where = [
2464
-            'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2465
-            'Registration.REG_count' => 1,
2466
-        ];
2467
-
2468
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2469
-        if ($EVT_ID) {
2470
-            $_where['Registration.EVT_ID'] = $EVT_ID;
2471
-        }
2472
-
2473
-        $search_term = $this->request->getRequestParam('s');
2474
-        if ($search_term) {
2475
-            $search_term  = '%' . $search_term . '%';
2476
-            $_where['OR'] = [
2477
-                'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2478
-                'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2479
-                'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2480
-                'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2481
-                'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2482
-                'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2483
-                'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2484
-                'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2485
-                'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2486
-                'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2487
-                'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2488
-                'Registration.REG_final_price'        => ['LIKE', $search_term],
2489
-                'Registration.REG_code'               => ['LIKE', $search_term],
2490
-                'Registration.REG_count'              => ['LIKE', $search_term],
2491
-                'Registration.REG_group_size'         => ['LIKE', $search_term],
2492
-                'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2493
-                'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2494
-                'Payment.PAY_source'                  => ['LIKE', $search_term],
2495
-                'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2496
-                'TXN_session_data'                    => ['LIKE', $search_term],
2497
-                'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2498
-            ];
2499
-        }
2500
-
2501
-        $status = $this->request->getRequestParam('status');
2502
-        // failed transactions
2503
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2504
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2505
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2506
-
2507
-        if ($failed) {
2508
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2509
-        } elseif ($abandoned) {
2510
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2511
-        } elseif ($incomplete) {
2512
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2513
-        } else {
2514
-            $_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2515
-            $_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2516
-        }
2517
-
2518
-        $query_params = apply_filters(
2519
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2520
-            [
2521
-                $_where,
2522
-                'order_by'                 => [$orderby => $sort],
2523
-                'limit'                    => $limit,
2524
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2525
-            ],
2526
-            $this->request->requestParams(),
2527
-            $view,
2528
-            $count
2529
-        );
2530
-
2531
-        return $count
2532
-            ? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2533
-            : EEM_Transaction::instance()->get_all($query_params);
2534
-    }
2535
-
2536
-
2537
-    /**
2538
-     * @throws EE_Error
2539
-     * @throws InvalidArgumentException
2540
-     * @throws InvalidDataTypeException
2541
-     * @throws InvalidInterfaceException
2542
-     * @throws ReflectionException
2543
-     * @throws RuntimeException
2544
-     * @since 4.9.79.p
2545
-     */
2546
-    public function recalculateLineItems()
2547
-    {
2548
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2549
-        /** @var EE_Transaction $transaction */
2550
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2551
-        $success     = $transaction->recalculateLineItems();
2552
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2553
-        $query_args  = $redirect_to
2554
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2555
-            : [];
2556
-        $this->_redirect_after_action(
2557
-            $success,
2558
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2559
-            esc_html__('recalculated', 'event_espresso'),
2560
-            $query_args,
2561
-            true
2562
-        );
2563
-    }
16
+	/**
17
+	 * @var EE_Transaction
18
+	 */
19
+	private $_transaction;
20
+
21
+	/**
22
+	 * @var EE_Session
23
+	 */
24
+	private $_session;
25
+
26
+	/**
27
+	 * @var array $_txn_status
28
+	 */
29
+	private static $_txn_status;
30
+
31
+	/**
32
+	 * @var array $_pay_status
33
+	 */
34
+	private static $_pay_status;
35
+
36
+	/**
37
+	 * @var array $_existing_reg_payment_REG_IDs
38
+	 */
39
+	protected $_existing_reg_payment_REG_IDs;
40
+
41
+
42
+	/**
43
+	 *    _init_page_props
44
+	 *
45
+	 * @return void
46
+	 */
47
+	protected function _init_page_props()
48
+	{
49
+		$this->page_slug        = TXN_PG_SLUG;
50
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
51
+		$this->_admin_base_url  = TXN_ADMIN_URL;
52
+		$this->_admin_base_path = TXN_ADMIN;
53
+	}
54
+
55
+
56
+	/**
57
+	 *    _ajax_hooks
58
+	 *
59
+	 * @return void
60
+	 */
61
+	protected function _ajax_hooks()
62
+	{
63
+		// add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
+		// add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
+		// add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
+	}
67
+
68
+
69
+	/**
70
+	 *    _define_page_props
71
+	 *
72
+	 * @return void
73
+	 */
74
+	protected function _define_page_props()
75
+	{
76
+		$this->_admin_page_title = $this->page_label;
77
+		$this->_labels           = [
78
+			'buttons' => [
79
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
+			],
83
+		];
84
+	}
85
+
86
+
87
+	/**
88
+	 *        grab url requests and route them
89
+	 *
90
+	 * @access private
91
+	 * @return void
92
+	 * @throws EE_Error
93
+	 * @throws InvalidArgumentException
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InvalidInterfaceException
96
+	 * @throws ReflectionException
97
+	 */
98
+	public function _set_page_routes()
99
+	{
100
+		$this->_set_transaction_status_array();
101
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
+
103
+		$this->_page_routes = [
104
+
105
+			'default' => [
106
+				'func'       => '_transactions_overview_list_table',
107
+				'capability' => 'ee_read_transactions',
108
+			],
109
+
110
+			'view_transaction' => [
111
+				'func'       => '_transaction_details',
112
+				'capability' => 'ee_read_transaction',
113
+				'obj_id'     => $TXN_ID,
114
+			],
115
+
116
+			'send_payment_reminder' => [
117
+				'func'       => '_send_payment_reminder',
118
+				'noheader'   => true,
119
+				'capability' => 'ee_send_message',
120
+			],
121
+
122
+			'espresso_apply_payment' => [
123
+				'func'       => [$this, 'apply_payments_or_refunds'],
124
+				'noheader'   => true,
125
+				'capability' => 'ee_edit_payments',
126
+			],
127
+
128
+			'espresso_apply_refund' => [
129
+				'func'       => [$this, 'apply_payments_or_refunds'],
130
+				'noheader'   => true,
131
+				'capability' => 'ee_edit_payments',
132
+			],
133
+
134
+			'espresso_delete_payment' => [
135
+				'func'       => [$this, 'delete_payment'],
136
+				'noheader'   => true,
137
+				'capability' => 'ee_delete_payments',
138
+			],
139
+
140
+			'espresso_recalculate_line_items' => [
141
+				'func'       => 'recalculateLineItems',
142
+				'noheader'   => true,
143
+				'capability' => 'ee_edit_payments',
144
+			],
145
+
146
+		];
147
+	}
148
+
149
+
150
+	protected function _set_page_config()
151
+	{
152
+		$TXN_ID             = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
+		$this->_page_config = [
154
+			'default'          => [
155
+				'nav'           => [
156
+					'label' => esc_html__('Overview', 'event_espresso'),
157
+					'icon'  => 'dashicons-list-view',
158
+					'order' => 10,
159
+				],
160
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
161
+				'help_tabs'     => [
162
+					'transactions_overview_help_tab'                       => [
163
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
164
+						'filename' => 'transactions_overview',
165
+					],
166
+					'transactions_overview_table_column_headings_help_tab' => [
167
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
168
+						'filename' => 'transactions_overview_table_column_headings',
169
+					],
170
+					'transactions_overview_views_filters_help_tab'         => [
171
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
172
+						'filename' => 'transactions_overview_views_filters_search',
173
+					],
174
+				],
175
+				'require_nonce' => false,
176
+			],
177
+			'view_transaction' => [
178
+				'nav'       => [
179
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
180
+					'icon'       => 'dashicons-cart',
181
+					'order'      => 5,
182
+					'url'        => $TXN_ID
183
+						? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
184
+						: $this->_admin_base_url,
185
+					'persistent' => false,
186
+				],
187
+				'help_tabs' => [
188
+					'transactions_view_transaction_help_tab'                                              => [
189
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
190
+						'filename' => 'transactions_view_transaction',
191
+					],
192
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => [
193
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
194
+						'filename' => 'transactions_view_transaction_transaction_details_table',
195
+					],
196
+					'transactions_view_transaction_attendees_registered_help_tab'                         => [
197
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
198
+						'filename' => 'transactions_view_transaction_attendees_registered',
199
+					],
200
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
201
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
202
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
203
+					],
204
+				],
205
+				'qtips'     => ['Transaction_Details_Tips'],
206
+				'metaboxes' => ['_transaction_details_metaboxes'],
207
+
208
+				'require_nonce' => false,
209
+			],
210
+		];
211
+	}
212
+
213
+
214
+	/**
215
+	 * The below methods aren't used by this class currently
216
+	 */
217
+	protected function _add_screen_options()
218
+	{
219
+		// noop
220
+	}
221
+
222
+
223
+	protected function _add_feature_pointers()
224
+	{
225
+		// noop
226
+	}
227
+
228
+
229
+	public function admin_init()
230
+	{
231
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
232
+		$event_name    = $this->request->getRequestParam('event_name');
233
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
234
+		// IF a registration was JUST added via the admin...
235
+		if ($EVT_ID && $event_name && $redirect_from) {
236
+			// then set a cookie so that we can block any attempts to use
237
+			// the back button as a way to enter another registration.
238
+			setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
239
+			// and update the global
240
+			$_COOKIE['ee_registration_added'] = $EVT_ID;
241
+		}
242
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
243
+			'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
244
+			'event_espresso'
245
+		);
246
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
247
+			'An error occurred! Please refresh the page and try again.',
248
+			'event_espresso'
249
+		);
250
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
251
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
252
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
253
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
254
+			'This transaction has been overpaid ! Payments Total',
255
+			'event_espresso'
256
+		);
257
+	}
258
+
259
+
260
+	public function admin_notices()
261
+	{
262
+		// noop
263
+	}
264
+
265
+
266
+	public function admin_footer_scripts()
267
+	{
268
+		// noop
269
+	}
270
+
271
+
272
+	/**
273
+	 * _set_transaction_status_array
274
+	 * sets list of transaction statuses
275
+	 *
276
+	 * @access private
277
+	 * @return void
278
+	 * @throws EE_Error
279
+	 * @throws InvalidArgumentException
280
+	 * @throws InvalidDataTypeException
281
+	 * @throws InvalidInterfaceException
282
+	 * @throws ReflectionException
283
+	 */
284
+	private function _set_transaction_status_array()
285
+	{
286
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
287
+	}
288
+
289
+
290
+	/**
291
+	 * get_transaction_status_array
292
+	 * return the transaction status array for wp_list_table
293
+	 *
294
+	 * @access public
295
+	 * @return array
296
+	 */
297
+	public function get_transaction_status_array()
298
+	{
299
+		return self::$_txn_status;
300
+	}
301
+
302
+
303
+	/**
304
+	 *    get list of payment statuses
305
+	 *
306
+	 * @access private
307
+	 * @return void
308
+	 * @throws EE_Error
309
+	 * @throws InvalidArgumentException
310
+	 * @throws InvalidDataTypeException
311
+	 * @throws InvalidInterfaceException
312
+	 * @throws ReflectionException
313
+	 */
314
+	private function _get_payment_status_array()
315
+	{
316
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
317
+		$this->_template_args['payment_status'] = self::$_pay_status;
318
+	}
319
+
320
+
321
+	/**
322
+	 *    _add_screen_options_default
323
+	 *
324
+	 * @access protected
325
+	 * @return void
326
+	 * @throws InvalidArgumentException
327
+	 * @throws InvalidDataTypeException
328
+	 * @throws InvalidInterfaceException
329
+	 */
330
+	protected function _add_screen_options_default()
331
+	{
332
+		$this->_per_page_screen_option();
333
+	}
334
+
335
+
336
+	/**
337
+	 * load_scripts_styles
338
+	 *
339
+	 * @access public
340
+	 * @return void
341
+	 */
342
+	public function load_scripts_styles()
343
+	{
344
+		// enqueue style
345
+		wp_register_style(
346
+			'espresso_txn',
347
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
348
+			[],
349
+			EVENT_ESPRESSO_VERSION
350
+		);
351
+		wp_enqueue_style('espresso_txn');
352
+		// scripts
353
+		wp_register_script(
354
+			'espresso_txn',
355
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
356
+			[
357
+				'ee_admin_js',
358
+				'ee-datepicker',
359
+				'jquery-ui-datepicker',
360
+				'jquery-ui-draggable',
361
+				'ee-dialog',
362
+				'ee-accounting',
363
+				'ee-serialize-full-array',
364
+			],
365
+			EVENT_ESPRESSO_VERSION,
366
+			true
367
+		);
368
+		wp_enqueue_script('espresso_txn');
369
+	}
370
+
371
+
372
+	/**
373
+	 *    load_scripts_styles_view_transaction
374
+	 *
375
+	 * @access public
376
+	 * @return void
377
+	 */
378
+	public function load_scripts_styles_view_transaction()
379
+	{
380
+		// styles
381
+		wp_enqueue_style('espresso-ui-theme');
382
+	}
383
+
384
+
385
+	/**
386
+	 *    load_scripts_styles_default
387
+	 *
388
+	 * @access public
389
+	 * @return void
390
+	 */
391
+	public function load_scripts_styles_default()
392
+	{
393
+		// styles
394
+		wp_enqueue_style('espresso-ui-theme');
395
+	}
396
+
397
+
398
+	/**
399
+	 *    _set_list_table_views_default
400
+	 *
401
+	 * @access protected
402
+	 * @return void
403
+	 */
404
+	protected function _set_list_table_views_default()
405
+	{
406
+		$this->_views = [
407
+			'all'        => [
408
+				'slug'  => 'all',
409
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
410
+				'count' => 0,
411
+			],
412
+			'abandoned'  => [
413
+				'slug'  => 'abandoned',
414
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
415
+				'count' => 0,
416
+			],
417
+			'incomplete' => [
418
+				'slug'  => 'incomplete',
419
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
420
+				'count' => 0,
421
+			],
422
+		];
423
+		if (
424
+			/**
425
+			 * Filters whether a link to the "Failed Transactions" list table
426
+			 * appears on the Transactions Admin Page list table.
427
+			 * List display can be turned back on via the following:
428
+			 * add_filter(
429
+			 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
430
+			 *     '__return_true'
431
+			 * );
432
+			 *
433
+			 * @param boolean                 $display_failed_txns_list
434
+			 * @param Transactions_Admin_Page $this
435
+			 * @since 4.9.70.p
436
+			 */
437
+		apply_filters(
438
+			'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
439
+			false,
440
+			$this
441
+		)
442
+		) {
443
+			$this->_views['failed'] = [
444
+				'slug'  => 'failed',
445
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
446
+				'count' => 0,
447
+			];
448
+		}
449
+	}
450
+
451
+
452
+	/**
453
+	 * _set_transaction_object
454
+	 * This sets the _transaction property for the transaction details screen
455
+	 *
456
+	 * @access private
457
+	 * @return void
458
+	 * @throws EE_Error
459
+	 * @throws InvalidArgumentException
460
+	 * @throws RuntimeException
461
+	 * @throws InvalidDataTypeException
462
+	 * @throws InvalidInterfaceException
463
+	 * @throws ReflectionException
464
+	 */
465
+	private function _set_transaction_object()
466
+	{
467
+		if ($this->_transaction instanceof EE_Transaction) {
468
+			return;
469
+		} //get out we've already set the object
470
+
471
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
472
+
473
+		// get transaction object
474
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
475
+		$this->_session     = $this->_transaction instanceof EE_Transaction
476
+			? $this->_transaction->session_data()
477
+			: null;
478
+		if ($this->_transaction instanceof EE_Transaction) {
479
+			$this->_transaction->verify_abandoned_transaction_status();
480
+		}
481
+
482
+		if (! $this->_transaction instanceof EE_Transaction) {
483
+			$error_msg = sprintf(
484
+				esc_html__(
485
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
486
+					'event_espresso'
487
+				),
488
+				$TXN_ID
489
+			);
490
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
491
+		}
492
+	}
493
+
494
+
495
+	/**
496
+	 *    _transaction_legend_items
497
+	 *
498
+	 * @access protected
499
+	 * @return array
500
+	 * @throws EE_Error
501
+	 * @throws InvalidArgumentException
502
+	 * @throws ReflectionException
503
+	 * @throws InvalidDataTypeException
504
+	 * @throws InvalidInterfaceException
505
+	 */
506
+	protected function _transaction_legend_items()
507
+	{
508
+		EE_Registry::instance()->load_helper('MSG_Template');
509
+		$items = [];
510
+
511
+		if (
512
+			$this->capabilities->current_user_can(
513
+				'ee_read_global_messages',
514
+				'view_filtered_messages'
515
+			)
516
+		) {
517
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
518
+			if (
519
+				is_array($related_for_icon)
520
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
521
+			) {
522
+				$items['view_related_messages'] = [
523
+					'class' => $related_for_icon['css_class'],
524
+					'desc'  => $related_for_icon['label'],
525
+				];
526
+			}
527
+		}
528
+
529
+		$items = apply_filters(
530
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
531
+			array_merge(
532
+				$items,
533
+				[
534
+					'view_details'          => [
535
+						'class' => 'dashicons dashicons-cart',
536
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
537
+					],
538
+					'view_invoice'          => [
539
+						'class' => 'dashicons dashicons-media-spreadsheet',
540
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
541
+					],
542
+					'view_receipt'          => [
543
+						'class' => 'dashicons dashicons-text-page',
544
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
545
+					],
546
+					'view_registration'     => [
547
+						'class' => 'dashicons dashicons-clipboard',
548
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
549
+					],
550
+					'payment_overview_link' => [
551
+						'class' => 'dashicons dashicons-money',
552
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
553
+					],
554
+				]
555
+			)
556
+		);
557
+
558
+		if (
559
+			EEH_MSG_Template::is_mt_active('payment_reminder')
560
+			&& $this->capabilities->current_user_can(
561
+				'ee_send_message',
562
+				'espresso_transactions_send_payment_reminder'
563
+			)
564
+		) {
565
+			$items['send_payment_reminder'] = [
566
+				'class' => 'dashicons dashicons-email-alt',
567
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
568
+			];
569
+		} else {
570
+			$items['blank*'] = [
571
+				'class' => '',
572
+				'desc'  => '',
573
+			];
574
+		}
575
+		$more_items = apply_filters(
576
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
577
+			[
578
+				'overpaid'   => [
579
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
580
+					'desc'  => EEH_Template::pretty_status(
581
+						EEM_Transaction::overpaid_status_code,
582
+						false,
583
+						'sentence'
584
+					),
585
+				],
586
+				'complete'   => [
587
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
588
+					'desc'  => EEH_Template::pretty_status(
589
+						EEM_Transaction::complete_status_code,
590
+						false,
591
+						'sentence'
592
+					),
593
+				],
594
+				'incomplete' => [
595
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
596
+					'desc'  => EEH_Template::pretty_status(
597
+						EEM_Transaction::incomplete_status_code,
598
+						false,
599
+						'sentence'
600
+					),
601
+				],
602
+				'abandoned'  => [
603
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
604
+					'desc'  => EEH_Template::pretty_status(
605
+						EEM_Transaction::abandoned_status_code,
606
+						false,
607
+						'sentence'
608
+					),
609
+				],
610
+				'failed'     => [
611
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
612
+					'desc'  => EEH_Template::pretty_status(
613
+						EEM_Transaction::failed_status_code,
614
+						false,
615
+						'sentence'
616
+					),
617
+				],
618
+			]
619
+		);
620
+
621
+		return array_merge($items, $more_items);
622
+	}
623
+
624
+
625
+	/**
626
+	 *    _transactions_overview_list_table
627
+	 *
628
+	 * @access protected
629
+	 * @return void
630
+	 * @throws DomainException
631
+	 * @throws EE_Error
632
+	 * @throws InvalidArgumentException
633
+	 * @throws InvalidDataTypeException
634
+	 * @throws InvalidInterfaceException
635
+	 * @throws ReflectionException
636
+	 */
637
+	protected function _transactions_overview_list_table()
638
+	{
639
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
640
+
641
+		$EVT_ID                                    = $this->request->getRequestParam('EVT_ID', 0, 'int');
642
+		$event                                     = EEM_Event::instance()->get_one_by_ID($EVT_ID);
643
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
644
+			? sprintf(
645
+				esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
646
+				'<h3>',
647
+				'<a href="'
648
+				. EE_Admin_Page::add_query_args_and_nonce(
649
+					['action' => 'edit', 'post' => $event->ID()],
650
+					EVENTS_ADMIN_URL
651
+				)
652
+				. '" aria-label="'
653
+				. esc_attr__('Click to Edit event', 'event_espresso')
654
+				. '">' . $event->name() . '</a>',
655
+				'</h3>'
656
+			)
657
+			: '';
658
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
659
+		$this->display_admin_list_table_page_with_no_sidebar();
660
+	}
661
+
662
+
663
+	/**
664
+	 *    _transaction_details
665
+	 * generates HTML for the View Transaction Details Admin page
666
+	 *
667
+	 * @access protected
668
+	 * @return void
669
+	 * @throws DomainException
670
+	 * @throws EE_Error
671
+	 * @throws InvalidArgumentException
672
+	 * @throws InvalidDataTypeException
673
+	 * @throws InvalidInterfaceException
674
+	 * @throws RuntimeException
675
+	 * @throws ReflectionException
676
+	 */
677
+	protected function _transaction_details()
678
+	{
679
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
680
+
681
+		$this->_set_transaction_status_array();
682
+
683
+		$this->_template_args                      = [];
684
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
685
+
686
+		$this->_set_transaction_object();
687
+
688
+		if (! $this->_transaction instanceof EE_Transaction) {
689
+			return;
690
+		}
691
+
692
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
693
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
694
+
695
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
696
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
697
+
698
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
699
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
700
+		$this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
701
+
702
+		$txn_total  = $this->_transaction->total();
703
+		$total_paid = $this->_transaction->paid();
704
+		$amount_due = $txn_total - $total_paid;
705
+
706
+		$this->_template_args['grand_total'] = $txn_total;
707
+		$this->_template_args['total_paid']  = $total_paid;
708
+
709
+		$this->_template_args['amount_due']     = EEH_Template::format_currency($amount_due, false, false);
710
+		$this->_template_args['amount_due_raw'] = $amount_due;
711
+
712
+		$this->_template_args['amount_due_class'] = '';
713
+
714
+		if ($txn_total === (float) 0) {
715
+			// free event
716
+			$this->_template_args['amount_due'] = false;
717
+		} elseif ($amount_due < (float) 0) {
718
+			// overpaid
719
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
720
+		} elseif ($amount_due > (float) 0) {
721
+			// monies owing
722
+			$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
723
+		} elseif ($total_paid === (float) 0) {
724
+			// no payments made yet
725
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
726
+		}
727
+
728
+		$payment_method = $this->_transaction->payment_method();
729
+
730
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
731
+			? $payment_method->admin_name()
732
+			: esc_html__('Unknown', 'event_espresso');
733
+
734
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
735
+		// link back to overview
736
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
737
+			'HTTP_REFERER',
738
+			TXN_ADMIN_URL
739
+		);
740
+
741
+
742
+		// next link
743
+		$next_txn                                 = $this->_transaction->next(
744
+			null,
745
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
746
+			'TXN_ID'
747
+		);
748
+		$this->_template_args['next_transaction'] = $next_txn
749
+			? $this->_next_link(
750
+				EE_Admin_Page::add_query_args_and_nonce(
751
+					['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
752
+					TXN_ADMIN_URL
753
+				),
754
+				'dashicons dashicons-arrow-right ee-icon-size-22'
755
+			)
756
+			: '';
757
+		// previous link
758
+		$previous_txn                                 = $this->_transaction->previous(
759
+			null,
760
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
761
+			'TXN_ID'
762
+		);
763
+		$this->_template_args['previous_transaction'] = $previous_txn
764
+			? $this->_previous_link(
765
+				EE_Admin_Page::add_query_args_and_nonce(
766
+					['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
767
+					TXN_ADMIN_URL
768
+				),
769
+				'dashicons dashicons-arrow-left ee-icon-size-22'
770
+			)
771
+			: '';
772
+
773
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
774
+		$event_name    = $this->request->getRequestParam('event_name');
775
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
776
+
777
+		// were we just redirected here after adding a new registration ???
778
+		if ($EVT_ID && $event_name && $redirect_from) {
779
+			if (
780
+				$this->capabilities->current_user_can(
781
+					'ee_edit_registrations',
782
+					'espresso_registrations_new_registration',
783
+					$EVT_ID
784
+				)
785
+			) {
786
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
787
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
788
+					[
789
+						'page'     => 'espresso_registrations',
790
+						'action'   => 'new_registration',
791
+						'return'   => 'default',
792
+						'TXN_ID'   => $this->_transaction->ID(),
793
+						'event_id' => $EVT_ID,
794
+					],
795
+					REG_ADMIN_URL
796
+				);
797
+				$this->_admin_page_title .= '">';
798
+
799
+				$this->_admin_page_title .= sprintf(
800
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
801
+					htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
802
+				);
803
+				$this->_admin_page_title .= '</a>';
804
+			}
805
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
806
+		}
807
+		// grab messages at the last second
808
+		$this->_template_args['notices'] = EE_Error::get_notices();
809
+		// path to template
810
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
811
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
812
+			$template_path,
813
+			$this->_template_args,
814
+			true
815
+		);
816
+
817
+		// the details template wrapper
818
+		$this->display_admin_page_with_sidebar();
819
+	}
820
+
821
+
822
+	/**
823
+	 *        _transaction_details_metaboxes
824
+	 *
825
+	 * @access protected
826
+	 * @return void
827
+	 * @throws EE_Error
828
+	 * @throws InvalidArgumentException
829
+	 * @throws InvalidDataTypeException
830
+	 * @throws InvalidInterfaceException
831
+	 * @throws RuntimeException
832
+	 * @throws ReflectionException
833
+	 */
834
+	protected function _transaction_details_metaboxes()
835
+	{
836
+		$this->_set_transaction_object();
837
+
838
+		if (! $this->_transaction instanceof EE_Transaction) {
839
+			return;
840
+		}
841
+		$this->addMetaBox(
842
+			'edit-txn-details-mbox',
843
+			'<span>' . esc_html__('Transaction Details', 'event_espresso')
844
+			. '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
845
+			[$this, 'txn_details_meta_box'],
846
+			$this->_wp_page_slug
847
+		);
848
+		$this->addMetaBox(
849
+			'edit-txn-attendees-mbox',
850
+			'<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
851
+			. '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
852
+			[$this, 'txn_attendees_meta_box'],
853
+			$this->_wp_page_slug,
854
+			'normal',
855
+			'high',
856
+			['TXN_ID' => $this->_transaction->ID()]
857
+		);
858
+		$this->addMetaBox(
859
+			'edit-txn-registrant-mbox',
860
+			esc_html__('Primary Contact', 'event_espresso'),
861
+			[$this, 'txn_registrant_side_meta_box'],
862
+			$this->_wp_page_slug,
863
+			'side'
864
+		);
865
+		$this->addMetaBox(
866
+			'edit-txn-billing-info-mbox',
867
+			esc_html__('Billing Information', 'event_espresso'),
868
+			[$this, 'txn_billing_info_side_meta_box'],
869
+			$this->_wp_page_slug,
870
+			'side'
871
+		);
872
+	}
873
+
874
+
875
+	/**
876
+	 * Callback for transaction actions metabox.
877
+	 *
878
+	 * @param EE_Transaction|null $transaction
879
+	 * @return string
880
+	 * @throws DomainException
881
+	 * @throws EE_Error
882
+	 * @throws InvalidArgumentException
883
+	 * @throws InvalidDataTypeException
884
+	 * @throws InvalidInterfaceException
885
+	 * @throws ReflectionException
886
+	 * @throws RuntimeException
887
+	 */
888
+	public function getActionButtons(EE_Transaction $transaction = null)
889
+	{
890
+		$content = '';
891
+		$actions = [];
892
+		if (! $transaction instanceof EE_Transaction) {
893
+			return $content;
894
+		}
895
+		/** @var EE_Registration $primary_registration */
896
+		$primary_registration = $transaction->primary_registration();
897
+		$attendee             = $primary_registration instanceof EE_Registration
898
+			? $primary_registration->attendee()
899
+			: null;
900
+
901
+		if (
902
+			$attendee instanceof EE_Attendee
903
+			&& $this->capabilities->current_user_can(
904
+				'ee_send_message',
905
+				'espresso_transactions_send_payment_reminder'
906
+			)
907
+		) {
908
+			$actions['payment_reminder'] =
909
+				EEH_MSG_Template::is_mt_active('payment_reminder')
910
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
911
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
912
+					? EEH_Template::get_button_or_link(
913
+					EE_Admin_Page::add_query_args_and_nonce(
914
+						[
915
+							'action'      => 'send_payment_reminder',
916
+							'TXN_ID'      => $this->_transaction->ID(),
917
+							'redirect_to' => 'view_transaction',
918
+						],
919
+						TXN_ADMIN_URL
920
+					),
921
+					esc_html__(' Send Payment Reminder', 'event_espresso'),
922
+					'button button--secondary',
923
+					'dashicons dashicons-email-alt'
924
+				)
925
+					: '';
926
+		}
927
+
928
+		if (
929
+			$this->capabilities->current_user_can(
930
+				'ee_edit_payments',
931
+				'espresso_transactions_recalculate_line_items'
932
+			)
933
+		) {
934
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
935
+				EE_Admin_Page::add_query_args_and_nonce(
936
+					[
937
+						'action'      => 'espresso_recalculate_line_items',
938
+						'TXN_ID'      => $this->_transaction->ID(),
939
+						'redirect_to' => 'view_transaction',
940
+					],
941
+					TXN_ADMIN_URL
942
+				),
943
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
944
+				'button button--secondary',
945
+				'dashicons dashicons-update'
946
+			);
947
+		}
948
+
949
+		if (
950
+			$primary_registration instanceof EE_Registration
951
+			&& EEH_MSG_Template::is_mt_active('receipt')
952
+		) {
953
+			$actions['receipt'] = EEH_Template::get_button_or_link(
954
+				$primary_registration->receipt_url(),
955
+				esc_html__('View Receipt', 'event_espresso'),
956
+				'button button--secondary',
957
+				'dashicons dashicons-text-page'
958
+			);
959
+		}
960
+
961
+		if (
962
+			$primary_registration instanceof EE_Registration
963
+			&& EEH_MSG_Template::is_mt_active('invoice')
964
+		) {
965
+			$actions['invoice'] = EEH_Template::get_button_or_link(
966
+				$primary_registration->invoice_url(),
967
+				esc_html__('View Invoice', 'event_espresso'),
968
+				'button button--secondary',
969
+				'dashicons dashicons-media-spreadsheet'
970
+			);
971
+		}
972
+		$actions = array_filter(
973
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
974
+		);
975
+		if ($actions) {
976
+			$content .= implode('', $actions);
977
+		}
978
+		return $content;
979
+	}
980
+
981
+
982
+	/**
983
+	 * txn_details_meta_box
984
+	 * generates HTML for the Transaction main meta box
985
+	 *
986
+	 * @return void
987
+	 * @throws DomainException
988
+	 * @throws EE_Error
989
+	 * @throws InvalidArgumentException
990
+	 * @throws InvalidDataTypeException
991
+	 * @throws InvalidInterfaceException
992
+	 * @throws RuntimeException
993
+	 * @throws ReflectionException
994
+	 */
995
+	public function txn_details_meta_box()
996
+	{
997
+		$this->_set_transaction_object();
998
+		$this->_template_args['TXN_ID']              = $this->_transaction->ID();
999
+		$this->_template_args['attendee']            =
1000
+			$this->_transaction->primary_registration() instanceof EE_Registration
1001
+				? $this->_transaction->primary_registration()->attendee()
1002
+				: null;
1003
+		$this->_template_args['can_edit_payments']   = $this->capabilities->current_user_can(
1004
+			'ee_edit_payments',
1005
+			'apply_payment_or_refund_from_registration_details'
1006
+		);
1007
+		$this->_template_args['can_delete_payments'] = $this->capabilities->current_user_can(
1008
+			'ee_delete_payments',
1009
+			'delete_payment_from_registration_details'
1010
+		);
1011
+
1012
+		// get line table
1013
+		EEH_Autoloader::register_line_item_display_autoloaders();
1014
+		$Line_Item_Display                       = new EE_Line_Item_Display(
1015
+			'admin_table',
1016
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1017
+		);
1018
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1019
+			$this->_transaction->total_line_item()
1020
+		);
1021
+		$this->_template_args['REG_code']        =
1022
+			$this->_transaction->primary_registration() instanceof EE_Registration
1023
+				? $this->_transaction->primary_registration()->reg_code()
1024
+				: null;
1025
+		// process taxes
1026
+		$taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1027
+		$this->_template_args['taxes'] = ! empty($taxes)
1028
+			? $taxes
1029
+			: false;
1030
+
1031
+		$this->_template_args['grand_total']     = EEH_Template::format_currency(
1032
+			$this->_transaction->total(),
1033
+			false,
1034
+			false
1035
+		);
1036
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1037
+		$this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1038
+
1039
+		// process payment details
1040
+		$payments = $this->_transaction->payments();
1041
+		if (! empty($payments)) {
1042
+			$this->_template_args['payments']              = $payments;
1043
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1044
+		} else {
1045
+			$this->_template_args['payments']              = false;
1046
+			$this->_template_args['existing_reg_payments'] = [];
1047
+		}
1048
+
1049
+		$this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1050
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1051
+			['action' => 'espresso_delete_payment'],
1052
+			TXN_ADMIN_URL
1053
+		);
1054
+
1055
+		if (isset($txn_details['invoice_number'])) {
1056
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1057
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1058
+				'Invoice Number',
1059
+				'event_espresso'
1060
+			);
1061
+		}
1062
+
1063
+		$this->_template_args['txn_details']['registration_session']['value'] =
1064
+			$this->_transaction->primary_registration() instanceof EE_Registration
1065
+				? $this->_transaction->primary_registration()->session_ID()
1066
+				: null;
1067
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1068
+			'Registration Session',
1069
+			'event_espresso'
1070
+		);
1071
+
1072
+		$this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1073
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1074
+			'Transaction placed from IP',
1075
+			'event_espresso'
1076
+		);
1077
+
1078
+		$this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1079
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1080
+			'Registrant User Agent',
1081
+			'event_espresso'
1082
+		);
1083
+
1084
+		$reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1085
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1086
+			if ($reg_step_status === true) {
1087
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1088
+							  . sprintf(
1089
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1090
+								  ucwords(str_replace('_', ' ', $reg_step))
1091
+							  )
1092
+							  . '</div>';
1093
+			} elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1094
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1095
+							  . sprintf(
1096
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1097
+								  ucwords(str_replace('_', ' ', $reg_step)),
1098
+								  date(
1099
+									  get_option('date_format') . ' ' . get_option('time_format'),
1100
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1101
+								  )
1102
+							  )
1103
+							  . '</div>';
1104
+			} else {
1105
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1106
+							  . sprintf(
1107
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1108
+								  ucwords(str_replace('_', ' ', $reg_step))
1109
+							  )
1110
+							  . '</div>';
1111
+			}
1112
+		}
1113
+		$reg_steps                                                 .= '</ul>';
1114
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1115
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1116
+			'Registration Step Progress',
1117
+			'event_espresso'
1118
+		);
1119
+
1120
+
1121
+		$this->_get_registrations_to_apply_payment_to();
1122
+		$this->_get_payment_methods($payments);
1123
+		$this->_get_payment_status_array();
1124
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1125
+
1126
+		$this->_template_args['transaction_form_url']    = add_query_arg(
1127
+			[
1128
+				'action'  => 'edit_transaction',
1129
+				'process' => 'transaction',
1130
+			],
1131
+			TXN_ADMIN_URL
1132
+		);
1133
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(
1134
+			[
1135
+				'page'   => 'espresso_transactions',
1136
+				'action' => 'espresso_apply_payment',
1137
+			],
1138
+			TXN_ADMIN_URL
1139
+		);
1140
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1141
+			[
1142
+				'page'   => 'espresso_transactions',
1143
+				'action' => 'espresso_delete_payment',
1144
+			],
1145
+			TXN_ADMIN_URL
1146
+		);
1147
+
1148
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1149
+
1150
+		// 'espresso_delete_payment_nonce'
1151
+
1152
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1153
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1154
+	}
1155
+
1156
+
1157
+	/**
1158
+	 * _get_registration_payment_IDs
1159
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1160
+	 *
1161
+	 * @access protected
1162
+	 * @param EE_Payment[] $payments
1163
+	 * @return array
1164
+	 * @throws EE_Error
1165
+	 * @throws InvalidArgumentException
1166
+	 * @throws InvalidDataTypeException
1167
+	 * @throws InvalidInterfaceException
1168
+	 * @throws ReflectionException
1169
+	 */
1170
+	protected function _get_registration_payment_IDs($payments = [])
1171
+	{
1172
+		$existing_reg_payments = [];
1173
+		// get all reg payments for these payments
1174
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1175
+			[
1176
+				[
1177
+					'PAY_ID' => [
1178
+						'IN',
1179
+						array_keys($payments),
1180
+					],
1181
+				],
1182
+			]
1183
+		);
1184
+		if (! empty($reg_payments)) {
1185
+			foreach ($payments as $payment) {
1186
+				if (! $payment instanceof EE_Payment) {
1187
+					continue;
1188
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1189
+					$existing_reg_payments[ $payment->ID() ] = [];
1190
+				}
1191
+				foreach ($reg_payments as $reg_payment) {
1192
+					if (
1193
+						$reg_payment instanceof EE_Registration_Payment
1194
+						&& $reg_payment->payment_ID() === $payment->ID()
1195
+					) {
1196
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1197
+					}
1198
+				}
1199
+			}
1200
+		}
1201
+
1202
+		return $existing_reg_payments;
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * _get_registrations_to_apply_payment_to
1208
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1209
+	 * which allows the admin to only apply the payment to the specific registrations
1210
+	 *
1211
+	 * @access protected
1212
+	 * @return void
1213
+	 * @throws EE_Error
1214
+	 * @throws InvalidArgumentException
1215
+	 * @throws InvalidDataTypeException
1216
+	 * @throws InvalidInterfaceException
1217
+	 * @throws ReflectionException
1218
+	 */
1219
+	protected function _get_registrations_to_apply_payment_to()
1220
+	{
1221
+		// we want any registration with an active status (ie: not deleted or cancelled)
1222
+		$query_params                      = [
1223
+			[
1224
+				'STS_ID' => [
1225
+					'IN',
1226
+					[
1227
+						EEM_Registration::status_id_approved,
1228
+						EEM_Registration::status_id_pending_payment,
1229
+						EEM_Registration::status_id_not_approved,
1230
+					],
1231
+				],
1232
+			],
1233
+		];
1234
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1235
+				'',
1236
+				'txn-admin-apply-payment-to-registrations-dv',
1237
+				'',
1238
+				'clear: both; margin: 1.5em 0 0; display: none;'
1239
+			);
1240
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1241
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1242
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1243
+			EEH_HTML::tr(
1244
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1245
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1246
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1247
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1248
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1249
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1250
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1251
+			)
1252
+		);
1253
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1254
+		// get registrations for TXN
1255
+		$registrations         = $this->_transaction->registrations($query_params);
1256
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1257
+		foreach ($registrations as $registration) {
1258
+			if ($registration instanceof EE_Registration) {
1259
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
1260
+					? $registration->attendee()->full_name()
1261
+					: esc_html__('Unknown Attendee', 'event_espresso');
1262
+				$owing                             = $registration->final_price() - $registration->paid();
1263
+				$taxable                           = $registration->ticket()->taxable()
1264
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1265
+					: '';
1266
+				$checked                           = empty($existing_reg_payments)
1267
+													 || in_array($registration->ID(), $existing_reg_payments, true)
1268
+					? ' checked'
1269
+					: '';
1270
+				$disabled                          = $registration->final_price() > 0
1271
+					? ''
1272
+					: ' disabled';
1273
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1274
+					EEH_HTML::td($registration->ID()) .
1275
+					EEH_HTML::td($attendee_name) .
1276
+					EEH_HTML::td(
1277
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1278
+					) .
1279
+					EEH_HTML::td($registration->event_name()) .
1280
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1281
+					EEH_HTML::td(
1282
+						EEH_Template::format_currency($owing),
1283
+						'',
1284
+						'txn-admin-payment-owing-td jst-cntr'
1285
+					) .
1286
+					EEH_HTML::td(
1287
+						'<input type="checkbox" value="' . $registration->ID()
1288
+						. '" name="txn_admin_payment[registrations]"'
1289
+						. $checked . $disabled . '>',
1290
+						'',
1291
+						'jst-cntr'
1292
+					),
1293
+					'apply-payment-registration-row-' . $registration->ID()
1294
+				);
1295
+			}
1296
+		}
1297
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1298
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1299
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1300
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1301
+			esc_html__(
1302
+				'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1303
+				'event_espresso'
1304
+			),
1305
+			'',
1306
+			'clear description'
1307
+		);
1308
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1309
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1310
+	}
1311
+
1312
+
1313
+	/**
1314
+	 * _get_reg_status_selection
1315
+	 *
1316
+	 * @return void
1317
+	 * @throws EE_Error
1318
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1319
+	 *         instead of events.
1320
+	 * @access protected
1321
+	 */
1322
+	protected function _get_reg_status_selection()
1323
+	{
1324
+		// first get all possible statuses
1325
+		$statuses = EEM_Registration::reg_status_array([], true);
1326
+		// let's add a "don't change" option.
1327
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1328
+		$status_array                                        = array_merge($status_array, $statuses);
1329
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1330
+			'txn_reg_status_change[reg_status]',
1331
+			$status_array,
1332
+			'NAN',
1333
+			'id="txn-admin-payment-reg-status-inp"',
1334
+			'txn-reg-status-change-reg-status'
1335
+		);
1336
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1337
+			'delete_txn_reg_status_change[reg_status]',
1338
+			$status_array,
1339
+			'NAN',
1340
+			'delete-txn-admin-payment-reg-status-inp',
1341
+			'delete-txn-reg-status-change-reg-status'
1342
+		);
1343
+	}
1344
+
1345
+
1346
+	/**
1347
+	 *    _get_payment_methods
1348
+	 * Gets all the payment methods available generally, or the ones that are already
1349
+	 * selected on these payments (in case their payment methods are no longer active).
1350
+	 * Has the side-effect of updating the template args' payment_methods item
1351
+	 *
1352
+	 * @access private
1353
+	 * @param EE_Payment[] to show on this page
1354
+	 * @return void
1355
+	 * @throws EE_Error
1356
+	 * @throws InvalidArgumentException
1357
+	 * @throws InvalidDataTypeException
1358
+	 * @throws InvalidInterfaceException
1359
+	 * @throws ReflectionException
1360
+	 */
1361
+	private function _get_payment_methods($payments = [])
1362
+	{
1363
+		$payment_methods_of_payments = [];
1364
+		foreach ($payments as $payment) {
1365
+			if ($payment instanceof EE_Payment) {
1366
+				$payment_methods_of_payments[] = $payment->ID();
1367
+			}
1368
+		}
1369
+		if ($payment_methods_of_payments) {
1370
+			$query_args = [
1371
+				[
1372
+					'OR*payment_method_for_payment' => [
1373
+						'PMD_ID'    => ['IN', $payment_methods_of_payments],
1374
+						'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1375
+					],
1376
+				],
1377
+			];
1378
+		} else {
1379
+			$query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1380
+		}
1381
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1382
+	}
1383
+
1384
+
1385
+	/**
1386
+	 * txn_attendees_meta_box
1387
+	 *    generates HTML for the Attendees Transaction main meta box
1388
+	 *
1389
+	 * @access public
1390
+	 * @param WP_Post $post
1391
+	 * @param array   $metabox
1392
+	 * @return void
1393
+	 * @throws DomainException
1394
+	 * @throws EE_Error
1395
+	 * @throws InvalidArgumentException
1396
+	 * @throws InvalidDataTypeException
1397
+	 * @throws InvalidInterfaceException
1398
+	 * @throws ReflectionException
1399
+	 */
1400
+	public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1401
+	{
1402
+		/** @noinspection NonSecureExtractUsageInspection */
1403
+		extract($metabox['args']);
1404
+		$this->_template_args['post']            = $post;
1405
+		$this->_template_args['event_attendees'] = [];
1406
+		// process items in cart
1407
+		$line_items = $this->_transaction->get_many_related(
1408
+			'Line_Item',
1409
+			[['LIN_type' => 'line-item']]
1410
+		);
1411
+		if (! empty($line_items)) {
1412
+			foreach ($line_items as $item) {
1413
+				if ($item instanceof EE_Line_Item) {
1414
+					switch ($item->OBJ_type()) {
1415
+						case 'Event':
1416
+							break;
1417
+						case 'Ticket':
1418
+							$ticket = $item->ticket();
1419
+							// right now we're only handling tickets here.
1420
+							// Cause its expected that only tickets will have attendees right?
1421
+							if (! $ticket instanceof EE_Ticket) {
1422
+								break;
1423
+							}
1424
+							try {
1425
+								$event_name = $ticket->get_event_name();
1426
+							} catch (Exception $e) {
1427
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1428
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1429
+							}
1430
+							$event_name   .= ' - ' . $item->name();
1431
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1432
+							// now get all of the registrations for this transaction that use this ticket
1433
+							$registrations = $ticket->registrations(
1434
+								[['TXN_ID' => $this->_transaction->ID()]]
1435
+							);
1436
+							foreach ($registrations as $registration) {
1437
+								if (! $registration instanceof EE_Registration) {
1438
+									break;
1439
+								}
1440
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1441
+									= $registration->status_ID();
1442
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1443
+									= $registration->count();
1444
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1445
+									= $event_name;
1446
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1447
+									= $ticket_price;
1448
+								// attendee info
1449
+								$attendee = $registration->get_first_related('Attendee');
1450
+								if ($attendee instanceof EE_Attendee) {
1451
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1452
+										= $attendee->ID();
1453
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1454
+										= $attendee->full_name();
1455
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1456
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1457
+										  . esc_html__(
1458
+											  ' Event',
1459
+											  'event_espresso'
1460
+										  )
1461
+										  . '">' . $attendee->email() . '</a>';
1462
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1463
+										= EEH_Address::format($attendee, 'inline', false, false);
1464
+								} else {
1465
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1466
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1467
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1468
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1469
+								}
1470
+							}
1471
+							break;
1472
+					}
1473
+				}
1474
+			}
1475
+
1476
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1477
+				[
1478
+					'action'  => 'edit_transaction',
1479
+					'process' => 'attendees',
1480
+				],
1481
+				TXN_ADMIN_URL
1482
+			);
1483
+			echo EEH_Template::display_template(
1484
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1485
+				$this->_template_args,
1486
+				true
1487
+			);
1488
+		} else {
1489
+			printf(
1490
+				esc_html__(
1491
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1492
+					'event_espresso'
1493
+				),
1494
+				'<p class="important-notice">',
1495
+				'</p>'
1496
+			);
1497
+		}
1498
+	}
1499
+
1500
+
1501
+	/**
1502
+	 * txn_registrant_side_meta_box
1503
+	 * generates HTML for the Edit Transaction side meta box
1504
+	 *
1505
+	 * @access public
1506
+	 * @return void
1507
+	 * @throws DomainException
1508
+	 * @throws EE_Error
1509
+	 * @throws InvalidArgumentException
1510
+	 * @throws InvalidDataTypeException
1511
+	 * @throws InvalidInterfaceException
1512
+	 * @throws ReflectionException
1513
+	 */
1514
+	public function txn_registrant_side_meta_box()
1515
+	{
1516
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1517
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1518
+			: null;
1519
+		if (! $primary_att instanceof EE_Attendee) {
1520
+			$this->_template_args['no_attendee_message'] = esc_html__(
1521
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1522
+				'event_espresso'
1523
+			);
1524
+			$primary_att                                 = EEM_Attendee::instance()->create_default_object();
1525
+		}
1526
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1527
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1528
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1529
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1530
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1531
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1532
+			[
1533
+				'action' => 'edit_attendee',
1534
+				'post'   => $primary_att->ID(),
1535
+			],
1536
+			REG_ADMIN_URL
1537
+		);
1538
+		// get formatted address for registrant
1539
+		$formatted_address                         = EEH_Address::format($primary_att);
1540
+		$formatted_address                         =
1541
+			$formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1542
+				? $formatted_address
1543
+				: '';
1544
+		$this->_template_args['formatted_address'] = $formatted_address;
1545
+		echo EEH_Template::display_template(
1546
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1547
+			$this->_template_args,
1548
+			true
1549
+		);
1550
+	}
1551
+
1552
+
1553
+	/**
1554
+	 * txn_billing_info_side_meta_box
1555
+	 *    generates HTML for the Edit Transaction side meta box
1556
+	 *
1557
+	 * @access public
1558
+	 * @return void
1559
+	 * @throws DomainException
1560
+	 * @throws EE_Error
1561
+	 * @throws ReflectionException
1562
+	 */
1563
+	public function txn_billing_info_side_meta_box()
1564
+	{
1565
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1566
+		$this->_template_args['billing_form_url'] = add_query_arg(
1567
+			['action' => 'edit_transaction', 'process' => 'billing'],
1568
+			TXN_ADMIN_URL
1569
+		);
1570
+
1571
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1572
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1573
+	}
1574
+
1575
+
1576
+	/**
1577
+	 * apply_payments_or_refunds
1578
+	 *    registers a payment or refund made towards a transaction
1579
+	 *
1580
+	 * @access public
1581
+	 * @return void
1582
+	 * @throws EE_Error
1583
+	 * @throws InvalidArgumentException
1584
+	 * @throws ReflectionException
1585
+	 * @throws RuntimeException
1586
+	 * @throws InvalidDataTypeException
1587
+	 * @throws InvalidInterfaceException
1588
+	 */
1589
+	public function apply_payments_or_refunds()
1590
+	{
1591
+		$valid_data = $this->_validate_payment_request_data();
1592
+		$has_access = $this->capabilities->current_user_can(
1593
+			'ee_edit_payments',
1594
+			'apply_payment_or_refund_from_registration_details'
1595
+		);
1596
+		$TXD_ID     = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1597
+		$amount     = 0;
1598
+		if (! empty($valid_data) && $has_access) {
1599
+			$PAY_ID = $valid_data['PAY_ID'];
1600
+			// save  the new payment
1601
+			$payment = $this->_create_payment_from_request_data($valid_data);
1602
+			$amount  = $payment->amount();
1603
+			// get the TXN for this payment
1604
+			$transaction = $payment->transaction();
1605
+			// verify transaction
1606
+			if ($transaction instanceof EE_Transaction) {
1607
+				// calculate_total_payments_and_update_status
1608
+				$this->_process_transaction_payments($transaction);
1609
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1610
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1611
+				// apply payment to registrations (if applicable)
1612
+				if (! empty($REG_IDs)) {
1613
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1614
+					$this->_maybe_send_notifications();
1615
+					// now process status changes for the same registrations
1616
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1617
+				}
1618
+				$this->_maybe_send_notifications($payment);
1619
+				// prepare to render page
1620
+				do_action(
1621
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1622
+					$transaction,
1623
+					$payment
1624
+				);
1625
+			} else {
1626
+				EE_Error::add_error(
1627
+					esc_html__(
1628
+						'A valid Transaction for this payment could not be retrieved.',
1629
+						'event_espresso'
1630
+					),
1631
+					__FILE__,
1632
+					__FUNCTION__,
1633
+					__LINE__
1634
+				);
1635
+			}
1636
+		} elseif ($has_access) {
1637
+			EE_Error::add_error(
1638
+				esc_html__(
1639
+					'The payment form data could not be processed. Please try again.',
1640
+					'event_espresso'
1641
+				),
1642
+				__FILE__,
1643
+				__FUNCTION__,
1644
+				__LINE__
1645
+			);
1646
+		} else {
1647
+			EE_Error::add_error(
1648
+				esc_html__(
1649
+					'You do not have access to apply payments or refunds to a registration.',
1650
+					'event_espresso'
1651
+				),
1652
+				__FILE__,
1653
+				__FUNCTION__,
1654
+				__LINE__
1655
+			);
1656
+		}
1657
+		$query_args = [
1658
+			'page'   => 'espresso_transactions',
1659
+			'action' => 'view_transaction',
1660
+			'TXN_ID' => $TXD_ID,
1661
+		];
1662
+
1663
+		$this->_redirect_after_action(
1664
+			! EE_Error::has_error(),
1665
+			$amount > 0
1666
+				? esc_html__('payment', 'event_espresso')
1667
+				: esc_html__('refund', 'event_espresso'),
1668
+			esc_html__('processed', 'event_espresso'),
1669
+			$query_args
1670
+		);
1671
+	}
1672
+
1673
+
1674
+	/**
1675
+	 * _validate_payment_request_data
1676
+	 *
1677
+	 * @return array
1678
+	 * @throws EE_Error
1679
+	 * @throws InvalidArgumentException
1680
+	 * @throws InvalidDataTypeException
1681
+	 * @throws InvalidInterfaceException
1682
+	 */
1683
+	protected function _validate_payment_request_data()
1684
+	{
1685
+		if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1686
+			return [];
1687
+		}
1688
+		$payment_form = $this->_generate_payment_form_section();
1689
+		try {
1690
+			if ($payment_form->was_submitted()) {
1691
+				$payment_form->receive_form_submission();
1692
+				if (! $payment_form->is_valid()) {
1693
+					$submission_error_messages = [];
1694
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1695
+						if ($validation_error instanceof EE_Validation_Error) {
1696
+							$form_input                  = $validation_error->get_form_section();
1697
+							$submission_error_messages[] = sprintf(
1698
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1699
+								$form_input instanceof EE_Form_Input_Base
1700
+									? $form_input->html_label_text()
1701
+									: '',
1702
+								$validation_error->getMessage()
1703
+							);
1704
+						}
1705
+					}
1706
+					EE_Error::add_error(
1707
+						implode('<br />', $submission_error_messages),
1708
+						__FILE__,
1709
+						__FUNCTION__,
1710
+						__LINE__
1711
+					);
1712
+					return [];
1713
+				}
1714
+			}
1715
+		} catch (EE_Error $e) {
1716
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1717
+			return [];
1718
+		}
1719
+
1720
+		return $payment_form->valid_data();
1721
+	}
1722
+
1723
+
1724
+	/**
1725
+	 * _generate_payment_form_section
1726
+	 *
1727
+	 * @return EE_Form_Section_Proper
1728
+	 * @throws EE_Error
1729
+	 */
1730
+	protected function _generate_payment_form_section()
1731
+	{
1732
+		return new EE_Form_Section_Proper(
1733
+			[
1734
+				'name'        => 'txn_admin_payment',
1735
+				'subsections' => [
1736
+					'PAY_ID'          => new EE_Text_Input(
1737
+						[
1738
+							'default'               => 0,
1739
+							'required'              => false,
1740
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1741
+							'validation_strategies' => [new EE_Int_Normalization()],
1742
+						]
1743
+					),
1744
+					'TXN_ID'          => new EE_Text_Input(
1745
+						[
1746
+							'default'               => 0,
1747
+							'required'              => true,
1748
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1749
+							'validation_strategies' => [new EE_Int_Normalization()],
1750
+						]
1751
+					),
1752
+					'type'            => new EE_Text_Input(
1753
+						[
1754
+							'default'               => 1,
1755
+							'required'              => true,
1756
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1757
+							'validation_strategies' => [new EE_Int_Normalization()],
1758
+						]
1759
+					),
1760
+					'amount'          => new EE_Text_Input(
1761
+						[
1762
+							'default'               => 0,
1763
+							'required'              => true,
1764
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1765
+							'validation_strategies' => [new EE_Float_Normalization()],
1766
+						]
1767
+					),
1768
+					'status'          => new EE_Text_Input(
1769
+						[
1770
+							'default'         => EEM_Payment::status_id_approved,
1771
+							'required'        => true,
1772
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1773
+						]
1774
+					),
1775
+					'PMD_ID'          => new EE_Text_Input(
1776
+						[
1777
+							'default'               => 2,
1778
+							'required'              => true,
1779
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1780
+							'validation_strategies' => [new EE_Int_Normalization()],
1781
+						]
1782
+					),
1783
+					'date'            => new EE_Text_Input(
1784
+						[
1785
+							'default'         => time(),
1786
+							'required'        => true,
1787
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1788
+						]
1789
+					),
1790
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1791
+						[
1792
+							'default'               => '',
1793
+							'required'              => false,
1794
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1795
+							'validation_strategies' => [
1796
+								new EE_Max_Length_Validation_Strategy(
1797
+									esc_html__('Input too long', 'event_espresso'),
1798
+									100
1799
+								),
1800
+							],
1801
+						]
1802
+					),
1803
+					'po_number'       => new EE_Text_Input(
1804
+						[
1805
+							'default'               => '',
1806
+							'required'              => false,
1807
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1808
+							'validation_strategies' => [
1809
+								new EE_Max_Length_Validation_Strategy(
1810
+									esc_html__('Input too long', 'event_espresso'),
1811
+									100
1812
+								),
1813
+							],
1814
+						]
1815
+					),
1816
+					'accounting'      => new EE_Text_Input(
1817
+						[
1818
+							'default'               => '',
1819
+							'required'              => false,
1820
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1821
+							'validation_strategies' => [
1822
+								new EE_Max_Length_Validation_Strategy(
1823
+									esc_html__('Input too long', 'event_espresso'),
1824
+									100
1825
+								),
1826
+							],
1827
+						]
1828
+					),
1829
+				],
1830
+			]
1831
+		);
1832
+	}
1833
+
1834
+
1835
+	/**
1836
+	 * _create_payment_from_request_data
1837
+	 *
1838
+	 * @param array $valid_data
1839
+	 * @return EE_Payment
1840
+	 * @throws EE_Error
1841
+	 * @throws InvalidArgumentException
1842
+	 * @throws InvalidDataTypeException
1843
+	 * @throws InvalidInterfaceException
1844
+	 * @throws ReflectionException
1845
+	 */
1846
+	protected function _create_payment_from_request_data($valid_data)
1847
+	{
1848
+		$PAY_ID = $valid_data['PAY_ID'];
1849
+		// get payment amount
1850
+		$amount = $valid_data['amount']
1851
+			? EEH_Money::strip_localized_money_formatting($valid_data['amount'])
1852
+			: 0;
1853
+		// payments have a type value of 1 and refunds have a type value of -1
1854
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1855
+		$amount = $valid_data['type'] < 0
1856
+			? $amount * -1
1857
+			: $amount;
1858
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1859
+		$date    = $valid_data['date']
1860
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1861
+			: date('Y-m-d g:i a', current_time('timestamp'));
1862
+		$payment = EE_Payment::new_instance(
1863
+			[
1864
+				'TXN_ID'              => $valid_data['TXN_ID'],
1865
+				'STS_ID'              => $valid_data['status'],
1866
+				'PAY_timestamp'       => $date,
1867
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1868
+				'PMD_ID'              => $valid_data['PMD_ID'],
1869
+				'PAY_amount'          => $amount,
1870
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1871
+				'PAY_po_number'       => $valid_data['po_number'],
1872
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1873
+				'PAY_details'         => $valid_data,
1874
+				'PAY_ID'              => $PAY_ID,
1875
+			],
1876
+			'',
1877
+			['Y-m-d', 'g:i a']
1878
+		);
1879
+
1880
+		if (! $payment->save()) {
1881
+			EE_Error::add_error(
1882
+				sprintf(
1883
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1884
+					$payment->ID()
1885
+				),
1886
+				__FILE__,
1887
+				__FUNCTION__,
1888
+				__LINE__
1889
+			);
1890
+		}
1891
+
1892
+		return $payment;
1893
+	}
1894
+
1895
+
1896
+	/**
1897
+	 * _process_transaction_payments
1898
+	 *
1899
+	 * @param EE_Transaction $transaction
1900
+	 * @return void
1901
+	 * @throws EE_Error
1902
+	 * @throws InvalidArgumentException
1903
+	 * @throws ReflectionException
1904
+	 * @throws InvalidDataTypeException
1905
+	 * @throws InvalidInterfaceException
1906
+	 */
1907
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1908
+	{
1909
+		/** @type EE_Transaction_Payments $transaction_payments */
1910
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1911
+		// update the transaction with this payment
1912
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1913
+			EE_Error::add_success(
1914
+				esc_html__(
1915
+					'The payment has been processed successfully.',
1916
+					'event_espresso'
1917
+				),
1918
+				__FILE__,
1919
+				__FUNCTION__,
1920
+				__LINE__
1921
+			);
1922
+		} else {
1923
+			EE_Error::add_error(
1924
+				esc_html__(
1925
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1926
+					'event_espresso'
1927
+				),
1928
+				__FILE__,
1929
+				__FUNCTION__,
1930
+				__LINE__
1931
+			);
1932
+		}
1933
+	}
1934
+
1935
+
1936
+	/**
1937
+	 * _get_REG_IDs_to_apply_payment_to
1938
+	 * returns a list of registration IDs that the payment will apply to
1939
+	 *
1940
+	 * @param EE_Payment $payment
1941
+	 * @return array
1942
+	 * @throws EE_Error
1943
+	 * @throws InvalidArgumentException
1944
+	 * @throws InvalidDataTypeException
1945
+	 * @throws InvalidInterfaceException
1946
+	 * @throws ReflectionException
1947
+	 */
1948
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1949
+	{
1950
+		// grab array of IDs for specific registrations to apply changes to
1951
+		$apply_to_all = $this->request->getRequestParam(
1952
+			'txn_admin_payment[apply_to_all_registrations]',
1953
+			false,
1954
+			DataType::BOOL
1955
+		);
1956
+		$REG_IDs      = ! $apply_to_all
1957
+			? $this->request->getRequestParam(
1958
+				'txn_admin_payment[registrations]',
1959
+				[],
1960
+				DataType::INT,
1961
+				true
1962
+			)
1963
+			: [];
1964
+		// nothing specified ? then get all reg IDs
1965
+		if ($apply_to_all || empty($REG_IDs)) {
1966
+			$registrations = $payment->transaction()->registrations(
1967
+				[
1968
+					[
1969
+						'STS_ID' => [
1970
+							'NOT_IN', [ EEM_Registration::status_id_cancelled ]
1971
+						]
1972
+					]
1973
+				]
1974
+			);
1975
+			$REG_IDs       = ! empty($registrations)
1976
+				? array_keys($registrations)
1977
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1978
+		}
1979
+		// ensure that REG_IDs are integers and NOT strings
1980
+		return array_map('absint', $REG_IDs);
1981
+	}
1982
+
1983
+
1984
+	/**
1985
+	 * @return array
1986
+	 */
1987
+	public function existing_reg_payment_REG_IDs()
1988
+	{
1989
+		return $this->_existing_reg_payment_REG_IDs;
1990
+	}
1991
+
1992
+
1993
+	/**
1994
+	 * @param array $existing_reg_payment_REG_IDs
1995
+	 */
1996
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1997
+	{
1998
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1999
+	}
2000
+
2001
+
2002
+	/**
2003
+	 * _get_existing_reg_payment_REG_IDs
2004
+	 * returns a list of registration IDs that the payment is currently related to
2005
+	 * as recorded in the database
2006
+	 *
2007
+	 * @param EE_Payment $payment
2008
+	 * @return array
2009
+	 * @throws EE_Error
2010
+	 * @throws InvalidArgumentException
2011
+	 * @throws InvalidDataTypeException
2012
+	 * @throws InvalidInterfaceException
2013
+	 * @throws ReflectionException
2014
+	 */
2015
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2016
+	{
2017
+		if ($this->existing_reg_payment_REG_IDs() === null) {
2018
+			// let's get any existing reg payment records for this payment
2019
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2020
+			// but we only want the REG IDs, so grab the array keys
2021
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2022
+				? array_keys($existing_reg_payment_REG_IDs)
2023
+				: [];
2024
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2025
+		}
2026
+
2027
+		return $this->existing_reg_payment_REG_IDs();
2028
+	}
2029
+
2030
+
2031
+	/**
2032
+	 * _remove_existing_registration_payments
2033
+	 * this calculates the difference between existing relations
2034
+	 * to the supplied payment and the new list registration IDs,
2035
+	 * removes any related registrations that no longer apply,
2036
+	 * and then updates the registration paid fields
2037
+	 *
2038
+	 * @param EE_Payment $payment
2039
+	 * @param int        $PAY_ID
2040
+	 * @return bool;
2041
+	 * @throws EE_Error
2042
+	 * @throws InvalidArgumentException
2043
+	 * @throws ReflectionException
2044
+	 * @throws InvalidDataTypeException
2045
+	 * @throws InvalidInterfaceException
2046
+	 */
2047
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2048
+	{
2049
+		// newly created payments will have nothing recorded for $PAY_ID
2050
+		if (absint($PAY_ID) === 0) {
2051
+			return false;
2052
+		}
2053
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2054
+		if (empty($existing_reg_payment_REG_IDs)) {
2055
+			return false;
2056
+		}
2057
+		/** @type EE_Transaction_Payments $transaction_payments */
2058
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2059
+
2060
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2061
+			$payment,
2062
+			[
2063
+				[
2064
+					'PAY_ID' => $payment->ID(),
2065
+					'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2066
+				],
2067
+			]
2068
+		);
2069
+	}
2070
+
2071
+
2072
+	/**
2073
+	 * _update_registration_payments
2074
+	 * this applies the payments to the selected registrations
2075
+	 * but only if they have not already been paid for
2076
+	 *
2077
+	 * @param EE_Transaction $transaction
2078
+	 * @param EE_Payment     $payment
2079
+	 * @param array          $REG_IDs
2080
+	 * @return void
2081
+	 * @throws EE_Error
2082
+	 * @throws InvalidArgumentException
2083
+	 * @throws ReflectionException
2084
+	 * @throws RuntimeException
2085
+	 * @throws InvalidDataTypeException
2086
+	 * @throws InvalidInterfaceException
2087
+	 */
2088
+	protected function _update_registration_payments(
2089
+		EE_Transaction $transaction,
2090
+		EE_Payment $payment,
2091
+		$REG_IDs = []
2092
+	) {
2093
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2094
+		// so let's do that using our set of REG_IDs from the form
2095
+		$registration_query_where_params = [
2096
+			'REG_ID' => ['IN', $REG_IDs],
2097
+		];
2098
+		// but add in some conditions regarding payment,
2099
+		// so that we don't apply payments to registrations that are free or have already been paid for
2100
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2101
+		if (! $payment->is_a_refund()) {
2102
+			$registration_query_where_params['REG_final_price']  = ['!=', 0];
2103
+			$registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2104
+		}
2105
+		$registrations = $transaction->registrations([$registration_query_where_params]);
2106
+		if (! empty($registrations)) {
2107
+			/** @type EE_Payment_Processor $payment_processor */
2108
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2109
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2110
+		}
2111
+	}
2112
+
2113
+
2114
+	/**
2115
+	 * _process_registration_status_change
2116
+	 * This processes requested registration status changes for all the registrations
2117
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2118
+	 *
2119
+	 * @param EE_Transaction $transaction
2120
+	 * @param array          $REG_IDs
2121
+	 * @return bool
2122
+	 * @throws EE_Error
2123
+	 * @throws InvalidArgumentException
2124
+	 * @throws ReflectionException
2125
+	 * @throws InvalidDataTypeException
2126
+	 * @throws InvalidInterfaceException
2127
+	 */
2128
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2129
+	{
2130
+		// first if there is no change in status then we get out.
2131
+		$reg_status = $reg_status
2132
+			?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2133
+		if ($reg_status === 'NAN') {
2134
+			// no error message, no change requested, just nothing to do man.
2135
+			return false;
2136
+		}
2137
+		/** @type EE_Transaction_Processor $transaction_processor */
2138
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2139
+
2140
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2141
+		return $transaction_processor->manually_update_registration_statuses(
2142
+			$transaction,
2143
+			$reg_status,
2144
+			[['REG_ID' => ['IN', $REG_IDs]]]
2145
+		);
2146
+	}
2147
+
2148
+
2149
+	/**
2150
+	 * _build_payment_json_response
2151
+	 *
2152
+	 * @access public
2153
+	 * @param EE_Payment  $payment
2154
+	 * @param array       $REG_IDs
2155
+	 * @param bool | null $delete_txn_reg_status_change
2156
+	 * @return array
2157
+	 * @throws EE_Error
2158
+	 * @throws InvalidArgumentException
2159
+	 * @throws InvalidDataTypeException
2160
+	 * @throws InvalidInterfaceException
2161
+	 * @throws ReflectionException
2162
+	 */
2163
+	protected function _build_payment_json_response(
2164
+		EE_Payment $payment,
2165
+		$REG_IDs = [],
2166
+		$delete_txn_reg_status_change = null
2167
+	) {
2168
+		// was the payment deleted ?
2169
+		if (is_bool($delete_txn_reg_status_change)) {
2170
+			return [
2171
+				'PAY_ID'                       => $payment->ID(),
2172
+				'amount'                       => $payment->amount(),
2173
+				'total_paid'                   => $payment->transaction()->paid(),
2174
+				'txn_status'                   => $payment->transaction()->status_ID(),
2175
+				'pay_status'                   => $payment->STS_ID(),
2176
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2177
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2178
+			];
2179
+		}
2180
+
2181
+		$this->_get_payment_status_array();
2182
+		$payment_method = $payment->payment_method();
2183
+		return [
2184
+			'amount'           => $payment->amount(),
2185
+			'total_paid'       => $payment->transaction()->paid(),
2186
+			'txn_status'       => $payment->transaction()->status_ID(),
2187
+			'pay_status'       => $payment->STS_ID(),
2188
+			'PAY_ID'           => $payment->ID(),
2189
+			'STS_ID'           => $payment->STS_ID(),
2190
+			'status'           => self::$_pay_status[ $payment->STS_ID() ],
2191
+			'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2192
+			'method'           => strtoupper($payment->source()),
2193
+			'PM_ID'            => $payment_method instanceof EE_Payment_Method
2194
+				? $payment_method->ID()
2195
+				: 1,
2196
+			'gateway'          => $payment_method instanceof EE_Payment_Method
2197
+				? $payment_method->admin_name()
2198
+				: esc_html__('Unknown', 'event_espresso'),
2199
+			'gateway_response' => $payment->gateway_response(),
2200
+			'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2201
+			'po_number'        => $payment->po_number(),
2202
+			'extra_accntng'    => $payment->extra_accntng(),
2203
+			'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2204
+		];
2205
+	}
2206
+
2207
+
2208
+	/**
2209
+	 * delete_payment
2210
+	 *    delete a payment or refund made towards a transaction
2211
+	 *
2212
+	 * @access public
2213
+	 * @return void
2214
+	 * @throws EE_Error
2215
+	 * @throws InvalidArgumentException
2216
+	 * @throws ReflectionException
2217
+	 * @throws InvalidDataTypeException
2218
+	 * @throws InvalidInterfaceException
2219
+	 */
2220
+	public function delete_payment()
2221
+	{
2222
+		$TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2223
+		// $json_response_data = ['return_data' => false];
2224
+		$PAY_ID     = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2225
+		$amount     = 0;
2226
+		$can_delete = $this->capabilities->current_user_can(
2227
+			'ee_delete_payments',
2228
+			'delete_payment_from_registration_details'
2229
+		);
2230
+		if ($PAY_ID && $can_delete) {
2231
+			$delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2232
+			$payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2233
+			if ($payment instanceof EE_Payment) {
2234
+				$amount  = $payment->amount();
2235
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2236
+				/** @type EE_Transaction_Payments $transaction_payments */
2237
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2238
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2239
+					if ($delete_txn_reg_status_change) {
2240
+						$this->_maybe_send_notifications();
2241
+						$this->_process_registration_status_change(
2242
+							$payment->transaction(),
2243
+							$REG_IDs,
2244
+							$delete_txn_reg_status_change
2245
+						);
2246
+					}
2247
+				}
2248
+			} else {
2249
+				EE_Error::add_error(
2250
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2251
+					__FILE__,
2252
+					__FUNCTION__,
2253
+					__LINE__
2254
+				);
2255
+			}
2256
+		} elseif ($can_delete) {
2257
+			EE_Error::add_error(
2258
+				esc_html__(
2259
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2260
+					'event_espresso'
2261
+				),
2262
+				__FILE__,
2263
+				__FUNCTION__,
2264
+				__LINE__
2265
+			);
2266
+		} else {
2267
+			EE_Error::add_error(
2268
+				esc_html__(
2269
+					'You do not have access to delete a payment.',
2270
+					'event_espresso'
2271
+				),
2272
+				__FILE__,
2273
+				__FUNCTION__,
2274
+				__LINE__
2275
+			);
2276
+		}
2277
+		$query_args = [
2278
+			'page'   => 'espresso_transactions',
2279
+			'action' => 'view_transaction',
2280
+			'TXN_ID' => $TXD_ID,
2281
+		];
2282
+		$this->_redirect_after_action(
2283
+			! EE_Error::has_error(),
2284
+			$amount > 0
2285
+				? esc_html__('payment', 'event_espresso')
2286
+				: esc_html__('refund', 'event_espresso'),
2287
+			esc_html__('deleted', 'event_espresso'),
2288
+			$query_args
2289
+		);
2290
+	}
2291
+
2292
+
2293
+	/**
2294
+	 * _registration_payment_data_array
2295
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2296
+	 *
2297
+	 * @access protected
2298
+	 * @param array $REG_IDs
2299
+	 * @return array
2300
+	 * @throws EE_Error
2301
+	 * @throws InvalidArgumentException
2302
+	 * @throws InvalidDataTypeException
2303
+	 * @throws InvalidInterfaceException
2304
+	 * @throws ReflectionException
2305
+	 */
2306
+	protected function _registration_payment_data_array($REG_IDs)
2307
+	{
2308
+		$registration_payment_data = [];
2309
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2310
+		if (! empty($REG_IDs)) {
2311
+			$registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2312
+			foreach ($registrations as $registration) {
2313
+				if ($registration instanceof EE_Registration) {
2314
+					$registration_payment_data[ $registration->ID() ] = [
2315
+						'paid'  => $registration->pretty_paid(),
2316
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2317
+					];
2318
+				}
2319
+			}
2320
+		}
2321
+
2322
+		return $registration_payment_data;
2323
+	}
2324
+
2325
+
2326
+	/**
2327
+	 * _maybe_send_notifications
2328
+	 * determines whether or not the admin has indicated that notifications should be sent.
2329
+	 * If so, will toggle a filter switch for delivering registration notices.
2330
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2331
+	 *
2332
+	 * @access protected
2333
+	 * @param EE_Payment | null $payment
2334
+	 */
2335
+	protected function _maybe_send_notifications($payment = null)
2336
+	{
2337
+		switch ($payment instanceof EE_Payment) {
2338
+			// payment notifications
2339
+			case true:
2340
+				if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2341
+					$this->_process_payment_notification($payment);
2342
+				}
2343
+				break;
2344
+			// registration notifications
2345
+			case false:
2346
+				if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2347
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2348
+				}
2349
+				break;
2350
+		}
2351
+	}
2352
+
2353
+
2354
+	/**
2355
+	 * _send_payment_reminder
2356
+	 *    generates HTML for the View Transaction Details Admin page
2357
+	 *
2358
+	 * @access protected
2359
+	 * @return void
2360
+	 * @throws EE_Error
2361
+	 * @throws InvalidArgumentException
2362
+	 * @throws InvalidDataTypeException
2363
+	 * @throws InvalidInterfaceException
2364
+	 */
2365
+	protected function _send_payment_reminder()
2366
+	{
2367
+		$TXN_ID      = $this->request->getRequestParam('TXN_ID', 0, 'int');
2368
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2369
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2370
+		$query_args  = $redirect_to
2371
+			? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2372
+			: [];
2373
+		do_action(
2374
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2375
+			$transaction
2376
+		);
2377
+		$this->_redirect_after_action(
2378
+			false,
2379
+			esc_html__('payment reminder', 'event_espresso'),
2380
+			esc_html__('sent', 'event_espresso'),
2381
+			$query_args,
2382
+			true
2383
+		);
2384
+	}
2385
+
2386
+
2387
+	/**
2388
+	 *  get_transactions
2389
+	 *    get transactions for given parameters (used by list table)
2390
+	 *
2391
+	 * @param int     $per_page how many transactions displayed per page
2392
+	 * @param boolean $count    return the count or objects
2393
+	 * @param string  $view
2394
+	 * @return EE_Transaction[]|int int = count || array of transaction objects
2395
+	 * @throws EE_Error
2396
+	 * @throws InvalidArgumentException
2397
+	 * @throws InvalidDataTypeException
2398
+	 * @throws InvalidInterfaceException
2399
+	 * @throws ReflectionException
2400
+	 */
2401
+	public function get_transactions($per_page, $count = false, $view = '')
2402
+	{
2403
+		$start_date = wp_strip_all_tags(
2404
+			$this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2405
+		);
2406
+		$end_date   = wp_strip_all_tags(
2407
+			$this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2408
+		);
2409
+
2410
+		// make sure our timestamps start and end right at the boundaries for each day
2411
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2412
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2413
+
2414
+
2415
+		// convert to timestamps
2416
+		$start_date = strtotime($start_date);
2417
+		$end_date   = strtotime($end_date);
2418
+
2419
+		// makes sure start date is the lowest value and vice versa
2420
+		$start_date = min($start_date, $end_date);
2421
+		$end_date   = max($start_date, $end_date);
2422
+
2423
+		// convert to correct format for query
2424
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2425
+			'TXN_timestamp',
2426
+			date('Y-m-d H:i:s', $start_date),
2427
+			'Y-m-d H:i:s'
2428
+		);
2429
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2430
+			'TXN_timestamp',
2431
+			date('Y-m-d H:i:s', $end_date),
2432
+			'Y-m-d H:i:s'
2433
+		);
2434
+
2435
+
2436
+		// set orderby
2437
+		$orderby = $this->request->getRequestParam('orderby');
2438
+
2439
+		switch ($orderby) {
2440
+			case 'TXN_ID':
2441
+				break;
2442
+			case 'ATT_fname':
2443
+				$orderby = 'Registration.Attendee.ATT_fname';
2444
+				break;
2445
+			case 'event_name':
2446
+				$orderby = 'Registration.Event.EVT_name';
2447
+				break;
2448
+			default: // 'TXN_timestamp'
2449
+				$orderby = 'TXN_timestamp';
2450
+		}
2451
+
2452
+		$sort         = $this->request->getRequestParam('order', 'DESC');
2453
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
2454
+
2455
+		$per_page = absint($per_page)
2456
+			? $per_page
2457
+			: 10;
2458
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2459
+
2460
+		$offset = ($current_page - 1) * $per_page;
2461
+		$limit  = [$offset, $per_page];
2462
+
2463
+		$_where = [
2464
+			'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2465
+			'Registration.REG_count' => 1,
2466
+		];
2467
+
2468
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2469
+		if ($EVT_ID) {
2470
+			$_where['Registration.EVT_ID'] = $EVT_ID;
2471
+		}
2472
+
2473
+		$search_term = $this->request->getRequestParam('s');
2474
+		if ($search_term) {
2475
+			$search_term  = '%' . $search_term . '%';
2476
+			$_where['OR'] = [
2477
+				'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2478
+				'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2479
+				'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2480
+				'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2481
+				'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2482
+				'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2483
+				'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2484
+				'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2485
+				'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2486
+				'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2487
+				'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2488
+				'Registration.REG_final_price'        => ['LIKE', $search_term],
2489
+				'Registration.REG_code'               => ['LIKE', $search_term],
2490
+				'Registration.REG_count'              => ['LIKE', $search_term],
2491
+				'Registration.REG_group_size'         => ['LIKE', $search_term],
2492
+				'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2493
+				'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2494
+				'Payment.PAY_source'                  => ['LIKE', $search_term],
2495
+				'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2496
+				'TXN_session_data'                    => ['LIKE', $search_term],
2497
+				'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2498
+			];
2499
+		}
2500
+
2501
+		$status = $this->request->getRequestParam('status');
2502
+		// failed transactions
2503
+		$failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2504
+		$abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2505
+		$incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2506
+
2507
+		if ($failed) {
2508
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2509
+		} elseif ($abandoned) {
2510
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2511
+		} elseif ($incomplete) {
2512
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2513
+		} else {
2514
+			$_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2515
+			$_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2516
+		}
2517
+
2518
+		$query_params = apply_filters(
2519
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2520
+			[
2521
+				$_where,
2522
+				'order_by'                 => [$orderby => $sort],
2523
+				'limit'                    => $limit,
2524
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2525
+			],
2526
+			$this->request->requestParams(),
2527
+			$view,
2528
+			$count
2529
+		);
2530
+
2531
+		return $count
2532
+			? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2533
+			: EEM_Transaction::instance()->get_all($query_params);
2534
+	}
2535
+
2536
+
2537
+	/**
2538
+	 * @throws EE_Error
2539
+	 * @throws InvalidArgumentException
2540
+	 * @throws InvalidDataTypeException
2541
+	 * @throws InvalidInterfaceException
2542
+	 * @throws ReflectionException
2543
+	 * @throws RuntimeException
2544
+	 * @since 4.9.79.p
2545
+	 */
2546
+	public function recalculateLineItems()
2547
+	{
2548
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2549
+		/** @var EE_Transaction $transaction */
2550
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2551
+		$success     = $transaction->recalculateLineItems();
2552
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2553
+		$query_args  = $redirect_to
2554
+			? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2555
+			: [];
2556
+		$this->_redirect_after_action(
2557
+			$success,
2558
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2559
+			esc_html__('recalculated', 'event_espresso'),
2560
+			$query_args,
2561
+			true
2562
+		);
2563
+	}
2564 2564
 }
Please login to merge, or discard this patch.
admin_pages/maintenance/Maintenance_Admin_Page.core.php 1 patch
Indentation   +955 added lines, -955 removed lines patch added patch discarded remove patch
@@ -14,959 +14,959 @@
 block discarded – undo
14 14
  */
15 15
 class Maintenance_Admin_Page extends EE_Admin_Page
16 16
 {
17
-    /**
18
-     * @var EE_Data_Migration_Manager
19
-     */
20
-    protected $migration_manager;
21
-
22
-    /**
23
-     * @var EE_Maintenance_Mode
24
-     */
25
-    protected $maintenance_mode;
26
-
27
-    /**
28
-     * @var EE_Form_Section_Proper
29
-     */
30
-    protected $datetime_fix_offset_form;
31
-
32
-
33
-    /**
34
-     * @param bool $routing
35
-     * @throws EE_Error
36
-     * @throws ReflectionException
37
-     */
38
-    public function __construct($routing = true)
39
-    {
40
-        $this->migration_manager = EE_Data_Migration_Manager::instance();
41
-        $this->maintenance_mode  = EE_Maintenance_Mode::instance();
42
-        parent::__construct($routing);
43
-    }
44
-
45
-
46
-    protected function _init_page_props()
47
-    {
48
-        $this->page_slug        = EE_MAINTENANCE_PG_SLUG;
49
-        $this->page_label       = EE_MAINTENANCE_LABEL;
50
-        $this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
51
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
52
-    }
53
-
54
-
55
-    protected function _ajax_hooks()
56
-    {
57
-        add_action('wp_ajax_migration_step', [$this, 'migration_step']);
58
-        add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
59
-    }
60
-
61
-
62
-    protected function _define_page_props()
63
-    {
64
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
65
-        $this->_labels           = [
66
-            'buttons' => [
67
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
68
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
69
-            ],
70
-        ];
71
-    }
72
-
73
-
74
-    protected function _set_page_routes()
75
-    {
76
-        $this->_page_routes = [
77
-            'default'                             => [
78
-                'func'       => [$this, '_maintenance'],
79
-                'capability' => 'manage_options',
80
-            ],
81
-            'change_maintenance_level'            => [
82
-                'func'       => [$this, '_change_maintenance_level'],
83
-                'capability' => 'manage_options',
84
-                'noheader'   => true,
85
-            ],
86
-            'system_status'                       => [
87
-                'func'       => [$this, '_system_status'],
88
-                'capability' => 'manage_options',
89
-            ],
90
-            'download_system_status'              => [
91
-                'func'       => [$this, '_download_system_status'],
92
-                'capability' => 'manage_options',
93
-                'noheader'   => true,
94
-            ],
95
-            'send_migration_crash_report'         => [
96
-                'func'       => [$this, '_send_migration_crash_report'],
97
-                'capability' => 'manage_options',
98
-                'noheader'   => true,
99
-            ],
100
-            'confirm_migration_crash_report_sent' => [
101
-                'func'       => [$this, '_confirm_migration_crash_report_sent'],
102
-                'capability' => 'manage_options',
103
-            ],
104
-            'data_reset'                          => [
105
-                'func'       => [$this, '_data_reset_and_delete'],
106
-                'capability' => 'manage_options',
107
-            ],
108
-            'reset_db'                            => [
109
-                'func'       => [$this, '_reset_db'],
110
-                'capability' => 'manage_options',
111
-                'noheader'   => true,
112
-                'args'       => ['nuke_old_ee4_data' => true],
113
-            ],
114
-            'start_with_fresh_ee4_db'             => [
115
-                'func'       => [$this, '_reset_db'],
116
-                'capability' => 'manage_options',
117
-                'noheader'   => true,
118
-                'args'       => ['nuke_old_ee4_data' => false],
119
-            ],
120
-            'delete_db'                           => [
121
-                'func'       => [$this, '_delete_db'],
122
-                'capability' => 'manage_options',
123
-                'noheader'   => true,
124
-            ],
125
-            'rerun_migration_from_ee3'            => [
126
-                'func'       => [$this, '_rerun_migration_from_ee3'],
127
-                'capability' => 'manage_options',
128
-                'noheader'   => true,
129
-            ],
130
-            'reset_reservations'                  => [
131
-                'func'       => [$this, '_reset_reservations'],
132
-                'capability' => 'manage_options',
133
-                'noheader'   => true,
134
-            ],
135
-            'reset_capabilities'                  => [
136
-                'func'       => [$this, '_reset_capabilities'],
137
-                'capability' => 'manage_options',
138
-                'noheader'   => true,
139
-            ],
140
-            'reattempt_migration'                 => [
141
-                'func'       => [$this, '_reattempt_migration'],
142
-                'capability' => 'manage_options',
143
-                'noheader'   => true,
144
-            ],
145
-            'datetime_tools'                      => [
146
-                'func'       => [$this, '_datetime_tools'],
147
-                'capability' => 'manage_options',
148
-            ],
149
-            'run_datetime_offset_fix'             => [
150
-                'func'               => [$this, '_apply_datetime_offset'],
151
-                'noheader'           => true,
152
-                'headers_sent_route' => 'datetime_tools',
153
-                'capability'         => 'manage_options',
154
-            ],
155
-        ];
156
-    }
157
-
158
-
159
-    protected function _set_page_config()
160
-    {
161
-        $this->_page_config = [
162
-            'default'        => [
163
-                'nav'           => [
164
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
165
-                    'icon'  => 'dashicons-admin-tools',
166
-                    'order' => 10,
167
-                ],
168
-                'require_nonce' => false,
169
-            ],
170
-            'data_reset'     => [
171
-                'nav'           => [
172
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
173
-                    'icon'  => 'dashicons-trash',
174
-                    'order' => 20,
175
-                ],
176
-                'require_nonce' => false,
177
-            ],
178
-            'datetime_tools' => [
179
-                'nav'           => [
180
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
181
-                    'icon'  => 'dashicons-calendar-alt',
182
-                    'order' => 25,
183
-                ],
184
-                'require_nonce' => false,
185
-            ],
186
-            'system_status'  => [
187
-                'nav'           => [
188
-                    'label' => esc_html__("System Information", "event_espresso"),
189
-                    'icon'  => 'dashicons-info',
190
-                    'order' => 30,
191
-                ],
192
-                'require_nonce' => false,
193
-            ],
194
-        ];
195
-    }
196
-
197
-
198
-    /**
199
-     * default maintenance page.
200
-     * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
201
-     *
202
-     * @throws EE_Error
203
-     */
204
-    public function _maintenance()
205
-    {
206
-        $show_maintenance_switch         = true;
207
-        $show_backup_db_text             = false;
208
-        $show_migration_progress         = false;
209
-        $script_names                    = [];
210
-        $addons_should_be_upgraded_first = false;
211
-        // it all depends on if we're in maintenance model level 1 (frontend-only) or
212
-        // level 2 (everything except maintenance page)
213
-        try {
214
-            // get the current maintenance level and check if
215
-            // we are removed
216
-            $mMode_level  = $this->maintenance_mode->level();
217
-            $placed_in_mm = $this->maintenance_mode->set_maintenance_mode_if_db_old();
218
-            if ($mMode_level == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
219
-                // we just took the site out of maintenance mode, so notify the user.
220
-                // unfortunately this message appears to be echoed on the NEXT page load...
221
-                // oh well, we should really be checking for this on addon deactivation anyways
222
-                EE_Error::add_attention(
223
-                    esc_html__(
224
-                        'Site taken out of maintenance mode because no data migration scripts are required',
225
-                        'event_espresso'
226
-                    )
227
-                );
228
-                $this->_process_notices(['page' => 'espresso_maintenance_settings']);
229
-            }
230
-            // in case an exception is thrown while trying to handle migrations
231
-            if ($mMode_level === EE_Maintenance_Mode::level_2_complete_maintenance) {
232
-                $show_maintenance_switch = false;
233
-                $show_migration_progress = true;
234
-                if (isset($this->_req_data['continue_migration'])) {
235
-                    $show_backup_db_text = false;
236
-                } else {
237
-                    $show_backup_db_text = true;
238
-                }
239
-                $scripts_needing_to_run          =
240
-                    $this->migration_manager->check_for_applicable_data_migration_scripts();
241
-                $addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
242
-                $script_names                    = [];
243
-                $current_script                  = null;
244
-                foreach ($scripts_needing_to_run as $script) {
245
-                    if ($script instanceof EE_Data_Migration_Script_Base) {
246
-                        if (! $current_script) {
247
-                            $current_script = $script;
248
-                            $current_script->migration_page_hooks();
249
-                        }
250
-                        $script_names[] = $script->pretty_name();
251
-                    }
252
-                }
253
-            }
254
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
255
-            $exception_thrown      = false;
256
-        } catch (EE_Error $e) {
257
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
258
-            // now, just so we can display the page correctly, make an error migration script stage object
259
-            // and also put the error on it. It only persists for the duration of this request
260
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
261
-            $most_recent_migration->add_error($e->getMessage());
262
-            $exception_thrown = true;
263
-        }
264
-        $current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
265
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
266
-        if (
267
-            $exception_thrown
268
-            || (
269
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
270
-                && $most_recent_migration->is_broken()
271
-            )
272
-        ) {
273
-            $this->_template_path                =
274
-                EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
-            $this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
276
-            $this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
277
-                [
278
-                    'action'  => 'confirm_migration_crash_report_sent',
279
-                    'success' => '0',
280
-                ],
281
-                EE_MAINTENANCE_ADMIN_URL
282
-            );
283
-        } elseif ($addons_should_be_upgraded_first) {
284
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
285
-        } else {
286
-            if (
287
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
288
-                && $most_recent_migration->can_continue()
289
-            ) {
290
-                $show_backup_db_text                    = false;
291
-                $show_continue_current_migration_script = true;
292
-                $show_most_recent_migration             = true;
293
-            } elseif (isset($this->_req_data['continue_migration'])) {
294
-                $show_most_recent_migration             = true;
295
-                $show_continue_current_migration_script = false;
296
-            } else {
297
-                $show_most_recent_migration             = false;
298
-                $show_continue_current_migration_script = false;
299
-            }
300
-            if (isset($current_script)) {
301
-                $migrates_to          = $current_script->migrates_to_version();
302
-                $plugin_slug          = $migrates_to['slug'];
303
-                $new_version          = $migrates_to['version'];
304
-                $this->_template_args = array_merge(
305
-                    $this->_template_args,
306
-                    [
307
-                        'current_db_state' => sprintf(
308
-                            esc_html__("EE%s (%s)", "event_espresso"),
309
-                            isset($current_db_state[ $plugin_slug ]) ? $current_db_state[ $plugin_slug ] : 3,
310
-                            $plugin_slug
311
-                        ),
312
-                        'next_db_state'    => sprintf(
313
-                            esc_html__("EE%s (%s)", 'event_espresso'),
314
-                            $new_version,
315
-                            $plugin_slug
316
-                        ),
317
-                    ]
318
-                );
319
-            } else {
320
-                $this->_template_args['current_db_state'] = null;
321
-                $this->_template_args['next_db_state']    = null;
322
-            }
323
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
324
-            $this->_template_args = array_merge(
325
-                $this->_template_args,
326
-                [
327
-                    'show_most_recent_migration'             => $show_most_recent_migration,
328
-                    // flag for showing the most recent migration's status and/or errors
329
-                    'show_migration_progress'                => $show_migration_progress,
330
-                    // flag for showing the option to run migrations and see their progress
331
-                    'show_backup_db_text'                    => $show_backup_db_text,
332
-                    // flag for showing text telling the user to back up their DB
333
-                    'show_maintenance_switch'                => $show_maintenance_switch,
334
-                    // flag for showing the option to change maintenance mode between levels 0 and 1
335
-                    'script_names'                           => $script_names,
336
-                    // array of names of scripts that have run
337
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
338
-                    // flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
339
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
340
-                        ['action' => 'reset_db'],
341
-                        EE_MAINTENANCE_ADMIN_URL
342
-                    ),
343
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
344
-                        ['action' => 'data_reset'],
345
-                        EE_MAINTENANCE_ADMIN_URL
346
-                    ),
347
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
348
-                        ['action' => 'change_maintenance_level'],
349
-                        EE_MAINTENANCE_ADMIN_URL
350
-                    ),
351
-                    'ultimate_db_state'                      => sprintf(
352
-                        esc_html__("EE%s", 'event_espresso'),
353
-                        espresso_version()
354
-                    ),
355
-                ]
356
-            );
357
-        }
358
-        $this->_template_args['most_recent_migration'] =
359
-            $most_recent_migration;// the actual most recently ran migration
360
-        // now render the migration options part, and put it in a variable
361
-        $migration_options_template_file                = apply_filters(
362
-            'FHEE__ee_migration_page__migration_options_template',
363
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
364
-        );
365
-        $migration_options_html                         = EEH_Template::display_template(
366
-            $migration_options_template_file,
367
-            $this->_template_args,
368
-            true
369
-        );
370
-        $this->_template_args['migration_options_html'] = $migration_options_html;
371
-        $this->_template_args['admin_page_content']     = EEH_Template::display_template(
372
-            $this->_template_path,
373
-            $this->_template_args,
374
-            true
375
-        );
376
-        $this->display_admin_page_with_sidebar();
377
-    }
378
-
379
-
380
-    /**
381
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
382
-     *
383
-     * @throws EE_Error
384
-     */
385
-    public function migration_step()
386
-    {
387
-        $this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
388
-        $this->_return_json();
389
-    }
390
-
391
-
392
-    /**
393
-     * Can be used by js when it notices a response with HTML in it in order
394
-     * to log the malformed response
395
-     *
396
-     * @throws EE_Error
397
-     */
398
-    public function add_error_to_migrations_ran()
399
-    {
400
-        $this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
401
-        $this->_template_args['data'] = ['ok' => true];
402
-        $this->_return_json();
403
-    }
404
-
405
-
406
-    /**
407
-     * changes the maintenance level, provided there are still no migration scripts that should run
408
-     *
409
-     * @throws EE_Error
410
-     */
411
-    public function _change_maintenance_level()
412
-    {
413
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
414
-        if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
415
-            $this->maintenance_mode->set_maintenance_level($new_level);
416
-            $success = true;
417
-        } else {
418
-            $this->maintenance_mode->set_maintenance_mode_if_db_old();
419
-            $success = false;
420
-        }
421
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
422
-    }
423
-
424
-
425
-    /**
426
-     * a tab with options for resetting and/or deleting EE data
427
-     *
428
-     * @throws EE_Error
429
-     * @throws DomainException
430
-     */
431
-    public function _data_reset_and_delete()
432
-    {
433
-        $this->_template_path                              =
434
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
435
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
436
-            'reset_reservations',
437
-            'reset_reservations',
438
-            [],
439
-            'button button--caution ee-confirm'
440
-        );
441
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
442
-            'reset_capabilities',
443
-            'reset_capabilities',
444
-            [],
445
-            'button button--caution ee-confirm'
446
-        );
447
-        $this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
448
-            ['action' => 'delete_db'],
449
-            EE_MAINTENANCE_ADMIN_URL
450
-        );
451
-        $this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
452
-            ['action' => 'reset_db'],
453
-            EE_MAINTENANCE_ADMIN_URL
454
-        );
455
-        $this->_template_args['admin_page_content']        = EEH_Template::display_template(
456
-            $this->_template_path,
457
-            $this->_template_args,
458
-            true
459
-        );
460
-        $this->display_admin_page_with_no_sidebar();
461
-    }
462
-
463
-
464
-    /**
465
-     * @throws EE_Error
466
-     * @throws ReflectionException
467
-     */
468
-    protected function _reset_reservations()
469
-    {
470
-        if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
471
-            EE_Error::add_success(
472
-                esc_html__(
473
-                    'Ticket and datetime reserved counts have been successfully reset.',
474
-                    'event_espresso'
475
-                )
476
-            );
477
-        } else {
478
-            EE_Error::add_success(
479
-                esc_html__(
480
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
481
-                    'event_espresso'
482
-                )
483
-            );
484
-        }
485
-        $this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
486
-    }
487
-
488
-
489
-    /**
490
-     * @throws EE_Error
491
-     */
492
-    protected function _reset_capabilities()
493
-    {
494
-        $this->capabilities->init_caps(true);
495
-        EE_Error::add_success(
496
-            esc_html__(
497
-                'Default Event Espresso capabilities have been restored for all current roles.',
498
-                'event_espresso'
499
-            )
500
-        );
501
-        $this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
502
-    }
503
-
504
-
505
-    /**
506
-     * resets the DMSs, so we can attempt to continue migrating after a fatal error
507
-     * (only a good idea when someone has somehow tried ot fix whatever caused
508
-     * the fatal error in teh first place)
509
-     *
510
-     * @throws EE_Error
511
-     */
512
-    protected function _reattempt_migration()
513
-    {
514
-        $this->migration_manager->reattempt();
515
-        $this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
516
-    }
517
-
518
-
519
-    /**
520
-     * shows the big ol' System Information page
521
-     *
522
-     * @throws EE_Error
523
-     */
524
-    public function _system_status()
525
-    {
526
-        $this->_template_path                               =
527
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
528
-        $this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
529
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
530
-            [
531
-                'action' => 'download_system_status',
532
-            ],
533
-            EE_MAINTENANCE_ADMIN_URL
534
-        );
535
-        $this->_template_args['admin_page_content']         = EEH_Template::display_template(
536
-            $this->_template_path,
537
-            $this->_template_args,
538
-            true
539
-        );
540
-        $this->display_admin_page_with_no_sidebar();
541
-    }
542
-
543
-
544
-    /**
545
-     * Downloads an HTML file of the system status that can be easily stored or emailed
546
-     */
547
-    public function _download_system_status()
548
-    {
549
-        $status_info = EEM_System_Status::instance()->get_system_stati();
550
-        header('Content-Disposition: attachment');
551
-        header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
552
-        $output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
553
-        $output .= '<h1>' . sprintf(
554
-                __('System Information for %1$s', 'event_espresso'),
555
-                esc_url_raw(site_url())
556
-            ) . '</h1>';
557
-        $output .= EEH_Template::layout_array_as_table($status_info);
558
-        echo esc_html($output);
559
-        die;
560
-    }
561
-
562
-
563
-    /**
564
-     * @throws EE_Error
565
-     */
566
-    public function _send_migration_crash_report()
567
-    {
568
-        $from      = $this->_req_data['from'];
569
-        $from_name = $this->_req_data['from_name'];
570
-        $body      = $this->_req_data['body'];
571
-        try {
572
-            $success = wp_mail(
573
-                EE_SUPPORT_EMAIL,
574
-                'Migration Crash Report',
575
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
576
-                [
577
-                    "from:$from_name<$from>",
578
-                ]
579
-            );
580
-        } catch (Exception $e) {
581
-            $success = false;
582
-        }
583
-        $this->_redirect_after_action(
584
-            $success,
585
-            esc_html__("Migration Crash Report", "event_espresso"),
586
-            esc_html__("sent", "event_espresso"),
587
-            ['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
588
-        );
589
-    }
590
-
591
-
592
-    /**
593
-     * @throws EE_Error
594
-     */
595
-    public function _confirm_migration_crash_report_sent()
596
-    {
597
-        try {
598
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
599
-        } catch (EE_Error $e) {
600
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
601
-            // now, just so we can display the page correctly, make an error migration script stage object
602
-            // and also put the error on it. It only persists for the duration of this request
603
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
604
-            $most_recent_migration->add_error($e->getMessage());
605
-        }
606
-        $success                                       = $this->_req_data['success'] === '1';
607
-        $this->_template_args['success']               = $success;
608
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
609
-        $this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
610
-            ['action' => 'reset_db'],
611
-            EE_MAINTENANCE_ADMIN_URL
612
-        );
613
-        $this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
614
-            ['action' => 'data_reset'],
615
-            EE_MAINTENANCE_ADMIN_URL
616
-        );
617
-        $this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
618
-            ['action' => 'reattempt_migration'],
619
-            EE_MAINTENANCE_ADMIN_URL
620
-        );
621
-        $this->_template_path                          =
622
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
623
-        $this->_template_args['admin_page_content']    = EEH_Template::display_template(
624
-            $this->_template_path,
625
-            $this->_template_args,
626
-            true
627
-        );
628
-        $this->display_admin_page_with_sidebar();
629
-    }
630
-
631
-
632
-    /**
633
-     * Resets the entire EE4 database.
634
-     * only sets up ee4 database for a fresh install-
635
-     * doesn't actually clean out the old wp options, or cpts
636
-     * (although it does erase old ee table data)
637
-     *
638
-     * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
639
-     *                                   or just try initializing ee4 default data
640
-     * @throws EE_Error
641
-     * @throws ReflectionException
642
-     */
643
-    public function _reset_db($nuke_old_ee4_data = true)
644
-    {
645
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
646
-        if ($nuke_old_ee4_data) {
647
-            EEH_Activation::delete_all_espresso_cpt_data();
648
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
649
-            EEH_Activation::remove_cron_tasks();
650
-        }
651
-        // make sure when we reset the registry's config that it
652
-        // switches to using the new singleton
653
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
654
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
655
-        EE_System::instance()->redirect_to_about_ee();
656
-    }
657
-
658
-
659
-    /**
660
-     * Deletes ALL EE tables, Records, and Options from the database.
661
-     *
662
-     * @throws EE_Error
663
-     * @throws ReflectionException
664
-     */
665
-    public function _delete_db()
666
-    {
667
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
668
-        EEH_Activation::delete_all_espresso_cpt_data();
669
-        EEH_Activation::delete_all_espresso_tables_and_data();
670
-        EEH_Activation::remove_cron_tasks();
671
-        EEH_Activation::deactivate_event_espresso();
672
-        wp_safe_redirect(admin_url('plugins.php'));
673
-        exit;
674
-    }
675
-
676
-
677
-    /**
678
-     * sets up EE4 to rerun the migrations from ee3 to ee4
679
-     *
680
-     * @throws EE_Error
681
-     * @throws ReflectionException
682
-     */
683
-    public function _rerun_migration_from_ee3()
684
-    {
685
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
686
-        EEH_Activation::delete_all_espresso_cpt_data();
687
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
688
-        // set the db state to something that will require migrations
689
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
690
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
691
-        $this->_redirect_after_action(
692
-            true,
693
-            esc_html__("Database", 'event_espresso'),
694
-            esc_html__("reset", 'event_espresso')
695
-        );
696
-    }
697
-
698
-
699
-    // none of the below group are currently used for Gateway Settings
700
-    protected function _add_screen_options()
701
-    {
702
-    }
703
-
704
-
705
-    protected function _add_feature_pointers()
706
-    {
707
-    }
708
-
709
-
710
-    public function admin_init()
711
-    {
712
-    }
713
-
714
-
715
-    public function admin_notices()
716
-    {
717
-    }
718
-
719
-
720
-    public function admin_footer_scripts()
721
-    {
722
-    }
723
-
724
-
725
-    public function load_scripts_styles()
726
-    {
727
-        wp_enqueue_script('ee_admin_js');
728
-        wp_enqueue_script(
729
-            'ee-maintenance',
730
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
731
-            ['jquery'],
732
-            EVENT_ESPRESSO_VERSION,
733
-            true
734
-        );
735
-        wp_register_style(
736
-            'espresso_maintenance',
737
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
738
-            [],
739
-            EVENT_ESPRESSO_VERSION
740
-        );
741
-        wp_enqueue_style('espresso_maintenance');
742
-        // localize script stuff
743
-        wp_localize_script(
744
-            'ee-maintenance',
745
-            'ee_maintenance',
746
-            [
747
-                'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
748
-                'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
749
-                'fatal_error'                      => wp_strip_all_tags(
750
-                    __(
751
-                        "A Fatal Error Has Occurred",
752
-                        "event_espresso"
753
-                    )
754
-                ),
755
-                'click_next_when_ready'            => wp_strip_all_tags(
756
-                    __(
757
-                        "The current Database Update has ended. Click 'next' when ready to proceed",
758
-                        "event_espresso"
759
-                    )
760
-                ),
761
-                'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
762
-                'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
763
-                'status_completed'                 => EE_Data_Migration_Manager::status_completed,
764
-                'confirm'                          => wp_strip_all_tags(
765
-                    __(
766
-                        'Are you sure you want to do this? It CANNOT be undone!',
767
-                        'event_espresso'
768
-                    )
769
-                ),
770
-                'confirm_skip_migration'           => wp_strip_all_tags(
771
-                    __(
772
-                        'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
773
-                        'event_espresso'
774
-                    )
775
-                ),
776
-            ]
777
-        );
778
-    }
779
-
780
-
781
-    public function load_scripts_styles_default()
782
-    {
783
-    }
784
-
785
-
786
-    /**
787
-     * Enqueue scripts and styles for the datetime tools page.
788
-     */
789
-    public function load_scripts_styles_datetime_tools()
790
-    {
791
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
792
-    }
793
-
794
-
795
-    /**
796
-     * @throws EE_Error
797
-     */
798
-    protected function _datetime_tools()
799
-    {
800
-        $form_action                                = EE_Admin_Page::add_query_args_and_nonce(
801
-            [
802
-                'action'        => 'run_datetime_offset_fix',
803
-                'return_action' => $this->_req_action,
804
-            ],
805
-            EE_MAINTENANCE_ADMIN_URL
806
-        );
807
-        $form                                       = $this->_get_datetime_offset_fix_form();
808
-        $this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
809
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
810
-                                                      . $form->get_html_and_js()
811
-                                                      . $form->form_close();
812
-        $this->display_admin_page_with_sidebar();
813
-    }
814
-
815
-
816
-    /**
817
-     * @throws EE_Error
818
-     */
819
-    protected function _get_datetime_offset_fix_form()
820
-    {
821
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
822
-            $this->datetime_fix_offset_form = new EE_Form_Section_Proper(
823
-                [
824
-                    'name'            => 'datetime_offset_fix_option',
825
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
826
-                    'subsections'     => [
827
-                        'title'                  => new EE_Form_Section_HTML(
828
-                            EEH_HTML::h2(
829
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
830
-                            )
831
-                        ),
832
-                        'explanation'            => new EE_Form_Section_HTML(
833
-                            EEH_HTML::p(
834
-                                esc_html__(
835
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
836
-                                    'event_espresso'
837
-                                )
838
-                            )
839
-                            . EEH_HTML::p(
840
-                                esc_html__(
841
-                                    'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
842
-                                    'event_espresso'
843
-                                )
844
-                            )
845
-                        ),
846
-                        'offset_input'           => new EE_Float_Input(
847
-                            [
848
-                                'html_name'       => 'offset_for_datetimes',
849
-                                'html_label_text' => esc_html__(
850
-                                    'Offset to apply (in hours):',
851
-                                    'event_espresso'
852
-                                ),
853
-                                'min_value'       => '-12',
854
-                                'max_value'       => '14',
855
-                                'step_value'      => '.25',
856
-                                'default'         => DatetimeOffsetFix::getOffset(),
857
-                            ]
858
-                        ),
859
-                        'date_range_explanation' => new EE_Form_Section_HTML(
860
-                            EEH_HTML::p(
861
-                                esc_html__(
862
-                                    'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
863
-                                    'event_espresso'
864
-                                )
865
-                            )
866
-                            . EEH_HTML::p(
867
-                                EEH_HTML::strong(
868
-                                    sprintf(
869
-                                        esc_html__(
870
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
871
-                                            'event_espresso'
872
-                                        ),
873
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
874
-                                        '</a>'
875
-                                    )
876
-                                )
877
-                            )
878
-                        ),
879
-                        'date_range_start_date'  => new EE_Datepicker_Input(
880
-                            [
881
-                                'html_name'       => 'offset_date_start_range',
882
-                                'html_label_text' => esc_html__(
883
-                                    'Start Date for dates the offset applied to:',
884
-                                    'event_espresso'
885
-                                ),
886
-                            ]
887
-                        ),
888
-                        'date_range_end_date'    => new EE_Datepicker_Input(
889
-                            [
890
-                                'html_name'       => 'offset_date_end_range',
891
-                                'html_label_text' => esc_html__(
892
-                                    'End Date for dates the offset is applied to:',
893
-                                    'event_espresso'
894
-                                ),
895
-                            ]
896
-                        ),
897
-                        'submit'                 => new EE_Submit_Input(
898
-                            [
899
-                                'html_label_text' => '',
900
-                                'default'         => esc_html__('Apply Offset', 'event_espresso'),
901
-                            ]
902
-                        ),
903
-                    ],
904
-                ]
905
-            );
906
-        }
907
-        return $this->datetime_fix_offset_form;
908
-    }
909
-
910
-
911
-    /**
912
-     * Callback for the run_datetime_offset_fix route.
913
-     *
914
-     * @throws EE_Error
915
-     */
916
-    protected function _apply_datetime_offset()
917
-    {
918
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
919
-            $form = $this->_get_datetime_offset_fix_form();
920
-            $form->receive_form_submission($this->_req_data);
921
-            if ($form->is_valid()) {
922
-                // save offset data so batch processor can get it.
923
-                DatetimeOffsetFix::updateOffset((float) $form->get_input_value('offset_input'));
924
-                $utc_timezone          = new DateTimeZone('UTC');
925
-                $date_range_start_date = DateTime::createFromFormat(
926
-                    'm/d/Y H:i:s',
927
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
928
-                    $utc_timezone
929
-                );
930
-                $date_range_end_date   = DateTime::createFromFormat(
931
-                    'm/d/Y H:i:s',
932
-                    $form->get_input_value('date_range_end_date') . ' 23:59:59',
933
-                    $utc_timezone
934
-                );
935
-                if ($date_range_start_date instanceof DateTime) {
936
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
937
-                }
938
-                if ($date_range_end_date instanceof DateTime) {
939
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
940
-                }
941
-                // redirect to batch tool
942
-                wp_redirect(
943
-                    EE_Admin_Page::add_query_args_and_nonce(
944
-                        [
945
-                            'page'        => EED_Batch::PAGE_SLUG,
946
-                            'batch'       => EED_Batch::batch_job,
947
-                            'label'       => esc_html__('Applying Offset', 'event_espresso'),
948
-                            'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\DatetimeOffsetFix'),
949
-                            'return_url'  => urlencode(
950
-                                add_query_arg(
951
-                                    [
952
-                                        'action' => 'datetime_tools',
953
-                                    ],
954
-                                    EEH_URL::current_url_without_query_paramaters(
955
-                                        [
956
-                                            'return_action',
957
-                                            'run_datetime_offset_fix_nonce',
958
-                                            'return',
959
-                                            'datetime_tools_nonce',
960
-                                        ]
961
-                                    )
962
-                                )
963
-                            ),
964
-                        ],
965
-                        admin_url()
966
-                    )
967
-                );
968
-                exit;
969
-            }
970
-        }
971
-    }
17
+	/**
18
+	 * @var EE_Data_Migration_Manager
19
+	 */
20
+	protected $migration_manager;
21
+
22
+	/**
23
+	 * @var EE_Maintenance_Mode
24
+	 */
25
+	protected $maintenance_mode;
26
+
27
+	/**
28
+	 * @var EE_Form_Section_Proper
29
+	 */
30
+	protected $datetime_fix_offset_form;
31
+
32
+
33
+	/**
34
+	 * @param bool $routing
35
+	 * @throws EE_Error
36
+	 * @throws ReflectionException
37
+	 */
38
+	public function __construct($routing = true)
39
+	{
40
+		$this->migration_manager = EE_Data_Migration_Manager::instance();
41
+		$this->maintenance_mode  = EE_Maintenance_Mode::instance();
42
+		parent::__construct($routing);
43
+	}
44
+
45
+
46
+	protected function _init_page_props()
47
+	{
48
+		$this->page_slug        = EE_MAINTENANCE_PG_SLUG;
49
+		$this->page_label       = EE_MAINTENANCE_LABEL;
50
+		$this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
51
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
52
+	}
53
+
54
+
55
+	protected function _ajax_hooks()
56
+	{
57
+		add_action('wp_ajax_migration_step', [$this, 'migration_step']);
58
+		add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
59
+	}
60
+
61
+
62
+	protected function _define_page_props()
63
+	{
64
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
65
+		$this->_labels           = [
66
+			'buttons' => [
67
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
68
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
69
+			],
70
+		];
71
+	}
72
+
73
+
74
+	protected function _set_page_routes()
75
+	{
76
+		$this->_page_routes = [
77
+			'default'                             => [
78
+				'func'       => [$this, '_maintenance'],
79
+				'capability' => 'manage_options',
80
+			],
81
+			'change_maintenance_level'            => [
82
+				'func'       => [$this, '_change_maintenance_level'],
83
+				'capability' => 'manage_options',
84
+				'noheader'   => true,
85
+			],
86
+			'system_status'                       => [
87
+				'func'       => [$this, '_system_status'],
88
+				'capability' => 'manage_options',
89
+			],
90
+			'download_system_status'              => [
91
+				'func'       => [$this, '_download_system_status'],
92
+				'capability' => 'manage_options',
93
+				'noheader'   => true,
94
+			],
95
+			'send_migration_crash_report'         => [
96
+				'func'       => [$this, '_send_migration_crash_report'],
97
+				'capability' => 'manage_options',
98
+				'noheader'   => true,
99
+			],
100
+			'confirm_migration_crash_report_sent' => [
101
+				'func'       => [$this, '_confirm_migration_crash_report_sent'],
102
+				'capability' => 'manage_options',
103
+			],
104
+			'data_reset'                          => [
105
+				'func'       => [$this, '_data_reset_and_delete'],
106
+				'capability' => 'manage_options',
107
+			],
108
+			'reset_db'                            => [
109
+				'func'       => [$this, '_reset_db'],
110
+				'capability' => 'manage_options',
111
+				'noheader'   => true,
112
+				'args'       => ['nuke_old_ee4_data' => true],
113
+			],
114
+			'start_with_fresh_ee4_db'             => [
115
+				'func'       => [$this, '_reset_db'],
116
+				'capability' => 'manage_options',
117
+				'noheader'   => true,
118
+				'args'       => ['nuke_old_ee4_data' => false],
119
+			],
120
+			'delete_db'                           => [
121
+				'func'       => [$this, '_delete_db'],
122
+				'capability' => 'manage_options',
123
+				'noheader'   => true,
124
+			],
125
+			'rerun_migration_from_ee3'            => [
126
+				'func'       => [$this, '_rerun_migration_from_ee3'],
127
+				'capability' => 'manage_options',
128
+				'noheader'   => true,
129
+			],
130
+			'reset_reservations'                  => [
131
+				'func'       => [$this, '_reset_reservations'],
132
+				'capability' => 'manage_options',
133
+				'noheader'   => true,
134
+			],
135
+			'reset_capabilities'                  => [
136
+				'func'       => [$this, '_reset_capabilities'],
137
+				'capability' => 'manage_options',
138
+				'noheader'   => true,
139
+			],
140
+			'reattempt_migration'                 => [
141
+				'func'       => [$this, '_reattempt_migration'],
142
+				'capability' => 'manage_options',
143
+				'noheader'   => true,
144
+			],
145
+			'datetime_tools'                      => [
146
+				'func'       => [$this, '_datetime_tools'],
147
+				'capability' => 'manage_options',
148
+			],
149
+			'run_datetime_offset_fix'             => [
150
+				'func'               => [$this, '_apply_datetime_offset'],
151
+				'noheader'           => true,
152
+				'headers_sent_route' => 'datetime_tools',
153
+				'capability'         => 'manage_options',
154
+			],
155
+		];
156
+	}
157
+
158
+
159
+	protected function _set_page_config()
160
+	{
161
+		$this->_page_config = [
162
+			'default'        => [
163
+				'nav'           => [
164
+					'label' => esc_html__('Maintenance', 'event_espresso'),
165
+					'icon'  => 'dashicons-admin-tools',
166
+					'order' => 10,
167
+				],
168
+				'require_nonce' => false,
169
+			],
170
+			'data_reset'     => [
171
+				'nav'           => [
172
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
173
+					'icon'  => 'dashicons-trash',
174
+					'order' => 20,
175
+				],
176
+				'require_nonce' => false,
177
+			],
178
+			'datetime_tools' => [
179
+				'nav'           => [
180
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
181
+					'icon'  => 'dashicons-calendar-alt',
182
+					'order' => 25,
183
+				],
184
+				'require_nonce' => false,
185
+			],
186
+			'system_status'  => [
187
+				'nav'           => [
188
+					'label' => esc_html__("System Information", "event_espresso"),
189
+					'icon'  => 'dashicons-info',
190
+					'order' => 30,
191
+				],
192
+				'require_nonce' => false,
193
+			],
194
+		];
195
+	}
196
+
197
+
198
+	/**
199
+	 * default maintenance page.
200
+	 * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
201
+	 *
202
+	 * @throws EE_Error
203
+	 */
204
+	public function _maintenance()
205
+	{
206
+		$show_maintenance_switch         = true;
207
+		$show_backup_db_text             = false;
208
+		$show_migration_progress         = false;
209
+		$script_names                    = [];
210
+		$addons_should_be_upgraded_first = false;
211
+		// it all depends on if we're in maintenance model level 1 (frontend-only) or
212
+		// level 2 (everything except maintenance page)
213
+		try {
214
+			// get the current maintenance level and check if
215
+			// we are removed
216
+			$mMode_level  = $this->maintenance_mode->level();
217
+			$placed_in_mm = $this->maintenance_mode->set_maintenance_mode_if_db_old();
218
+			if ($mMode_level == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
219
+				// we just took the site out of maintenance mode, so notify the user.
220
+				// unfortunately this message appears to be echoed on the NEXT page load...
221
+				// oh well, we should really be checking for this on addon deactivation anyways
222
+				EE_Error::add_attention(
223
+					esc_html__(
224
+						'Site taken out of maintenance mode because no data migration scripts are required',
225
+						'event_espresso'
226
+					)
227
+				);
228
+				$this->_process_notices(['page' => 'espresso_maintenance_settings']);
229
+			}
230
+			// in case an exception is thrown while trying to handle migrations
231
+			if ($mMode_level === EE_Maintenance_Mode::level_2_complete_maintenance) {
232
+				$show_maintenance_switch = false;
233
+				$show_migration_progress = true;
234
+				if (isset($this->_req_data['continue_migration'])) {
235
+					$show_backup_db_text = false;
236
+				} else {
237
+					$show_backup_db_text = true;
238
+				}
239
+				$scripts_needing_to_run          =
240
+					$this->migration_manager->check_for_applicable_data_migration_scripts();
241
+				$addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
242
+				$script_names                    = [];
243
+				$current_script                  = null;
244
+				foreach ($scripts_needing_to_run as $script) {
245
+					if ($script instanceof EE_Data_Migration_Script_Base) {
246
+						if (! $current_script) {
247
+							$current_script = $script;
248
+							$current_script->migration_page_hooks();
249
+						}
250
+						$script_names[] = $script->pretty_name();
251
+					}
252
+				}
253
+			}
254
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
255
+			$exception_thrown      = false;
256
+		} catch (EE_Error $e) {
257
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
258
+			// now, just so we can display the page correctly, make an error migration script stage object
259
+			// and also put the error on it. It only persists for the duration of this request
260
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
261
+			$most_recent_migration->add_error($e->getMessage());
262
+			$exception_thrown = true;
263
+		}
264
+		$current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
265
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
266
+		if (
267
+			$exception_thrown
268
+			|| (
269
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
270
+				&& $most_recent_migration->is_broken()
271
+			)
272
+		) {
273
+			$this->_template_path                =
274
+				EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
+			$this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
276
+			$this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
277
+				[
278
+					'action'  => 'confirm_migration_crash_report_sent',
279
+					'success' => '0',
280
+				],
281
+				EE_MAINTENANCE_ADMIN_URL
282
+			);
283
+		} elseif ($addons_should_be_upgraded_first) {
284
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
285
+		} else {
286
+			if (
287
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
288
+				&& $most_recent_migration->can_continue()
289
+			) {
290
+				$show_backup_db_text                    = false;
291
+				$show_continue_current_migration_script = true;
292
+				$show_most_recent_migration             = true;
293
+			} elseif (isset($this->_req_data['continue_migration'])) {
294
+				$show_most_recent_migration             = true;
295
+				$show_continue_current_migration_script = false;
296
+			} else {
297
+				$show_most_recent_migration             = false;
298
+				$show_continue_current_migration_script = false;
299
+			}
300
+			if (isset($current_script)) {
301
+				$migrates_to          = $current_script->migrates_to_version();
302
+				$plugin_slug          = $migrates_to['slug'];
303
+				$new_version          = $migrates_to['version'];
304
+				$this->_template_args = array_merge(
305
+					$this->_template_args,
306
+					[
307
+						'current_db_state' => sprintf(
308
+							esc_html__("EE%s (%s)", "event_espresso"),
309
+							isset($current_db_state[ $plugin_slug ]) ? $current_db_state[ $plugin_slug ] : 3,
310
+							$plugin_slug
311
+						),
312
+						'next_db_state'    => sprintf(
313
+							esc_html__("EE%s (%s)", 'event_espresso'),
314
+							$new_version,
315
+							$plugin_slug
316
+						),
317
+					]
318
+				);
319
+			} else {
320
+				$this->_template_args['current_db_state'] = null;
321
+				$this->_template_args['next_db_state']    = null;
322
+			}
323
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
324
+			$this->_template_args = array_merge(
325
+				$this->_template_args,
326
+				[
327
+					'show_most_recent_migration'             => $show_most_recent_migration,
328
+					// flag for showing the most recent migration's status and/or errors
329
+					'show_migration_progress'                => $show_migration_progress,
330
+					// flag for showing the option to run migrations and see their progress
331
+					'show_backup_db_text'                    => $show_backup_db_text,
332
+					// flag for showing text telling the user to back up their DB
333
+					'show_maintenance_switch'                => $show_maintenance_switch,
334
+					// flag for showing the option to change maintenance mode between levels 0 and 1
335
+					'script_names'                           => $script_names,
336
+					// array of names of scripts that have run
337
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
338
+					// flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
339
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
340
+						['action' => 'reset_db'],
341
+						EE_MAINTENANCE_ADMIN_URL
342
+					),
343
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
344
+						['action' => 'data_reset'],
345
+						EE_MAINTENANCE_ADMIN_URL
346
+					),
347
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
348
+						['action' => 'change_maintenance_level'],
349
+						EE_MAINTENANCE_ADMIN_URL
350
+					),
351
+					'ultimate_db_state'                      => sprintf(
352
+						esc_html__("EE%s", 'event_espresso'),
353
+						espresso_version()
354
+					),
355
+				]
356
+			);
357
+		}
358
+		$this->_template_args['most_recent_migration'] =
359
+			$most_recent_migration;// the actual most recently ran migration
360
+		// now render the migration options part, and put it in a variable
361
+		$migration_options_template_file                = apply_filters(
362
+			'FHEE__ee_migration_page__migration_options_template',
363
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
364
+		);
365
+		$migration_options_html                         = EEH_Template::display_template(
366
+			$migration_options_template_file,
367
+			$this->_template_args,
368
+			true
369
+		);
370
+		$this->_template_args['migration_options_html'] = $migration_options_html;
371
+		$this->_template_args['admin_page_content']     = EEH_Template::display_template(
372
+			$this->_template_path,
373
+			$this->_template_args,
374
+			true
375
+		);
376
+		$this->display_admin_page_with_sidebar();
377
+	}
378
+
379
+
380
+	/**
381
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
382
+	 *
383
+	 * @throws EE_Error
384
+	 */
385
+	public function migration_step()
386
+	{
387
+		$this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
388
+		$this->_return_json();
389
+	}
390
+
391
+
392
+	/**
393
+	 * Can be used by js when it notices a response with HTML in it in order
394
+	 * to log the malformed response
395
+	 *
396
+	 * @throws EE_Error
397
+	 */
398
+	public function add_error_to_migrations_ran()
399
+	{
400
+		$this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
401
+		$this->_template_args['data'] = ['ok' => true];
402
+		$this->_return_json();
403
+	}
404
+
405
+
406
+	/**
407
+	 * changes the maintenance level, provided there are still no migration scripts that should run
408
+	 *
409
+	 * @throws EE_Error
410
+	 */
411
+	public function _change_maintenance_level()
412
+	{
413
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
414
+		if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
415
+			$this->maintenance_mode->set_maintenance_level($new_level);
416
+			$success = true;
417
+		} else {
418
+			$this->maintenance_mode->set_maintenance_mode_if_db_old();
419
+			$success = false;
420
+		}
421
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
422
+	}
423
+
424
+
425
+	/**
426
+	 * a tab with options for resetting and/or deleting EE data
427
+	 *
428
+	 * @throws EE_Error
429
+	 * @throws DomainException
430
+	 */
431
+	public function _data_reset_and_delete()
432
+	{
433
+		$this->_template_path                              =
434
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
435
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
436
+			'reset_reservations',
437
+			'reset_reservations',
438
+			[],
439
+			'button button--caution ee-confirm'
440
+		);
441
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
442
+			'reset_capabilities',
443
+			'reset_capabilities',
444
+			[],
445
+			'button button--caution ee-confirm'
446
+		);
447
+		$this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
448
+			['action' => 'delete_db'],
449
+			EE_MAINTENANCE_ADMIN_URL
450
+		);
451
+		$this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
452
+			['action' => 'reset_db'],
453
+			EE_MAINTENANCE_ADMIN_URL
454
+		);
455
+		$this->_template_args['admin_page_content']        = EEH_Template::display_template(
456
+			$this->_template_path,
457
+			$this->_template_args,
458
+			true
459
+		);
460
+		$this->display_admin_page_with_no_sidebar();
461
+	}
462
+
463
+
464
+	/**
465
+	 * @throws EE_Error
466
+	 * @throws ReflectionException
467
+	 */
468
+	protected function _reset_reservations()
469
+	{
470
+		if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
471
+			EE_Error::add_success(
472
+				esc_html__(
473
+					'Ticket and datetime reserved counts have been successfully reset.',
474
+					'event_espresso'
475
+				)
476
+			);
477
+		} else {
478
+			EE_Error::add_success(
479
+				esc_html__(
480
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
481
+					'event_espresso'
482
+				)
483
+			);
484
+		}
485
+		$this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
486
+	}
487
+
488
+
489
+	/**
490
+	 * @throws EE_Error
491
+	 */
492
+	protected function _reset_capabilities()
493
+	{
494
+		$this->capabilities->init_caps(true);
495
+		EE_Error::add_success(
496
+			esc_html__(
497
+				'Default Event Espresso capabilities have been restored for all current roles.',
498
+				'event_espresso'
499
+			)
500
+		);
501
+		$this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
502
+	}
503
+
504
+
505
+	/**
506
+	 * resets the DMSs, so we can attempt to continue migrating after a fatal error
507
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
508
+	 * the fatal error in teh first place)
509
+	 *
510
+	 * @throws EE_Error
511
+	 */
512
+	protected function _reattempt_migration()
513
+	{
514
+		$this->migration_manager->reattempt();
515
+		$this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
516
+	}
517
+
518
+
519
+	/**
520
+	 * shows the big ol' System Information page
521
+	 *
522
+	 * @throws EE_Error
523
+	 */
524
+	public function _system_status()
525
+	{
526
+		$this->_template_path                               =
527
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
528
+		$this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
529
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
530
+			[
531
+				'action' => 'download_system_status',
532
+			],
533
+			EE_MAINTENANCE_ADMIN_URL
534
+		);
535
+		$this->_template_args['admin_page_content']         = EEH_Template::display_template(
536
+			$this->_template_path,
537
+			$this->_template_args,
538
+			true
539
+		);
540
+		$this->display_admin_page_with_no_sidebar();
541
+	}
542
+
543
+
544
+	/**
545
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
546
+	 */
547
+	public function _download_system_status()
548
+	{
549
+		$status_info = EEM_System_Status::instance()->get_system_stati();
550
+		header('Content-Disposition: attachment');
551
+		header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
552
+		$output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
553
+		$output .= '<h1>' . sprintf(
554
+				__('System Information for %1$s', 'event_espresso'),
555
+				esc_url_raw(site_url())
556
+			) . '</h1>';
557
+		$output .= EEH_Template::layout_array_as_table($status_info);
558
+		echo esc_html($output);
559
+		die;
560
+	}
561
+
562
+
563
+	/**
564
+	 * @throws EE_Error
565
+	 */
566
+	public function _send_migration_crash_report()
567
+	{
568
+		$from      = $this->_req_data['from'];
569
+		$from_name = $this->_req_data['from_name'];
570
+		$body      = $this->_req_data['body'];
571
+		try {
572
+			$success = wp_mail(
573
+				EE_SUPPORT_EMAIL,
574
+				'Migration Crash Report',
575
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
576
+				[
577
+					"from:$from_name<$from>",
578
+				]
579
+			);
580
+		} catch (Exception $e) {
581
+			$success = false;
582
+		}
583
+		$this->_redirect_after_action(
584
+			$success,
585
+			esc_html__("Migration Crash Report", "event_espresso"),
586
+			esc_html__("sent", "event_espresso"),
587
+			['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
588
+		);
589
+	}
590
+
591
+
592
+	/**
593
+	 * @throws EE_Error
594
+	 */
595
+	public function _confirm_migration_crash_report_sent()
596
+	{
597
+		try {
598
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
599
+		} catch (EE_Error $e) {
600
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
601
+			// now, just so we can display the page correctly, make an error migration script stage object
602
+			// and also put the error on it. It only persists for the duration of this request
603
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
604
+			$most_recent_migration->add_error($e->getMessage());
605
+		}
606
+		$success                                       = $this->_req_data['success'] === '1';
607
+		$this->_template_args['success']               = $success;
608
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
609
+		$this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
610
+			['action' => 'reset_db'],
611
+			EE_MAINTENANCE_ADMIN_URL
612
+		);
613
+		$this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
614
+			['action' => 'data_reset'],
615
+			EE_MAINTENANCE_ADMIN_URL
616
+		);
617
+		$this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
618
+			['action' => 'reattempt_migration'],
619
+			EE_MAINTENANCE_ADMIN_URL
620
+		);
621
+		$this->_template_path                          =
622
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
623
+		$this->_template_args['admin_page_content']    = EEH_Template::display_template(
624
+			$this->_template_path,
625
+			$this->_template_args,
626
+			true
627
+		);
628
+		$this->display_admin_page_with_sidebar();
629
+	}
630
+
631
+
632
+	/**
633
+	 * Resets the entire EE4 database.
634
+	 * only sets up ee4 database for a fresh install-
635
+	 * doesn't actually clean out the old wp options, or cpts
636
+	 * (although it does erase old ee table data)
637
+	 *
638
+	 * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
639
+	 *                                   or just try initializing ee4 default data
640
+	 * @throws EE_Error
641
+	 * @throws ReflectionException
642
+	 */
643
+	public function _reset_db($nuke_old_ee4_data = true)
644
+	{
645
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
646
+		if ($nuke_old_ee4_data) {
647
+			EEH_Activation::delete_all_espresso_cpt_data();
648
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
649
+			EEH_Activation::remove_cron_tasks();
650
+		}
651
+		// make sure when we reset the registry's config that it
652
+		// switches to using the new singleton
653
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
654
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
655
+		EE_System::instance()->redirect_to_about_ee();
656
+	}
657
+
658
+
659
+	/**
660
+	 * Deletes ALL EE tables, Records, and Options from the database.
661
+	 *
662
+	 * @throws EE_Error
663
+	 * @throws ReflectionException
664
+	 */
665
+	public function _delete_db()
666
+	{
667
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
668
+		EEH_Activation::delete_all_espresso_cpt_data();
669
+		EEH_Activation::delete_all_espresso_tables_and_data();
670
+		EEH_Activation::remove_cron_tasks();
671
+		EEH_Activation::deactivate_event_espresso();
672
+		wp_safe_redirect(admin_url('plugins.php'));
673
+		exit;
674
+	}
675
+
676
+
677
+	/**
678
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
679
+	 *
680
+	 * @throws EE_Error
681
+	 * @throws ReflectionException
682
+	 */
683
+	public function _rerun_migration_from_ee3()
684
+	{
685
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
686
+		EEH_Activation::delete_all_espresso_cpt_data();
687
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
688
+		// set the db state to something that will require migrations
689
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
690
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
691
+		$this->_redirect_after_action(
692
+			true,
693
+			esc_html__("Database", 'event_espresso'),
694
+			esc_html__("reset", 'event_espresso')
695
+		);
696
+	}
697
+
698
+
699
+	// none of the below group are currently used for Gateway Settings
700
+	protected function _add_screen_options()
701
+	{
702
+	}
703
+
704
+
705
+	protected function _add_feature_pointers()
706
+	{
707
+	}
708
+
709
+
710
+	public function admin_init()
711
+	{
712
+	}
713
+
714
+
715
+	public function admin_notices()
716
+	{
717
+	}
718
+
719
+
720
+	public function admin_footer_scripts()
721
+	{
722
+	}
723
+
724
+
725
+	public function load_scripts_styles()
726
+	{
727
+		wp_enqueue_script('ee_admin_js');
728
+		wp_enqueue_script(
729
+			'ee-maintenance',
730
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
731
+			['jquery'],
732
+			EVENT_ESPRESSO_VERSION,
733
+			true
734
+		);
735
+		wp_register_style(
736
+			'espresso_maintenance',
737
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
738
+			[],
739
+			EVENT_ESPRESSO_VERSION
740
+		);
741
+		wp_enqueue_style('espresso_maintenance');
742
+		// localize script stuff
743
+		wp_localize_script(
744
+			'ee-maintenance',
745
+			'ee_maintenance',
746
+			[
747
+				'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
748
+				'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
749
+				'fatal_error'                      => wp_strip_all_tags(
750
+					__(
751
+						"A Fatal Error Has Occurred",
752
+						"event_espresso"
753
+					)
754
+				),
755
+				'click_next_when_ready'            => wp_strip_all_tags(
756
+					__(
757
+						"The current Database Update has ended. Click 'next' when ready to proceed",
758
+						"event_espresso"
759
+					)
760
+				),
761
+				'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
762
+				'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
763
+				'status_completed'                 => EE_Data_Migration_Manager::status_completed,
764
+				'confirm'                          => wp_strip_all_tags(
765
+					__(
766
+						'Are you sure you want to do this? It CANNOT be undone!',
767
+						'event_espresso'
768
+					)
769
+				),
770
+				'confirm_skip_migration'           => wp_strip_all_tags(
771
+					__(
772
+						'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
773
+						'event_espresso'
774
+					)
775
+				),
776
+			]
777
+		);
778
+	}
779
+
780
+
781
+	public function load_scripts_styles_default()
782
+	{
783
+	}
784
+
785
+
786
+	/**
787
+	 * Enqueue scripts and styles for the datetime tools page.
788
+	 */
789
+	public function load_scripts_styles_datetime_tools()
790
+	{
791
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
792
+	}
793
+
794
+
795
+	/**
796
+	 * @throws EE_Error
797
+	 */
798
+	protected function _datetime_tools()
799
+	{
800
+		$form_action                                = EE_Admin_Page::add_query_args_and_nonce(
801
+			[
802
+				'action'        => 'run_datetime_offset_fix',
803
+				'return_action' => $this->_req_action,
804
+			],
805
+			EE_MAINTENANCE_ADMIN_URL
806
+		);
807
+		$form                                       = $this->_get_datetime_offset_fix_form();
808
+		$this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
809
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
810
+													  . $form->get_html_and_js()
811
+													  . $form->form_close();
812
+		$this->display_admin_page_with_sidebar();
813
+	}
814
+
815
+
816
+	/**
817
+	 * @throws EE_Error
818
+	 */
819
+	protected function _get_datetime_offset_fix_form()
820
+	{
821
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
822
+			$this->datetime_fix_offset_form = new EE_Form_Section_Proper(
823
+				[
824
+					'name'            => 'datetime_offset_fix_option',
825
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
826
+					'subsections'     => [
827
+						'title'                  => new EE_Form_Section_HTML(
828
+							EEH_HTML::h2(
829
+								esc_html__('Datetime Offset Tool', 'event_espresso')
830
+							)
831
+						),
832
+						'explanation'            => new EE_Form_Section_HTML(
833
+							EEH_HTML::p(
834
+								esc_html__(
835
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
836
+									'event_espresso'
837
+								)
838
+							)
839
+							. EEH_HTML::p(
840
+								esc_html__(
841
+									'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
842
+									'event_espresso'
843
+								)
844
+							)
845
+						),
846
+						'offset_input'           => new EE_Float_Input(
847
+							[
848
+								'html_name'       => 'offset_for_datetimes',
849
+								'html_label_text' => esc_html__(
850
+									'Offset to apply (in hours):',
851
+									'event_espresso'
852
+								),
853
+								'min_value'       => '-12',
854
+								'max_value'       => '14',
855
+								'step_value'      => '.25',
856
+								'default'         => DatetimeOffsetFix::getOffset(),
857
+							]
858
+						),
859
+						'date_range_explanation' => new EE_Form_Section_HTML(
860
+							EEH_HTML::p(
861
+								esc_html__(
862
+									'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
863
+									'event_espresso'
864
+								)
865
+							)
866
+							. EEH_HTML::p(
867
+								EEH_HTML::strong(
868
+									sprintf(
869
+										esc_html__(
870
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
871
+											'event_espresso'
872
+										),
873
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
874
+										'</a>'
875
+									)
876
+								)
877
+							)
878
+						),
879
+						'date_range_start_date'  => new EE_Datepicker_Input(
880
+							[
881
+								'html_name'       => 'offset_date_start_range',
882
+								'html_label_text' => esc_html__(
883
+									'Start Date for dates the offset applied to:',
884
+									'event_espresso'
885
+								),
886
+							]
887
+						),
888
+						'date_range_end_date'    => new EE_Datepicker_Input(
889
+							[
890
+								'html_name'       => 'offset_date_end_range',
891
+								'html_label_text' => esc_html__(
892
+									'End Date for dates the offset is applied to:',
893
+									'event_espresso'
894
+								),
895
+							]
896
+						),
897
+						'submit'                 => new EE_Submit_Input(
898
+							[
899
+								'html_label_text' => '',
900
+								'default'         => esc_html__('Apply Offset', 'event_espresso'),
901
+							]
902
+						),
903
+					],
904
+				]
905
+			);
906
+		}
907
+		return $this->datetime_fix_offset_form;
908
+	}
909
+
910
+
911
+	/**
912
+	 * Callback for the run_datetime_offset_fix route.
913
+	 *
914
+	 * @throws EE_Error
915
+	 */
916
+	protected function _apply_datetime_offset()
917
+	{
918
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
919
+			$form = $this->_get_datetime_offset_fix_form();
920
+			$form->receive_form_submission($this->_req_data);
921
+			if ($form->is_valid()) {
922
+				// save offset data so batch processor can get it.
923
+				DatetimeOffsetFix::updateOffset((float) $form->get_input_value('offset_input'));
924
+				$utc_timezone          = new DateTimeZone('UTC');
925
+				$date_range_start_date = DateTime::createFromFormat(
926
+					'm/d/Y H:i:s',
927
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
928
+					$utc_timezone
929
+				);
930
+				$date_range_end_date   = DateTime::createFromFormat(
931
+					'm/d/Y H:i:s',
932
+					$form->get_input_value('date_range_end_date') . ' 23:59:59',
933
+					$utc_timezone
934
+				);
935
+				if ($date_range_start_date instanceof DateTime) {
936
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
937
+				}
938
+				if ($date_range_end_date instanceof DateTime) {
939
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
940
+				}
941
+				// redirect to batch tool
942
+				wp_redirect(
943
+					EE_Admin_Page::add_query_args_and_nonce(
944
+						[
945
+							'page'        => EED_Batch::PAGE_SLUG,
946
+							'batch'       => EED_Batch::batch_job,
947
+							'label'       => esc_html__('Applying Offset', 'event_espresso'),
948
+							'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\DatetimeOffsetFix'),
949
+							'return_url'  => urlencode(
950
+								add_query_arg(
951
+									[
952
+										'action' => 'datetime_tools',
953
+									],
954
+									EEH_URL::current_url_without_query_paramaters(
955
+										[
956
+											'return_action',
957
+											'run_datetime_offset_fix_nonce',
958
+											'return',
959
+											'datetime_tools_nonce',
960
+										]
961
+									)
962
+								)
963
+							),
964
+						],
965
+						admin_url()
966
+					)
967
+				);
968
+				exit;
969
+			}
970
+		}
971
+	}
972 972
 }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 1 patch
Indentation   +2939 added lines, -2939 removed lines patch added patch discarded remove patch
@@ -18,2946 +18,2946 @@
 block discarded – undo
18 18
  */
19 19
 class Events_Admin_Page extends EE_Admin_Page_CPT
20 20
 {
21
-    /**
22
-     * primary key for the event model
23
-     */
24
-    private int $EVT_ID = 0;
25
-
26
-    /**
27
-     * This will hold the event object for event_details screen.
28
-     *
29
-     * @var EE_Event|null $_event
30
-     */
31
-    protected ?EE_Event $_event = null;
32
-
33
-    /**
34
-     * This will hold the category object for category_details screen.
35
-     */
36
-    protected ?stdClass $_category = null;
37
-
38
-    protected ?EEM_Event $_event_model = null;
39
-
40
-    /**
41
-     * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
42
-     */
43
-    protected $_cpt_model_obj;
44
-
45
-    protected ?NodeGroupDao $model_obj_node_group_persister = null;
46
-
47
-    protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
48
-
49
-
50
-    /**
51
-     * Initialize page props for this admin page group.
52
-     */
53
-    protected function _init_page_props()
54
-    {
55
-        // is there a evt_id in the request?
56
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
57
-        $this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
58
-        $this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
59
-
60
-        $this->page_slug        = EVENTS_PG_SLUG;
61
-        $this->page_label       = EVENTS_LABEL;
62
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
63
-        $this->_admin_base_path = EVENTS_ADMIN;
64
-        $this->_cpt_model_names = [
65
-            'create_new' => 'EEM_Event',
66
-            'edit'       => 'EEM_Event',
67
-        ];
68
-        $this->_cpt_edit_routes = [
69
-            'espresso_events' => 'edit',
70
-        ];
71
-        add_action(
72
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
-            [$this, 'verify_event_edit'],
74
-            10,
75
-            2
76
-        );
77
-    }
78
-
79
-
80
-    /**
81
-     * Sets the ajax hooks used for this admin page group.
82
-     */
83
-    protected function _ajax_hooks()
84
-    {
85
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
-    }
87
-
88
-
89
-    /**
90
-     * Sets the page properties for this admin page group.
91
-     */
92
-    protected function _define_page_props()
93
-    {
94
-        $this->_admin_page_title = EVENTS_LABEL;
95
-        $this->_labels           = [
96
-            'buttons'      => [
97
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
98
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
-            ],
104
-            'editor_title' => [
105
-                'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
106
-            ],
107
-            'publishbox'   => [
108
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
110
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
-            ],
114
-        ];
115
-    }
116
-
117
-
118
-    /**
119
-     * Sets the page routes property for this admin page group.
120
-     */
121
-    protected function _set_page_routes()
122
-    {
123
-        $this->_page_routes = [
124
-            'default'                       => [
125
-                'func'       => [$this, '_events_overview_list_table'],
126
-                'capability' => 'ee_read_events',
127
-            ],
128
-            'create_new'                    => [
129
-                'func'       => [$this, '_create_new_cpt_item'],
130
-                'capability' => 'ee_edit_events',
131
-            ],
132
-            'edit'                          => [
133
-                'func'       => [$this, '_edit_cpt_item'],
134
-                'capability' => 'ee_edit_event',
135
-                'obj_id'     => $this->EVT_ID,
136
-            ],
137
-            'copy_event'                    => [
138
-                'func'       => [$this, '_copy_events'],
139
-                'capability' => 'ee_edit_event',
140
-                'obj_id'     => $this->EVT_ID,
141
-                'noheader'   => true,
142
-            ],
143
-            'trash_event'                   => [
144
-                'func'       => [$this, '_trash_or_restore_event'],
145
-                'args'       => ['event_status' => 'trash'],
146
-                'capability' => 'ee_delete_event',
147
-                'obj_id'     => $this->EVT_ID,
148
-                'noheader'   => true,
149
-            ],
150
-            'trash_events'                  => [
151
-                'func'       => [$this, '_trash_or_restore_events'],
152
-                'args'       => ['event_status' => 'trash'],
153
-                'capability' => 'ee_delete_events',
154
-                'noheader'   => true,
155
-            ],
156
-            'restore_event'                 => [
157
-                'func'       => [$this, '_trash_or_restore_event'],
158
-                'args'       => ['event_status' => 'draft'],
159
-                'capability' => 'ee_delete_event',
160
-                'obj_id'     => $this->EVT_ID,
161
-                'noheader'   => true,
162
-            ],
163
-            'restore_events'                => [
164
-                'func'       => [$this, '_trash_or_restore_events'],
165
-                'args'       => ['event_status' => 'draft'],
166
-                'capability' => 'ee_delete_events',
167
-                'noheader'   => true,
168
-            ],
169
-            'delete_event'                  => [
170
-                'func'       => [$this, '_delete_event'],
171
-                'capability' => 'ee_delete_event',
172
-                'obj_id'     => $this->EVT_ID,
173
-                'noheader'   => true,
174
-            ],
175
-            'delete_events'                 => [
176
-                'func'       => [$this, '_delete_events'],
177
-                'capability' => 'ee_delete_events',
178
-                'noheader'   => true,
179
-            ],
180
-            'view_report'                   => [
181
-                'func'       => [$this, '_view_report'],
182
-                'capability' => 'ee_edit_events',
183
-            ],
184
-            'default_event_settings'        => [
185
-                'func'       => [$this, '_default_event_settings'],
186
-                'capability' => 'manage_options',
187
-            ],
188
-            'update_default_event_settings' => [
189
-                'func'       => [$this, '_update_default_event_settings'],
190
-                'capability' => 'manage_options',
191
-                'noheader'   => true,
192
-            ],
193
-            'template_settings'             => [
194
-                'func'       => [$this, '_template_settings'],
195
-                'capability' => 'manage_options',
196
-            ],
197
-            // event category tab related
198
-            'add_category'                  => [
199
-                'func'       => [$this, '_category_details'],
200
-                'capability' => 'ee_edit_event_category',
201
-                'args'       => ['view' => 'add'],
202
-            ],
203
-            'edit_category'                 => [
204
-                'func'       => [$this, '_category_details'],
205
-                'capability' => 'ee_edit_event_category',
206
-                'args'       => ['view' => 'edit'],
207
-            ],
208
-            'delete_categories'             => [
209
-                'func'       => [$this, '_delete_categories'],
210
-                'capability' => 'ee_delete_event_category',
211
-                'noheader'   => true,
212
-            ],
213
-            'delete_category'               => [
214
-                'func'       => [$this, '_delete_categories'],
215
-                'capability' => 'ee_delete_event_category',
216
-                'noheader'   => true,
217
-            ],
218
-            'insert_category'               => [
219
-                'func'       => [$this, '_insert_or_update_category'],
220
-                'args'       => ['new_category' => true],
221
-                'capability' => 'ee_edit_event_category',
222
-                'noheader'   => true,
223
-            ],
224
-            'update_category'               => [
225
-                'func'       => [$this, '_insert_or_update_category'],
226
-                'args'       => ['new_category' => false],
227
-                'capability' => 'ee_edit_event_category',
228
-                'noheader'   => true,
229
-            ],
230
-            'category_list'                 => [
231
-                'func'       => [$this, '_category_list_table'],
232
-                'capability' => 'ee_manage_event_categories',
233
-            ],
234
-            'preview_deletion'              => [
235
-                'func'       => [$this, 'previewDeletion'],
236
-                'capability' => 'ee_delete_events',
237
-            ],
238
-            'confirm_deletion'              => [
239
-                'func'       => [$this, 'confirmDeletion'],
240
-                'capability' => 'ee_delete_events',
241
-                'noheader'   => true,
242
-            ],
243
-        ];
244
-    }
245
-
246
-
247
-    /**
248
-     * Set the _page_config property for this admin page group.
249
-     */
250
-    protected function _set_page_config()
251
-    {
252
-        $post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
253
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
254
-        $this->_page_config = [
255
-            'default'                => [
256
-                'nav'           => [
257
-                    'label' => esc_html__('Overview', 'event_espresso'),
258
-                    'icon'  => 'dashicons-list-view',
259
-                    'order' => 10,
260
-                ],
261
-                'list_table'    => 'Events_Admin_List_Table',
262
-                'help_tabs'     => [
263
-                    'events_overview_help_tab'                       => [
264
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
265
-                        'filename' => 'events_overview',
266
-                    ],
267
-                    'events_overview_table_column_headings_help_tab' => [
268
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
269
-                        'filename' => 'events_overview_table_column_headings',
270
-                    ],
271
-                    'events_overview_filters_help_tab'               => [
272
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
273
-                        'filename' => 'events_overview_filters',
274
-                    ],
275
-                    'events_overview_view_help_tab'                  => [
276
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
277
-                        'filename' => 'events_overview_views',
278
-                    ],
279
-                    'events_overview_other_help_tab'                 => [
280
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
281
-                        'filename' => 'events_overview_other',
282
-                    ],
283
-                ],
284
-                'require_nonce' => false,
285
-            ],
286
-            'create_new'             => [
287
-                'nav'           => [
288
-                    'label'      => esc_html__('Add New Event', 'event_espresso'),
289
-                    'icon'       => 'dashicons-plus-alt',
290
-                    'order'      => 15,
291
-                    'persistent' => false,
292
-                ],
293
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
294
-                'help_tabs'     => [
295
-                    'event_editor_help_tab'                            => [
296
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
297
-                        'filename' => 'event_editor',
298
-                    ],
299
-                    'event_editor_title_richtexteditor_help_tab'       => [
300
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
301
-                        'filename' => 'event_editor_title_richtexteditor',
302
-                    ],
303
-                    'event_editor_venue_details_help_tab'              => [
304
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
305
-                        'filename' => 'event_editor_venue_details',
306
-                    ],
307
-                    'event_editor_event_datetimes_help_tab'            => [
308
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
309
-                        'filename' => 'event_editor_event_datetimes',
310
-                    ],
311
-                    'event_editor_event_tickets_help_tab'              => [
312
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
313
-                        'filename' => 'event_editor_event_tickets',
314
-                    ],
315
-                    'event_editor_event_registration_options_help_tab' => [
316
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
317
-                        'filename' => 'event_editor_event_registration_options',
318
-                    ],
319
-                    'event_editor_tags_categories_help_tab'            => [
320
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
321
-                        'filename' => 'event_editor_tags_categories',
322
-                    ],
323
-                    'event_editor_questions_registrants_help_tab'      => [
324
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
325
-                        'filename' => 'event_editor_questions_registrants',
326
-                    ],
327
-                    'event_editor_save_new_event_help_tab'             => [
328
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
329
-                        'filename' => 'event_editor_save_new_event',
330
-                    ],
331
-                    'event_editor_other_help_tab'                      => [
332
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
333
-                        'filename' => 'event_editor_other',
334
-                    ],
335
-                ],
336
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
337
-                'require_nonce' => false,
338
-            ],
339
-            'edit'                   => [
340
-                'nav'           => [
341
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
342
-                    'icon'       => 'dashicons-edit',
343
-                    'order'      => 15,
344
-                    'persistent' => false,
345
-                    'url'        => $post_id
346
-                        ? EE_Admin_Page::add_query_args_and_nonce(
347
-                            ['post' => $post_id, 'action' => 'edit'],
348
-                            $this->_current_page_view_url
349
-                        )
350
-                        : $this->_admin_base_url,
351
-                ],
352
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
353
-                'help_tabs'     => [
354
-                    'event_editor_help_tab'                            => [
355
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
356
-                        'filename' => 'event_editor',
357
-                    ],
358
-                    'event_editor_title_richtexteditor_help_tab'       => [
359
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
360
-                        'filename' => 'event_editor_title_richtexteditor',
361
-                    ],
362
-                    'event_editor_venue_details_help_tab'              => [
363
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
364
-                        'filename' => 'event_editor_venue_details',
365
-                    ],
366
-                    'event_editor_event_datetimes_help_tab'            => [
367
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
368
-                        'filename' => 'event_editor_event_datetimes',
369
-                    ],
370
-                    'event_editor_event_tickets_help_tab'              => [
371
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
372
-                        'filename' => 'event_editor_event_tickets',
373
-                    ],
374
-                    'event_editor_event_registration_options_help_tab' => [
375
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
376
-                        'filename' => 'event_editor_event_registration_options',
377
-                    ],
378
-                    'event_editor_tags_categories_help_tab'            => [
379
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
380
-                        'filename' => 'event_editor_tags_categories',
381
-                    ],
382
-                    'event_editor_questions_registrants_help_tab'      => [
383
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
384
-                        'filename' => 'event_editor_questions_registrants',
385
-                    ],
386
-                    'event_editor_save_new_event_help_tab'             => [
387
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
388
-                        'filename' => 'event_editor_save_new_event',
389
-                    ],
390
-                    'event_editor_other_help_tab'                      => [
391
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
392
-                        'filename' => 'event_editor_other',
393
-                    ],
394
-                ],
395
-                'require_nonce' => false,
396
-            ],
397
-            'default_event_settings' => [
398
-                'nav'           => [
399
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
400
-                    'icon'  => 'dashicons-admin-generic',
401
-                    'order' => 40,
402
-                ],
403
-                'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
404
-                'labels'        => [
405
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
406
-                ],
407
-                'help_tabs'     => [
408
-                    'default_settings_help_tab'        => [
409
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
410
-                        'filename' => 'events_default_settings',
411
-                    ],
412
-                    'default_settings_status_help_tab' => [
413
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
414
-                        'filename' => 'events_default_settings_status',
415
-                    ],
416
-                    'default_maximum_tickets_help_tab' => [
417
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
418
-                        'filename' => 'events_default_settings_max_tickets',
419
-                    ],
420
-                ],
421
-                'require_nonce' => false,
422
-            ],
423
-            // template settings
424
-            'template_settings'      => [
425
-                'nav'           => [
426
-                    'label' => esc_html__('Templates', 'event_espresso'),
427
-                    'icon'  => 'dashicons-layout',
428
-                    'order' => 30,
429
-                ],
430
-                'metaboxes'     => $this->_default_espresso_metaboxes,
431
-                'help_tabs'     => [
432
-                    'general_settings_templates_help_tab' => [
433
-                        'title'    => esc_html__('Templates', 'event_espresso'),
434
-                        'filename' => 'general_settings_templates',
435
-                    ],
436
-                ],
437
-                'require_nonce' => false,
438
-            ],
439
-            // event category stuff
440
-            'add_category'           => [
441
-                'nav'           => [
442
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
443
-                    'icon'       => 'dashicons-plus-alt',
444
-                    'order'      => 25,
445
-                    'persistent' => false,
446
-                ],
447
-                'help_tabs'     => [
448
-                    'add_category_help_tab' => [
449
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
450
-                        'filename' => 'events_add_category',
451
-                    ],
452
-                ],
453
-                'metaboxes'     => ['_publish_post_box'],
454
-                'require_nonce' => false,
455
-            ],
456
-            'edit_category'          => [
457
-                'nav'           => [
458
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
459
-                    'icon'       => 'dashicons-edit',
460
-                    'order'      => 25,
461
-                    'persistent' => false,
462
-                    'url'        => $EVT_CAT_ID
463
-                        ? add_query_arg(
464
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
465
-                            $this->_current_page_view_url
466
-                        )
467
-                        : $this->_admin_base_url,
468
-                ],
469
-                'help_tabs'     => [
470
-                    'edit_category_help_tab' => [
471
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
472
-                        'filename' => 'events_edit_category',
473
-                    ],
474
-                ],
475
-                'metaboxes'     => ['_publish_post_box'],
476
-                'require_nonce' => false,
477
-            ],
478
-            'category_list'          => [
479
-                'nav'           => [
480
-                    'label' => esc_html__('Categories', 'event_espresso'),
481
-                    'icon'  => 'dashicons-networking',
482
-                    'order' => 20,
483
-                ],
484
-                'list_table'    => 'Event_Categories_Admin_List_Table',
485
-                'help_tabs'     => [
486
-                    'events_categories_help_tab'                       => [
487
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
488
-                        'filename' => 'events_categories',
489
-                    ],
490
-                    'events_categories_table_column_headings_help_tab' => [
491
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
492
-                        'filename' => 'events_categories_table_column_headings',
493
-                    ],
494
-                    'events_categories_view_help_tab'                  => [
495
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
496
-                        'filename' => 'events_categories_views',
497
-                    ],
498
-                    'events_categories_other_help_tab'                 => [
499
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
500
-                        'filename' => 'events_categories_other',
501
-                    ],
502
-                ],
503
-                'metaboxes'     => $this->_default_espresso_metaboxes,
504
-                'require_nonce' => false,
505
-            ],
506
-            'preview_deletion'       => [
507
-                'nav'           => [
508
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
509
-                    'icon'       => 'dashicons-remove',
510
-                    'order'      => 15,
511
-                    'persistent' => false,
512
-                    'url'        => '',
513
-                ],
514
-                'require_nonce' => false,
515
-            ],
516
-        ];
517
-    }
518
-
519
-
520
-    /**
521
-     * Used to register any global screen options if necessary for every route in this admin page group.
522
-     */
523
-    protected function _add_screen_options()
524
-    {
525
-    }
526
-
527
-
528
-    /**
529
-     * Implementing the screen options for the 'default' route.
530
-     *
531
-     * @throws InvalidArgumentException
532
-     * @throws InvalidDataTypeException
533
-     * @throws InvalidInterfaceException
534
-     */
535
-    protected function _add_screen_options_default()
536
-    {
537
-        $this->_per_page_screen_option();
538
-    }
539
-
540
-
541
-    /**
542
-     * Implementing screen options for the category list route.
543
-     *
544
-     * @throws InvalidArgumentException
545
-     * @throws InvalidDataTypeException
546
-     * @throws InvalidInterfaceException
547
-     */
548
-    protected function _add_screen_options_category_list()
549
-    {
550
-        $page_title              = $this->_admin_page_title;
551
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
552
-        $this->_per_page_screen_option();
553
-        $this->_admin_page_title = $page_title;
554
-    }
555
-
556
-
557
-    /**
558
-     * Used to register any global feature pointers for the admin page group.
559
-     */
560
-    protected function _add_feature_pointers()
561
-    {
562
-    }
563
-
564
-
565
-    /**
566
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
567
-     */
568
-    public function load_scripts_styles()
569
-    {
570
-        wp_register_style(
571
-            'events-admin-css',
572
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
573
-            [],
574
-            EVENT_ESPRESSO_VERSION
575
-        );
576
-        wp_register_style(
577
-            'ee-cat-admin',
578
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
579
-            [],
580
-            EVENT_ESPRESSO_VERSION
581
-        );
582
-        wp_enqueue_style('events-admin-css');
583
-        wp_enqueue_style('ee-cat-admin');
584
-        // scripts
585
-        wp_register_script(
586
-            'event_editor_js',
587
-            EVENTS_ASSETS_URL . 'event_editor.js',
588
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
589
-            EVENT_ESPRESSO_VERSION,
590
-            true
591
-        );
592
-    }
593
-
594
-
595
-    /**
596
-     * Enqueuing scripts and styles specific to this view
597
-     */
598
-    public function load_scripts_styles_create_new()
599
-    {
600
-        $this->load_scripts_styles_edit();
601
-    }
602
-
603
-
604
-    /**
605
-     * Enqueuing scripts and styles specific to this view
606
-     */
607
-    public function load_scripts_styles_edit()
608
-    {
609
-        // styles
610
-        wp_enqueue_style('espresso-ui-theme');
611
-        wp_register_style(
612
-            'event-editor-css',
613
-            EVENTS_ASSETS_URL . 'event-editor.css',
614
-            ['ee-admin-css'],
615
-            EVENT_ESPRESSO_VERSION
616
-        );
617
-        wp_enqueue_style('event-editor-css');
618
-        // scripts
619
-        if (! $this->admin_config->useAdvancedEditor()) {
620
-            wp_register_script(
621
-                'event-datetime-metabox',
622
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
623
-                ['event_editor_js', 'ee-datepicker'],
624
-                EVENT_ESPRESSO_VERSION
625
-            );
626
-            wp_enqueue_script('event-datetime-metabox');
627
-        }
628
-    }
629
-
630
-
631
-    /**
632
-     * Populating the _views property for the category list table view.
633
-     */
634
-    protected function _set_list_table_views_category_list()
635
-    {
636
-        $this->_views = [
637
-            'all' => [
638
-                'slug'        => 'all',
639
-                'label'       => esc_html__('All', 'event_espresso'),
640
-                'count'       => 0,
641
-                'bulk_action' => [
642
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
643
-                ],
644
-            ],
645
-        ];
646
-    }
647
-
648
-
649
-    /**
650
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
651
-     */
652
-    public function admin_init()
653
-    {
654
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
655
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
656
-            'event_espresso'
657
-        );
658
-    }
659
-
660
-
661
-    /**
662
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
663
-     * group.
664
-     */
665
-    public function admin_notices()
666
-    {
667
-    }
668
-
669
-
670
-    /**
671
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
672
-     * this admin page group.
673
-     */
674
-    public function admin_footer_scripts()
675
-    {
676
-    }
677
-
678
-
679
-    /**
680
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
681
-     * warning (via EE_Error::add_error());
682
-     *
683
-     * @param EE_Event|null $event Event object
684
-     * @param string        $req_type
685
-     * @return void
686
-     * @throws EE_Error
687
-     * @throws ReflectionException
688
-     */
689
-    public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
690
-    {
691
-        // don't need to do this when processing
692
-        if (! empty($req_type)) {
693
-            return;
694
-        }
695
-        // no event?
696
-        if (! $event instanceof EE_Event) {
697
-            $event = $this->_cpt_model_obj;
698
-        }
699
-        // STILL no event?
700
-        if (! $event instanceof EE_Event) {
701
-            return;
702
-        }
703
-        // don't need to keep calling this
704
-        remove_action(
705
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
706
-            [$this, 'verify_event_edit']
707
-        );
708
-        $orig_status = $event->status();
709
-        // first check if event is active.
710
-        if (
711
-            $orig_status === EEM_Event::cancelled
712
-            || $orig_status === EEM_Event::postponed
713
-            || $event->is_expired()
714
-            || $event->is_inactive()
715
-        ) {
716
-            return;
717
-        }
718
-        // made it here so it IS active... next check that any of the tickets are sold.
719
-        if ($event->is_sold_out(true)) {
720
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
721
-                EE_Error::add_attention(
722
-                    sprintf(
723
-                        esc_html__(
724
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
725
-                            'event_espresso'
726
-                        ),
727
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
728
-                    )
729
-                );
730
-            }
731
-            return;
732
-        }
733
-        if ($orig_status === EEM_Event::sold_out) {
734
-            EE_Error::add_attention(
735
-                sprintf(
736
-                    esc_html__(
737
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
738
-                        'event_espresso'
739
-                    ),
740
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
741
-                )
742
-            );
743
-        }
744
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
745
-        if (! $event->tickets_on_sale()) {
746
-            return;
747
-        }
748
-        // made it here so show warning
749
-        $this->_edit_event_warning();
750
-    }
751
-
752
-
753
-    /**
754
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
755
-     * When needed, hook this into a EE_Error::add_error() notice.
756
-     *
757
-     * @access protected
758
-     * @return void
759
-     */
760
-    protected function _edit_event_warning()
761
-    {
762
-        // we don't want to add warnings during these requests
763
-        if ($this->request->getRequestParam('action') === 'editpost') {
764
-            return;
765
-        }
766
-        EE_Error::add_attention(
767
-            sprintf(
768
-                esc_html__(
769
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
770
-                    'event_espresso'
771
-                ),
772
-                '<a class="espresso-help-tab-lnk ee-help-tab-link">',
773
-                '</a>'
774
-            )
775
-        );
776
-    }
777
-
778
-
779
-    /**
780
-     * When a user is creating a new event, notify them if they haven't set their timezone.
781
-     * Otherwise, do the normal logic
782
-     *
783
-     * @return void
784
-     * @throws EE_Error
785
-     * @throws InvalidArgumentException
786
-     * @throws InvalidDataTypeException
787
-     * @throws InvalidInterfaceException
788
-     * @throws ReflectionException
789
-     */
790
-    protected function _create_new_cpt_item()
791
-    {
792
-        $has_timezone_string = get_option('timezone_string');
793
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
794
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
795
-            EE_Error::add_attention(
796
-                sprintf(
797
-                    esc_html__(
798
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
799
-                        'event_espresso'
800
-                    ),
801
-                    '<br>',
802
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
803
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
804
-                    . '</select>',
805
-                    '<button class="button button--secondary timezone-submit">',
806
-                    '</button><span class="spinner"></span>'
807
-                ),
808
-                __FILE__,
809
-                __FUNCTION__,
810
-                __LINE__
811
-            );
812
-        }
813
-        parent::_create_new_cpt_item();
814
-    }
815
-
816
-
817
-    /**
818
-     * Sets the _views property for the default route in this admin page group.
819
-     */
820
-    protected function _set_list_table_views_default()
821
-    {
822
-        $this->_views = [
823
-            'all'   => [
824
-                'slug'        => 'all',
825
-                'label'       => esc_html__('View All Events', 'event_espresso'),
826
-                'count'       => 0,
827
-                'bulk_action' => [
828
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
829
-                ],
830
-            ],
831
-            'draft' => [
832
-                'slug'        => 'draft',
833
-                'label'       => esc_html__('Draft', 'event_espresso'),
834
-                'count'       => 0,
835
-                'bulk_action' => [
836
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
837
-                ],
838
-            ],
839
-        ];
840
-        if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
841
-            $this->_views['trash'] = [
842
-                'slug'        => 'trash',
843
-                'label'       => esc_html__('Trash', 'event_espresso'),
844
-                'count'       => 0,
845
-                'bulk_action' => [
846
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
847
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
848
-                ],
849
-            ];
850
-        }
851
-    }
852
-
853
-
854
-    /**
855
-     * Provides the legend item array for the default list table view.
856
-     *
857
-     * @return array
858
-     * @throws EE_Error
859
-     * @throws EE_Error
860
-     */
861
-    protected function _event_legend_items(): array
862
-    {
863
-        $items    = [
864
-            'view_details'   => [
865
-                'class' => 'dashicons dashicons-visibility',
866
-                'desc'  => esc_html__('View Event', 'event_espresso'),
867
-            ],
868
-            'edit_event'     => [
869
-                'class' => 'dashicons dashicons-calendar-alt',
870
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
871
-            ],
872
-            'view_attendees' => [
873
-                'class' => 'dashicons dashicons-groups',
874
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
875
-            ],
876
-        ];
877
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
878
-        $statuses = [
879
-            'sold_out_status'  => [
880
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
881
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
882
-            ],
883
-            'active_status'    => [
884
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
885
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
886
-            ],
887
-            'upcoming_status'  => [
888
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
889
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
890
-            ],
891
-            'postponed_status' => [
892
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
893
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
894
-            ],
895
-            'cancelled_status' => [
896
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
897
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
898
-            ],
899
-            'expired_status'   => [
900
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
901
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
902
-            ],
903
-            'inactive_status'  => [
904
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
905
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
906
-            ],
907
-        ];
908
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
909
-        return array_merge($items, $statuses);
910
-    }
911
-
912
-
913
-    /**
914
-     * @return EEM_Event
915
-     * @throws EE_Error
916
-     * @throws InvalidArgumentException
917
-     * @throws InvalidDataTypeException
918
-     * @throws InvalidInterfaceException
919
-     * @throws ReflectionException
920
-     */
921
-    private function _event_model(): EEM_Event
922
-    {
923
-        if (! $this->_event_model instanceof EEM_Event) {
924
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
925
-        }
926
-        return $this->_event_model;
927
-    }
928
-
929
-
930
-    /**
931
-     * Adds extra buttons to the WP CPT permalink field row.
932
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
933
-     *
934
-     * @param string      $return    the current html
935
-     * @param int         $id        the post id for the page
936
-     * @param string|null $new_title What the title is
937
-     * @param string|null $new_slug  what the slug is
938
-     * @return string            The new html string for the permalink area
939
-     * @deprecated 5.0.0.p
940
-     * @see        TicketSelectorShortcodeButton::addButton
941
-     */
942
-    public function extra_permalink_field_buttons(
943
-        string $return,
944
-        int $id,
945
-        ?string $new_title,
946
-        ?string $new_slug
947
-    ): string {
948
-        return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
949
-    }
950
-
951
-
952
-    /**
953
-     * _events_overview_list_table
954
-     * This contains the logic for showing the events_overview list
955
-     *
956
-     * @access protected
957
-     * @return void
958
-     * @throws DomainException
959
-     * @throws EE_Error
960
-     * @throws InvalidArgumentException
961
-     * @throws InvalidDataTypeException
962
-     * @throws InvalidInterfaceException
963
-     */
964
-    protected function _events_overview_list_table()
965
-    {
966
-        $after_list_table = [];
967
-        $links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
968
-        $links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
969
-        $links_html       .= EEH_HTML::div(
970
-            EEH_Template::get_button_or_link(
971
-                get_post_type_archive_link('espresso_events'),
972
-                esc_html__('View Event Archive Page', 'event_espresso'),
973
-                'button button--small button--secondary'
974
-            ),
975
-            '',
976
-            'ee-admin-button-row ee-admin-button-row--align-start'
977
-        );
978
-        $links_html       .= EEH_HTML::divx();
979
-
980
-        $after_list_table['view_event_list_button'] = $links_html;
981
-
982
-        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
983
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
984
-                'create_new',
985
-                'add',
986
-                [],
987
-                'add-new-h2'
988
-            );
989
-
990
-        $this->_template_args['after_list_table'] = array_merge(
991
-            (array) $this->_template_args['after_list_table'],
992
-            $after_list_table
993
-        );
994
-        $this->display_admin_list_table_page_with_no_sidebar();
995
-    }
996
-
997
-
998
-    /**
999
-     * this allows for extra misc actions in the default WP publish box
1000
-     *
1001
-     * @return void
1002
-     * @throws DomainException
1003
-     * @throws EE_Error
1004
-     * @throws InvalidArgumentException
1005
-     * @throws InvalidDataTypeException
1006
-     * @throws InvalidInterfaceException
1007
-     * @throws ReflectionException
1008
-     */
1009
-    public function extra_misc_actions_publish_box()
1010
-    {
1011
-        $this->_generate_publish_box_extra_content();
1012
-    }
1013
-
1014
-
1015
-    /**
1016
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1017
-     * saved.
1018
-     * Typically you would use this to save any additional data.
1019
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1020
-     * ALSO very important.  When a post transitions from scheduled to published,
1021
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1022
-     * other meta saves. So MAKE sure that you handle this accordingly.
1023
-     *
1024
-     * @access protected
1025
-     * @abstract
1026
-     * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1027
-     * @param WP_Post $post    The post object of the cpt that was saved.
1028
-     * @return void
1029
-     * @throws EE_Error
1030
-     * @throws InvalidArgumentException
1031
-     * @throws InvalidDataTypeException
1032
-     * @throws InvalidInterfaceException
1033
-     * @throws ReflectionException
1034
-     */
1035
-    protected function _insert_update_cpt_item($post_id, $post)
1036
-    {
1037
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1038
-            // get out we're not processing an event save.
1039
-            return;
1040
-        }
1041
-        $event_values = [
1042
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1043
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1044
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1045
-        ];
1046
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1047
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1049
-                'display_ticket_selector',
1050
-                false,
1051
-                'bool'
1052
-            );
1053
-            $event_values['EVT_additional_limit']            = min(
1054
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1055
-                $this->request->getRequestParam(
1056
-                    'additional_limit',
1057
-                    EEM_Event::get_default_additional_limit(),
1058
-                    'int'
1059
-                )
1060
-            );
1061
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1062
-                'EVT_default_registration_status',
1063
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1064
-            );
1065
-
1066
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1067
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1068
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1069
-        } elseif ($post instanceof WP_Post) {
1070
-            $event_values['EVT_name'] = $post->post_title;
1071
-            $event_values['EVT_desc'] = $post->post_content;
1072
-        }
1073
-        // update event
1074
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
-        // get event_object for other metaboxes...
1076
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
-        // i have to setup where conditions to override the filters in the model
1078
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1079
-        /** @var EE_Event $event */
1080
-        $event = $this->_event_model()->get_one(
1081
-            [
1082
-                [
1083
-                    $this->_event_model()->primary_key_name() => $post_id,
1084
-                    'OR'                                      => [
1085
-                        'status'   => $post->post_status,
1086
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1087
-                        // but the returned object here has a status of "publish", so use the original post status as well
1088
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1089
-                    ],
1090
-                    'status' => ['NOT IN', ['auto-draft']],
1091
-                ],
1092
-            ]
1093
-        );
1094
-
1095
-        // the following are default callbacks for event attachment updates
1096
-        // that can be overridden by caffeinated functionality and/or addons.
1097
-        $event_update_callbacks = [];
1098
-        if (! $this->admin_config->useAdvancedEditor()) {
1099
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1100
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1101
-        }
1102
-        $event_update_callbacks = apply_filters(
1103
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1104
-            $event_update_callbacks
1105
-        );
1106
-
1107
-        $att_success = true;
1108
-        foreach ($event_update_callbacks as $e_callback) {
1109
-            $_success = is_callable($e_callback)
1110
-                ? $e_callback($event, $this->request->requestParams())
1111
-                : false;
1112
-            // if ANY of these updates fail then we want the appropriate global error message
1113
-            $att_success = $_success !== false ? $att_success : false;
1114
-        }
1115
-        // any errors?
1116
-        if ($success && $att_success === false) {
1117
-            EE_Error::add_error(
1118
-                esc_html__(
1119
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1120
-                    'event_espresso'
1121
-                ),
1122
-                __FILE__,
1123
-                __FUNCTION__,
1124
-                __LINE__
1125
-            );
1126
-        } elseif ($success === false) {
1127
-            EE_Error::add_error(
1128
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1129
-                __FILE__,
1130
-                __FUNCTION__,
1131
-                __LINE__
1132
-            );
1133
-        }
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * @param int $post_id
1139
-     * @param int $revision_id
1140
-     * @throws EE_Error
1141
-     * @throws EE_Error
1142
-     * @throws ReflectionException
1143
-     * @see parent::restore_item()
1144
-     */
1145
-    protected function _restore_cpt_item(int $post_id, int $revision_id)
1146
-    {
1147
-        // copy existing event meta to new post
1148
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1149
-        if ($post_evt instanceof EE_Event) {
1150
-            // meta revision restore
1151
-            $post_evt->restore_revision($revision_id);
1152
-            // related objs restore
1153
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1154
-        }
1155
-    }
1156
-
1157
-
1158
-    /**
1159
-     * Attach the venue to the Event
1160
-     *
1161
-     * @param EE_Event $event Event Object to add the venue to
1162
-     * @param array    $data  The request data from the form
1163
-     * @return bool           Success or fail.
1164
-     * @throws EE_Error
1165
-     * @throws ReflectionException
1166
-     */
1167
-    protected function _default_venue_update(EE_Event $event, array $data): bool
1168
-    {
1169
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1170
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1171
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1172
-        // very important.  If we don't have a venue name...
1173
-        // then we'll get out because not necessary to create empty venue
1174
-        if (empty($data['venue_title'])) {
1175
-            return false;
1176
-        }
1177
-        $venue_array = [
1178
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1179
-            'VNU_name'            => $data['venue_title'],
1180
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1181
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1182
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1183
-                ? $data['venue_short_description']
1184
-                : null,
1185
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1186
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1187
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1188
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1189
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1190
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1191
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1192
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1193
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1194
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1195
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1196
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1197
-            'status'              => 'publish',
1198
-        ];
1199
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1200
-        if (! empty($venue_id)) {
1201
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1202
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1203
-            // we've gotta make sure that the venue is always attached to a revision..
1204
-            // add_relation_to should take care of making sure that the relation is already present.
1205
-            $event->_add_relation_to($venue_id, 'Venue');
1206
-            return $rows_affected > 0;
1207
-        }
1208
-        // we insert the venue
1209
-        $venue_id = $venue_model->insert($venue_array);
1210
-        $event->_add_relation_to($venue_id, 'Venue');
1211
-        return ! empty($venue_id);
1212
-        // when we have the ancestor come in it's already been handled by the revision save.
1213
-    }
1214
-
1215
-
1216
-    /**
1217
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1218
-     *
1219
-     * @param EE_Event $event The Event object we're attaching data to
1220
-     * @param array    $data  The request data from the form
1221
-     * @return array
1222
-     * @throws EE_Error
1223
-     * @throws ReflectionException
1224
-     * @throws Exception
1225
-     */
1226
-    protected function _default_tickets_update(EE_Event $event, array $data): array
1227
-    {
1228
-        if ($this->admin_config->useAdvancedEditor()) {
1229
-            return [];
1230
-        }
1231
-        $datetime       = null;
1232
-        $saved_tickets  = [];
1233
-        $event_timezone = $event->get_timezone();
1234
-        $date_formats   = ['Y-m-d', 'h:i a'];
1235
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1236
-            // trim all values to ensure any excess whitespace is removed.
1237
-            $datetime_data                = array_map('trim', $datetime_data);
1238
-            $datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1239
-                    ? $datetime_data['DTT_EVT_end']
1240
-                    : $datetime_data['DTT_EVT_start'];
1241
-            $datetime_values              = [
1242
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1243
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1244
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1245
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1246
-                'DTT_order'     => $row,
1247
-            ];
1248
-            // if we have an id then let's get existing object first and then set the new values.
1249
-            //  Otherwise we instantiate a new object for save.
1250
-            if (! empty($datetime_data['DTT_ID'])) {
1251
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1252
-                if (! $datetime instanceof EE_Datetime) {
1253
-                    throw new RuntimeException(
1254
-                        sprintf(
1255
-                            esc_html__(
1256
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1257
-                                'event_espresso'
1258
-                            ),
1259
-                            $datetime_data['DTT_ID']
1260
-                        )
1261
-                    );
1262
-                }
1263
-                $datetime->set_date_format($date_formats[0]);
1264
-                $datetime->set_time_format($date_formats[1]);
1265
-                foreach ($datetime_values as $field => $value) {
1266
-                    $datetime->set($field, $value);
1267
-                }
1268
-            } else {
1269
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1270
-            }
1271
-            if (! $datetime instanceof EE_Datetime) {
1272
-                throw new RuntimeException(
1273
-                    sprintf(
1274
-                        esc_html__(
1275
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1276
-                            'event_espresso'
1277
-                        ),
1278
-                        print_r($datetime_values, true)
1279
-                    )
1280
-                );
1281
-            }
1282
-            // before going any further make sure our dates are setup correctly
1283
-            // so that the end date is always equal or greater than the start date.
1284
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1285
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1286
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1287
-            }
1288
-            $datetime->save();
1289
-            $event->_add_relation_to($datetime, 'Datetime');
1290
-        }
1291
-        // no datetimes get deleted so we don't do any of that logic here.
1292
-        // update tickets next
1293
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1294
-
1295
-        // set up some default start and end dates in case those are not present in the incoming data
1296
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1297
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1298
-        // use the start date of the first datetime for the end date
1299
-        $first_datetime   = $event->first_datetime();
1300
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1301
-
1302
-        // now process the incoming data
1303
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1304
-            $update_prices = false;
1305
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1306
-            // trim inputs to ensure any excess whitespace is removed.
1307
-            $ticket_data   = array_map('trim', $ticket_data);
1308
-            $ticket_values = [
1309
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1310
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1311
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1312
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1313
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1314
-                    ? $ticket_data['TKT_start_date']
1315
-                    : $default_start_date,
1316
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1317
-                    ? $ticket_data['TKT_end_date']
1318
-                    : $default_end_date,
1319
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1320
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1321
-                    ? $ticket_data['TKT_qty']
1322
-                    : EE_INF,
1323
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1324
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1325
-                    ? $ticket_data['TKT_uses']
1326
-                    : EE_INF,
1327
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1328
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1329
-                'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1330
-                'TKT_price'       => $ticket_price,
1331
-                'TKT_row'         => $row,
1332
-            ];
1333
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1334
-            // which means in turn that the prices will become new prices as well.
1335
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1336
-                $ticket_values['TKT_ID']         = 0;
1337
-                $ticket_values['TKT_is_default'] = 0;
1338
-                $update_prices                   = true;
1339
-            }
1340
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1341
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1342
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1343
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1344
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1345
-            if (! empty($ticket_data['TKT_ID'])) {
1346
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1347
-                if (! $existing_ticket instanceof EE_Ticket) {
1348
-                    throw new RuntimeException(
1349
-                        sprintf(
1350
-                            esc_html__(
1351
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1352
-                                'event_espresso'
1353
-                            ),
1354
-                            $ticket_data['TKT_ID']
1355
-                        )
1356
-                    );
1357
-                }
1358
-                $ticket_sold = $existing_ticket->count_related(
1359
-                        'Registration',
1360
-                        [
1361
-                            [
1362
-                                'STS_ID' => [
1363
-                                    'NOT IN',
1364
-                                    [EEM_Registration::status_id_incomplete],
1365
-                                ],
1366
-                            ],
1367
-                        ]
1368
-                    ) > 0;
1369
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1370
-                // if they are different then we create a new ticket (if $ticket_sold)
1371
-                // if they aren't different then we go ahead and modify existing ticket.
1372
-                $create_new_ticket = $ticket_sold
1373
-                                     && $ticket_price !== $existing_ticket->price()
1374
-                                     && ! $existing_ticket->deleted();
1375
-                $existing_ticket->set_date_format($date_formats[0]);
1376
-                $existing_ticket->set_time_format($date_formats[1]);
1377
-                // set new values
1378
-                foreach ($ticket_values as $field => $value) {
1379
-                    if ($field == 'TKT_qty') {
1380
-                        $existing_ticket->set_qty($value);
1381
-                    } elseif ($field == 'TKT_price') {
1382
-                        $existing_ticket->set('TKT_price', $ticket_price);
1383
-                    } else {
1384
-                        $existing_ticket->set($field, $value);
1385
-                    }
1386
-                }
1387
-                $ticket = $existing_ticket;
1388
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1389
-                //  Otherwise we have to create a new ticket.
1390
-                if ($create_new_ticket) {
1391
-                    // archive the old ticket first
1392
-                    $existing_ticket->set('TKT_deleted', 1);
1393
-                    $existing_ticket->save();
1394
-                    // make sure this ticket is still recorded in our $saved_tickets
1395
-                    // so we don't run it through the regular trash routine.
1396
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1397
-                    // create new ticket that's a copy of the existing except,
1398
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1399
-                    $new_ticket = clone $existing_ticket;
1400
-                    $new_ticket->set('TKT_ID', 0);
1401
-                    $new_ticket->set('TKT_deleted', 0);
1402
-                    $new_ticket->set('TKT_sold', 0);
1403
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1404
-                    $update_prices = true;
1405
-                    $ticket        = $new_ticket;
1406
-                }
1407
-            } else {
1408
-                // no TKT_id so a new ticket
1409
-                $ticket_values['TKT_price'] = $ticket_price;
1410
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1411
-                $update_prices              = true;
1412
-            }
1413
-            if (! $ticket instanceof EE_Ticket) {
1414
-                throw new RuntimeException(
1415
-                    sprintf(
1416
-                        esc_html__(
1417
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1418
-                            'event_espresso'
1419
-                        ),
1420
-                        print_r($ticket_values, true)
1421
-                    )
1422
-                );
1423
-            }
1424
-            // cap ticket qty by datetime reg limits
1425
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1426
-            // update ticket.
1427
-            $ticket->save();
1428
-            // before going any further make sure our dates are setup correctly
1429
-            // so that the end date is always equal or greater than the start date.
1430
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1431
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1432
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1433
-                $ticket->save();
1434
-            }
1435
-            // initially let's add the ticket to the datetime
1436
-            $datetime->_add_relation_to($ticket, 'Ticket');
1437
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1438
-            // add prices to ticket
1439
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1440
-                ? $data['edit_prices'][ $row ]
1441
-                : [];
1442
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1443
-        }
1444
-        // however now we need to handle permanently deleting tickets via the ui.
1445
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1446
-        // However, it does allow for deleting tickets that have no tickets sold,
1447
-        // in which case we want to get rid of permanently because there is no need to save in db.
1448
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1449
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1450
-        foreach ($tickets_removed as $id) {
1451
-            $id = absint($id);
1452
-            // get the ticket for this id
1453
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1454
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1455
-                continue;
1456
-            }
1457
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1458
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1459
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1460
-            foreach ($related_datetimes as $related_datetime) {
1461
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1462
-            }
1463
-            // need to do the same for prices (except these prices can also be deleted because again,
1464
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1465
-            $ticket_to_remove->delete_related_permanently('Price');
1466
-            // finally let's delete this ticket
1467
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1468
-            $ticket_to_remove->delete_permanently();
1469
-        }
1470
-        return [$datetime, $saved_tickets];
1471
-    }
1472
-
1473
-
1474
-    /**
1475
-     * This attaches a list of given prices to a ticket.
1476
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1477
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1478
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1479
-     *
1480
-     * @access  private
1481
-     * @param array     $prices_data Array of prices from the form.
1482
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1483
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1484
-     * @return  void
1485
-     * @throws EE_Error
1486
-     * @throws ReflectionException
1487
-     */
1488
-    private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1489
-    {
1490
-        $timezone = $ticket->get_timezone();
1491
-        foreach ($prices_data as $row => $price_data) {
1492
-            $price_values = [
1493
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1494
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1495
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1496
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1497
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1498
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1499
-                'PRC_order'      => $row,
1500
-            ];
1501
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1502
-                $price_values['PRC_ID'] = 0;
1503
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1504
-            } else {
1505
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1506
-                // update this price with new values
1507
-                foreach ($price_values as $field => $new_price) {
1508
-                    $price->set($field, $new_price);
1509
-                }
1510
-            }
1511
-            if (! $price instanceof EE_Price) {
1512
-                throw new RuntimeException(
1513
-                    sprintf(
1514
-                        esc_html__(
1515
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1516
-                            'event_espresso'
1517
-                        ),
1518
-                        print_r($price_values, true)
1519
-                    )
1520
-                );
1521
-            }
1522
-            $price->save();
1523
-            $ticket->_add_relation_to($price, 'Price');
1524
-        }
1525
-    }
1526
-
1527
-
1528
-    /**
1529
-     * Add in our autosave ajax handlers
1530
-     */
1531
-    protected function _ee_autosave_create_new()
1532
-    {
1533
-    }
1534
-
1535
-
1536
-    /**
1537
-     * More autosave handlers.
1538
-     */
1539
-    protected function _ee_autosave_edit()
1540
-    {
1541
-    }
1542
-
1543
-
1544
-    /**
1545
-     * @throws EE_Error
1546
-     * @throws ReflectionException
1547
-     */
1548
-    private function _generate_publish_box_extra_content()
1549
-    {
1550
-        // load formatter helper
1551
-        // args for getting related registrations
1552
-        $approved_query_args        = [
1553
-            [
1554
-                'REG_deleted' => 0,
1555
-                'STS_ID'      => EEM_Registration::status_id_approved,
1556
-            ],
1557
-        ];
1558
-        $not_approved_query_args    = [
1559
-            [
1560
-                'REG_deleted' => 0,
1561
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1562
-            ],
1563
-        ];
1564
-        $pending_payment_query_args = [
1565
-            [
1566
-                'REG_deleted' => 0,
1567
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1568
-            ],
1569
-        ];
1570
-        // publish box
1571
-        $publish_box_extra_args = [
1572
-            'view_approved_reg_url'        => add_query_arg(
1573
-                [
1574
-                    'action'      => 'default',
1575
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1576
-                    '_reg_status' => EEM_Registration::status_id_approved,
1577
-                    'use_filters' => true,
1578
-                ],
1579
-                REG_ADMIN_URL
1580
-            ),
1581
-            'view_not_approved_reg_url'    => add_query_arg(
1582
-                [
1583
-                    'action'      => 'default',
1584
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1585
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1586
-                    'use_filters' => true,
1587
-                ],
1588
-                REG_ADMIN_URL
1589
-            ),
1590
-            'view_pending_payment_reg_url' => add_query_arg(
1591
-                [
1592
-                    'action'      => 'default',
1593
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1594
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1595
-                    'use_filters' => true,
1596
-                ],
1597
-                REG_ADMIN_URL
1598
-            ),
1599
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1600
-                'Registration',
1601
-                $approved_query_args
1602
-            ),
1603
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1604
-                'Registration',
1605
-                $not_approved_query_args
1606
-            ),
1607
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1608
-                'Registration',
1609
-                $pending_payment_query_args
1610
-            ),
1611
-            'misc_pub_section_class'       => apply_filters(
1612
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1613
-                'misc-pub-section'
1614
-            ),
1615
-        ];
1616
-        ob_start();
1617
-        do_action(
1618
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1619
-            $this->_cpt_model_obj
1620
-        );
1621
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1622
-        // load template
1623
-        EEH_Template::display_template(
1624
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1625
-            $publish_box_extra_args
1626
-        );
1627
-    }
1628
-
1629
-
1630
-    /**
1631
-     * @return EE_Event
1632
-     */
1633
-    public function get_event_object()
1634
-    {
1635
-        return $this->_cpt_model_obj;
1636
-    }
1637
-
1638
-
1639
-
1640
-
1641
-    /** METABOXES * */
1642
-    /**
1643
-     * _register_event_editor_meta_boxes
1644
-     * add all metaboxes related to the event_editor
1645
-     *
1646
-     * @return void
1647
-     * @throws EE_Error
1648
-     * @throws ReflectionException
1649
-     */
1650
-    protected function _register_event_editor_meta_boxes()
1651
-    {
1652
-        $this->verify_cpt_object();
1653
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1654
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1655
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1656
-            $this->addMetaBox(
1657
-                'espresso_event_editor_event_options',
1658
-                esc_html__('Event Registration Options', 'event_espresso'),
1659
-                [$this, 'registration_options_meta_box'],
1660
-                $this->page_slug,
1661
-                'side'
1662
-            );
1663
-        }
1664
-        if (! $use_advanced_editor) {
1665
-            $this->addMetaBox(
1666
-                'espresso_event_editor_tickets',
1667
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1668
-                [$this, 'ticket_metabox'],
1669
-                $this->page_slug,
1670
-                'normal',
1671
-                'high'
1672
-            );
1673
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1674
-            add_action(
1675
-                'add_meta_boxes_espresso_events',
1676
-                function () {
1677
-                    global $current_screen;
1678
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1679
-                },
1680
-                99
1681
-            );
1682
-        }
1683
-        // NOTE: if you're looking for other metaboxes in here,
1684
-        // where a metabox has a related management page in the admin
1685
-        // you will find it setup in the related management page's "_Hooks" file.
1686
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1687
-    }
1688
-
1689
-
1690
-    /**
1691
-     * @throws DomainException
1692
-     * @throws EE_Error
1693
-     * @throws ReflectionException
1694
-     */
1695
-    public function ticket_metabox()
1696
-    {
1697
-        $existing_datetime_ids = $existing_ticket_ids = [];
1698
-        // defaults for template args
1699
-        $template_args = [
1700
-            'ticket_rows'       => '',
1701
-            'total_ticket_rows' => 1,
1702
-            'trash_icon'        => 'dashicons dashicons-lock',
1703
-            'disabled'          => '',
1704
-        ];
1705
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1706
-        /**
1707
-         * 1. Start with retrieving Datetimes
1708
-         * 2. Fore each datetime get related tickets
1709
-         * 3. For each ticket get related prices
1710
-         */
1711
-        /** @var EEM_Datetime $datetime_model */
1712
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1713
-        /** @var EEM_Ticket $datetime_model */
1714
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1715
-        $times        = $datetime_model->get_all_event_dates($event_id);
1716
-        /** @type EE_Datetime $first_datetime */
1717
-        $first_datetime = reset($times);
1718
-        // do we get related tickets?
1719
-        if (
1720
-            $first_datetime instanceof EE_Datetime
1721
-            && $first_datetime->ID() !== 0
1722
-        ) {
1723
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1724
-            $template_args['time']   = $first_datetime;
1725
-            $related_tickets         = $first_datetime->tickets(
1726
-                [
1727
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1728
-                    'default_where_conditions' => 'none',
1729
-                ]
1730
-            );
1731
-            if (! empty($related_tickets)) {
1732
-                $template_args['total_ticket_rows'] = count($related_tickets);
1733
-                $row                                = 0;
1734
-                foreach ($related_tickets as $ticket) {
1735
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1736
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1737
-                    $row++;
1738
-                }
1739
-            } else {
1740
-                $template_args['total_ticket_rows'] = 1;
1741
-                /** @type EE_Ticket $ticket */
1742
-                $ticket                       = $ticket_model->create_default_object();
1743
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1744
-            }
1745
-        } else {
1746
-            $template_args['time'] = $times[0];
1747
-            /** @type EE_Ticket[] $tickets */
1748
-            $tickets                      = $ticket_model->get_all_default_tickets();
1749
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1750
-            // NOTE: we're just sending the first default row
1751
-            // (decaf can't manage default tickets so this should be sufficient);
1752
-        }
1753
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1754
-            'event_editor_event_datetimes_help_tab'
1755
-        );
1756
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1757
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1758
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1759
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1760
-            $ticket_model->create_default_object(),
1761
-            true
1762
-        );
1763
-        $template                                  = apply_filters(
1764
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1765
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1766
-        );
1767
-        EEH_Template::display_template($template, $template_args);
1768
-    }
1769
-
1770
-
1771
-    /**
1772
-     * Setup an individual ticket form for the decaf event editor page
21
+	/**
22
+	 * primary key for the event model
23
+	 */
24
+	private int $EVT_ID = 0;
25
+
26
+	/**
27
+	 * This will hold the event object for event_details screen.
28
+	 *
29
+	 * @var EE_Event|null $_event
30
+	 */
31
+	protected ?EE_Event $_event = null;
32
+
33
+	/**
34
+	 * This will hold the category object for category_details screen.
35
+	 */
36
+	protected ?stdClass $_category = null;
37
+
38
+	protected ?EEM_Event $_event_model = null;
39
+
40
+	/**
41
+	 * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
42
+	 */
43
+	protected $_cpt_model_obj;
44
+
45
+	protected ?NodeGroupDao $model_obj_node_group_persister = null;
46
+
47
+	protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
48
+
49
+
50
+	/**
51
+	 * Initialize page props for this admin page group.
52
+	 */
53
+	protected function _init_page_props()
54
+	{
55
+		// is there a evt_id in the request?
56
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
57
+		$this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
58
+		$this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
59
+
60
+		$this->page_slug        = EVENTS_PG_SLUG;
61
+		$this->page_label       = EVENTS_LABEL;
62
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
63
+		$this->_admin_base_path = EVENTS_ADMIN;
64
+		$this->_cpt_model_names = [
65
+			'create_new' => 'EEM_Event',
66
+			'edit'       => 'EEM_Event',
67
+		];
68
+		$this->_cpt_edit_routes = [
69
+			'espresso_events' => 'edit',
70
+		];
71
+		add_action(
72
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
+			[$this, 'verify_event_edit'],
74
+			10,
75
+			2
76
+		);
77
+	}
78
+
79
+
80
+	/**
81
+	 * Sets the ajax hooks used for this admin page group.
82
+	 */
83
+	protected function _ajax_hooks()
84
+	{
85
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
+	}
87
+
88
+
89
+	/**
90
+	 * Sets the page properties for this admin page group.
91
+	 */
92
+	protected function _define_page_props()
93
+	{
94
+		$this->_admin_page_title = EVENTS_LABEL;
95
+		$this->_labels           = [
96
+			'buttons'      => [
97
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
98
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
+			],
104
+			'editor_title' => [
105
+				'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
106
+			],
107
+			'publishbox'   => [
108
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
110
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
+			],
114
+		];
115
+	}
116
+
117
+
118
+	/**
119
+	 * Sets the page routes property for this admin page group.
120
+	 */
121
+	protected function _set_page_routes()
122
+	{
123
+		$this->_page_routes = [
124
+			'default'                       => [
125
+				'func'       => [$this, '_events_overview_list_table'],
126
+				'capability' => 'ee_read_events',
127
+			],
128
+			'create_new'                    => [
129
+				'func'       => [$this, '_create_new_cpt_item'],
130
+				'capability' => 'ee_edit_events',
131
+			],
132
+			'edit'                          => [
133
+				'func'       => [$this, '_edit_cpt_item'],
134
+				'capability' => 'ee_edit_event',
135
+				'obj_id'     => $this->EVT_ID,
136
+			],
137
+			'copy_event'                    => [
138
+				'func'       => [$this, '_copy_events'],
139
+				'capability' => 'ee_edit_event',
140
+				'obj_id'     => $this->EVT_ID,
141
+				'noheader'   => true,
142
+			],
143
+			'trash_event'                   => [
144
+				'func'       => [$this, '_trash_or_restore_event'],
145
+				'args'       => ['event_status' => 'trash'],
146
+				'capability' => 'ee_delete_event',
147
+				'obj_id'     => $this->EVT_ID,
148
+				'noheader'   => true,
149
+			],
150
+			'trash_events'                  => [
151
+				'func'       => [$this, '_trash_or_restore_events'],
152
+				'args'       => ['event_status' => 'trash'],
153
+				'capability' => 'ee_delete_events',
154
+				'noheader'   => true,
155
+			],
156
+			'restore_event'                 => [
157
+				'func'       => [$this, '_trash_or_restore_event'],
158
+				'args'       => ['event_status' => 'draft'],
159
+				'capability' => 'ee_delete_event',
160
+				'obj_id'     => $this->EVT_ID,
161
+				'noheader'   => true,
162
+			],
163
+			'restore_events'                => [
164
+				'func'       => [$this, '_trash_or_restore_events'],
165
+				'args'       => ['event_status' => 'draft'],
166
+				'capability' => 'ee_delete_events',
167
+				'noheader'   => true,
168
+			],
169
+			'delete_event'                  => [
170
+				'func'       => [$this, '_delete_event'],
171
+				'capability' => 'ee_delete_event',
172
+				'obj_id'     => $this->EVT_ID,
173
+				'noheader'   => true,
174
+			],
175
+			'delete_events'                 => [
176
+				'func'       => [$this, '_delete_events'],
177
+				'capability' => 'ee_delete_events',
178
+				'noheader'   => true,
179
+			],
180
+			'view_report'                   => [
181
+				'func'       => [$this, '_view_report'],
182
+				'capability' => 'ee_edit_events',
183
+			],
184
+			'default_event_settings'        => [
185
+				'func'       => [$this, '_default_event_settings'],
186
+				'capability' => 'manage_options',
187
+			],
188
+			'update_default_event_settings' => [
189
+				'func'       => [$this, '_update_default_event_settings'],
190
+				'capability' => 'manage_options',
191
+				'noheader'   => true,
192
+			],
193
+			'template_settings'             => [
194
+				'func'       => [$this, '_template_settings'],
195
+				'capability' => 'manage_options',
196
+			],
197
+			// event category tab related
198
+			'add_category'                  => [
199
+				'func'       => [$this, '_category_details'],
200
+				'capability' => 'ee_edit_event_category',
201
+				'args'       => ['view' => 'add'],
202
+			],
203
+			'edit_category'                 => [
204
+				'func'       => [$this, '_category_details'],
205
+				'capability' => 'ee_edit_event_category',
206
+				'args'       => ['view' => 'edit'],
207
+			],
208
+			'delete_categories'             => [
209
+				'func'       => [$this, '_delete_categories'],
210
+				'capability' => 'ee_delete_event_category',
211
+				'noheader'   => true,
212
+			],
213
+			'delete_category'               => [
214
+				'func'       => [$this, '_delete_categories'],
215
+				'capability' => 'ee_delete_event_category',
216
+				'noheader'   => true,
217
+			],
218
+			'insert_category'               => [
219
+				'func'       => [$this, '_insert_or_update_category'],
220
+				'args'       => ['new_category' => true],
221
+				'capability' => 'ee_edit_event_category',
222
+				'noheader'   => true,
223
+			],
224
+			'update_category'               => [
225
+				'func'       => [$this, '_insert_or_update_category'],
226
+				'args'       => ['new_category' => false],
227
+				'capability' => 'ee_edit_event_category',
228
+				'noheader'   => true,
229
+			],
230
+			'category_list'                 => [
231
+				'func'       => [$this, '_category_list_table'],
232
+				'capability' => 'ee_manage_event_categories',
233
+			],
234
+			'preview_deletion'              => [
235
+				'func'       => [$this, 'previewDeletion'],
236
+				'capability' => 'ee_delete_events',
237
+			],
238
+			'confirm_deletion'              => [
239
+				'func'       => [$this, 'confirmDeletion'],
240
+				'capability' => 'ee_delete_events',
241
+				'noheader'   => true,
242
+			],
243
+		];
244
+	}
245
+
246
+
247
+	/**
248
+	 * Set the _page_config property for this admin page group.
249
+	 */
250
+	protected function _set_page_config()
251
+	{
252
+		$post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
253
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
254
+		$this->_page_config = [
255
+			'default'                => [
256
+				'nav'           => [
257
+					'label' => esc_html__('Overview', 'event_espresso'),
258
+					'icon'  => 'dashicons-list-view',
259
+					'order' => 10,
260
+				],
261
+				'list_table'    => 'Events_Admin_List_Table',
262
+				'help_tabs'     => [
263
+					'events_overview_help_tab'                       => [
264
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
265
+						'filename' => 'events_overview',
266
+					],
267
+					'events_overview_table_column_headings_help_tab' => [
268
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
269
+						'filename' => 'events_overview_table_column_headings',
270
+					],
271
+					'events_overview_filters_help_tab'               => [
272
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
273
+						'filename' => 'events_overview_filters',
274
+					],
275
+					'events_overview_view_help_tab'                  => [
276
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
277
+						'filename' => 'events_overview_views',
278
+					],
279
+					'events_overview_other_help_tab'                 => [
280
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
281
+						'filename' => 'events_overview_other',
282
+					],
283
+				],
284
+				'require_nonce' => false,
285
+			],
286
+			'create_new'             => [
287
+				'nav'           => [
288
+					'label'      => esc_html__('Add New Event', 'event_espresso'),
289
+					'icon'       => 'dashicons-plus-alt',
290
+					'order'      => 15,
291
+					'persistent' => false,
292
+				],
293
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
294
+				'help_tabs'     => [
295
+					'event_editor_help_tab'                            => [
296
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
297
+						'filename' => 'event_editor',
298
+					],
299
+					'event_editor_title_richtexteditor_help_tab'       => [
300
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
301
+						'filename' => 'event_editor_title_richtexteditor',
302
+					],
303
+					'event_editor_venue_details_help_tab'              => [
304
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
305
+						'filename' => 'event_editor_venue_details',
306
+					],
307
+					'event_editor_event_datetimes_help_tab'            => [
308
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
309
+						'filename' => 'event_editor_event_datetimes',
310
+					],
311
+					'event_editor_event_tickets_help_tab'              => [
312
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
313
+						'filename' => 'event_editor_event_tickets',
314
+					],
315
+					'event_editor_event_registration_options_help_tab' => [
316
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
317
+						'filename' => 'event_editor_event_registration_options',
318
+					],
319
+					'event_editor_tags_categories_help_tab'            => [
320
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
321
+						'filename' => 'event_editor_tags_categories',
322
+					],
323
+					'event_editor_questions_registrants_help_tab'      => [
324
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
325
+						'filename' => 'event_editor_questions_registrants',
326
+					],
327
+					'event_editor_save_new_event_help_tab'             => [
328
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
329
+						'filename' => 'event_editor_save_new_event',
330
+					],
331
+					'event_editor_other_help_tab'                      => [
332
+						'title'    => esc_html__('Event Other', 'event_espresso'),
333
+						'filename' => 'event_editor_other',
334
+					],
335
+				],
336
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
337
+				'require_nonce' => false,
338
+			],
339
+			'edit'                   => [
340
+				'nav'           => [
341
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
342
+					'icon'       => 'dashicons-edit',
343
+					'order'      => 15,
344
+					'persistent' => false,
345
+					'url'        => $post_id
346
+						? EE_Admin_Page::add_query_args_and_nonce(
347
+							['post' => $post_id, 'action' => 'edit'],
348
+							$this->_current_page_view_url
349
+						)
350
+						: $this->_admin_base_url,
351
+				],
352
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
353
+				'help_tabs'     => [
354
+					'event_editor_help_tab'                            => [
355
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
356
+						'filename' => 'event_editor',
357
+					],
358
+					'event_editor_title_richtexteditor_help_tab'       => [
359
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
360
+						'filename' => 'event_editor_title_richtexteditor',
361
+					],
362
+					'event_editor_venue_details_help_tab'              => [
363
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
364
+						'filename' => 'event_editor_venue_details',
365
+					],
366
+					'event_editor_event_datetimes_help_tab'            => [
367
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
368
+						'filename' => 'event_editor_event_datetimes',
369
+					],
370
+					'event_editor_event_tickets_help_tab'              => [
371
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
372
+						'filename' => 'event_editor_event_tickets',
373
+					],
374
+					'event_editor_event_registration_options_help_tab' => [
375
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
376
+						'filename' => 'event_editor_event_registration_options',
377
+					],
378
+					'event_editor_tags_categories_help_tab'            => [
379
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
380
+						'filename' => 'event_editor_tags_categories',
381
+					],
382
+					'event_editor_questions_registrants_help_tab'      => [
383
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
384
+						'filename' => 'event_editor_questions_registrants',
385
+					],
386
+					'event_editor_save_new_event_help_tab'             => [
387
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
388
+						'filename' => 'event_editor_save_new_event',
389
+					],
390
+					'event_editor_other_help_tab'                      => [
391
+						'title'    => esc_html__('Event Other', 'event_espresso'),
392
+						'filename' => 'event_editor_other',
393
+					],
394
+				],
395
+				'require_nonce' => false,
396
+			],
397
+			'default_event_settings' => [
398
+				'nav'           => [
399
+					'label' => esc_html__('Default Settings', 'event_espresso'),
400
+					'icon'  => 'dashicons-admin-generic',
401
+					'order' => 40,
402
+				],
403
+				'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
404
+				'labels'        => [
405
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
406
+				],
407
+				'help_tabs'     => [
408
+					'default_settings_help_tab'        => [
409
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
410
+						'filename' => 'events_default_settings',
411
+					],
412
+					'default_settings_status_help_tab' => [
413
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
414
+						'filename' => 'events_default_settings_status',
415
+					],
416
+					'default_maximum_tickets_help_tab' => [
417
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
418
+						'filename' => 'events_default_settings_max_tickets',
419
+					],
420
+				],
421
+				'require_nonce' => false,
422
+			],
423
+			// template settings
424
+			'template_settings'      => [
425
+				'nav'           => [
426
+					'label' => esc_html__('Templates', 'event_espresso'),
427
+					'icon'  => 'dashicons-layout',
428
+					'order' => 30,
429
+				],
430
+				'metaboxes'     => $this->_default_espresso_metaboxes,
431
+				'help_tabs'     => [
432
+					'general_settings_templates_help_tab' => [
433
+						'title'    => esc_html__('Templates', 'event_espresso'),
434
+						'filename' => 'general_settings_templates',
435
+					],
436
+				],
437
+				'require_nonce' => false,
438
+			],
439
+			// event category stuff
440
+			'add_category'           => [
441
+				'nav'           => [
442
+					'label'      => esc_html__('Add Category', 'event_espresso'),
443
+					'icon'       => 'dashicons-plus-alt',
444
+					'order'      => 25,
445
+					'persistent' => false,
446
+				],
447
+				'help_tabs'     => [
448
+					'add_category_help_tab' => [
449
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
450
+						'filename' => 'events_add_category',
451
+					],
452
+				],
453
+				'metaboxes'     => ['_publish_post_box'],
454
+				'require_nonce' => false,
455
+			],
456
+			'edit_category'          => [
457
+				'nav'           => [
458
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
459
+					'icon'       => 'dashicons-edit',
460
+					'order'      => 25,
461
+					'persistent' => false,
462
+					'url'        => $EVT_CAT_ID
463
+						? add_query_arg(
464
+							['EVT_CAT_ID' => $EVT_CAT_ID],
465
+							$this->_current_page_view_url
466
+						)
467
+						: $this->_admin_base_url,
468
+				],
469
+				'help_tabs'     => [
470
+					'edit_category_help_tab' => [
471
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
472
+						'filename' => 'events_edit_category',
473
+					],
474
+				],
475
+				'metaboxes'     => ['_publish_post_box'],
476
+				'require_nonce' => false,
477
+			],
478
+			'category_list'          => [
479
+				'nav'           => [
480
+					'label' => esc_html__('Categories', 'event_espresso'),
481
+					'icon'  => 'dashicons-networking',
482
+					'order' => 20,
483
+				],
484
+				'list_table'    => 'Event_Categories_Admin_List_Table',
485
+				'help_tabs'     => [
486
+					'events_categories_help_tab'                       => [
487
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
488
+						'filename' => 'events_categories',
489
+					],
490
+					'events_categories_table_column_headings_help_tab' => [
491
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
492
+						'filename' => 'events_categories_table_column_headings',
493
+					],
494
+					'events_categories_view_help_tab'                  => [
495
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
496
+						'filename' => 'events_categories_views',
497
+					],
498
+					'events_categories_other_help_tab'                 => [
499
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
500
+						'filename' => 'events_categories_other',
501
+					],
502
+				],
503
+				'metaboxes'     => $this->_default_espresso_metaboxes,
504
+				'require_nonce' => false,
505
+			],
506
+			'preview_deletion'       => [
507
+				'nav'           => [
508
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
509
+					'icon'       => 'dashicons-remove',
510
+					'order'      => 15,
511
+					'persistent' => false,
512
+					'url'        => '',
513
+				],
514
+				'require_nonce' => false,
515
+			],
516
+		];
517
+	}
518
+
519
+
520
+	/**
521
+	 * Used to register any global screen options if necessary for every route in this admin page group.
522
+	 */
523
+	protected function _add_screen_options()
524
+	{
525
+	}
526
+
527
+
528
+	/**
529
+	 * Implementing the screen options for the 'default' route.
530
+	 *
531
+	 * @throws InvalidArgumentException
532
+	 * @throws InvalidDataTypeException
533
+	 * @throws InvalidInterfaceException
534
+	 */
535
+	protected function _add_screen_options_default()
536
+	{
537
+		$this->_per_page_screen_option();
538
+	}
539
+
540
+
541
+	/**
542
+	 * Implementing screen options for the category list route.
543
+	 *
544
+	 * @throws InvalidArgumentException
545
+	 * @throws InvalidDataTypeException
546
+	 * @throws InvalidInterfaceException
547
+	 */
548
+	protected function _add_screen_options_category_list()
549
+	{
550
+		$page_title              = $this->_admin_page_title;
551
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
552
+		$this->_per_page_screen_option();
553
+		$this->_admin_page_title = $page_title;
554
+	}
555
+
556
+
557
+	/**
558
+	 * Used to register any global feature pointers for the admin page group.
559
+	 */
560
+	protected function _add_feature_pointers()
561
+	{
562
+	}
563
+
564
+
565
+	/**
566
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
567
+	 */
568
+	public function load_scripts_styles()
569
+	{
570
+		wp_register_style(
571
+			'events-admin-css',
572
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
573
+			[],
574
+			EVENT_ESPRESSO_VERSION
575
+		);
576
+		wp_register_style(
577
+			'ee-cat-admin',
578
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
579
+			[],
580
+			EVENT_ESPRESSO_VERSION
581
+		);
582
+		wp_enqueue_style('events-admin-css');
583
+		wp_enqueue_style('ee-cat-admin');
584
+		// scripts
585
+		wp_register_script(
586
+			'event_editor_js',
587
+			EVENTS_ASSETS_URL . 'event_editor.js',
588
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
589
+			EVENT_ESPRESSO_VERSION,
590
+			true
591
+		);
592
+	}
593
+
594
+
595
+	/**
596
+	 * Enqueuing scripts and styles specific to this view
597
+	 */
598
+	public function load_scripts_styles_create_new()
599
+	{
600
+		$this->load_scripts_styles_edit();
601
+	}
602
+
603
+
604
+	/**
605
+	 * Enqueuing scripts and styles specific to this view
606
+	 */
607
+	public function load_scripts_styles_edit()
608
+	{
609
+		// styles
610
+		wp_enqueue_style('espresso-ui-theme');
611
+		wp_register_style(
612
+			'event-editor-css',
613
+			EVENTS_ASSETS_URL . 'event-editor.css',
614
+			['ee-admin-css'],
615
+			EVENT_ESPRESSO_VERSION
616
+		);
617
+		wp_enqueue_style('event-editor-css');
618
+		// scripts
619
+		if (! $this->admin_config->useAdvancedEditor()) {
620
+			wp_register_script(
621
+				'event-datetime-metabox',
622
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
623
+				['event_editor_js', 'ee-datepicker'],
624
+				EVENT_ESPRESSO_VERSION
625
+			);
626
+			wp_enqueue_script('event-datetime-metabox');
627
+		}
628
+	}
629
+
630
+
631
+	/**
632
+	 * Populating the _views property for the category list table view.
633
+	 */
634
+	protected function _set_list_table_views_category_list()
635
+	{
636
+		$this->_views = [
637
+			'all' => [
638
+				'slug'        => 'all',
639
+				'label'       => esc_html__('All', 'event_espresso'),
640
+				'count'       => 0,
641
+				'bulk_action' => [
642
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
643
+				],
644
+			],
645
+		];
646
+	}
647
+
648
+
649
+	/**
650
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
651
+	 */
652
+	public function admin_init()
653
+	{
654
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
655
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
656
+			'event_espresso'
657
+		);
658
+	}
659
+
660
+
661
+	/**
662
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
663
+	 * group.
664
+	 */
665
+	public function admin_notices()
666
+	{
667
+	}
668
+
669
+
670
+	/**
671
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
672
+	 * this admin page group.
673
+	 */
674
+	public function admin_footer_scripts()
675
+	{
676
+	}
677
+
678
+
679
+	/**
680
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
681
+	 * warning (via EE_Error::add_error());
682
+	 *
683
+	 * @param EE_Event|null $event Event object
684
+	 * @param string        $req_type
685
+	 * @return void
686
+	 * @throws EE_Error
687
+	 * @throws ReflectionException
688
+	 */
689
+	public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
690
+	{
691
+		// don't need to do this when processing
692
+		if (! empty($req_type)) {
693
+			return;
694
+		}
695
+		// no event?
696
+		if (! $event instanceof EE_Event) {
697
+			$event = $this->_cpt_model_obj;
698
+		}
699
+		// STILL no event?
700
+		if (! $event instanceof EE_Event) {
701
+			return;
702
+		}
703
+		// don't need to keep calling this
704
+		remove_action(
705
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
706
+			[$this, 'verify_event_edit']
707
+		);
708
+		$orig_status = $event->status();
709
+		// first check if event is active.
710
+		if (
711
+			$orig_status === EEM_Event::cancelled
712
+			|| $orig_status === EEM_Event::postponed
713
+			|| $event->is_expired()
714
+			|| $event->is_inactive()
715
+		) {
716
+			return;
717
+		}
718
+		// made it here so it IS active... next check that any of the tickets are sold.
719
+		if ($event->is_sold_out(true)) {
720
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
721
+				EE_Error::add_attention(
722
+					sprintf(
723
+						esc_html__(
724
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
725
+							'event_espresso'
726
+						),
727
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
728
+					)
729
+				);
730
+			}
731
+			return;
732
+		}
733
+		if ($orig_status === EEM_Event::sold_out) {
734
+			EE_Error::add_attention(
735
+				sprintf(
736
+					esc_html__(
737
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
738
+						'event_espresso'
739
+					),
740
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
741
+				)
742
+			);
743
+		}
744
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
745
+		if (! $event->tickets_on_sale()) {
746
+			return;
747
+		}
748
+		// made it here so show warning
749
+		$this->_edit_event_warning();
750
+	}
751
+
752
+
753
+	/**
754
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
755
+	 * When needed, hook this into a EE_Error::add_error() notice.
756
+	 *
757
+	 * @access protected
758
+	 * @return void
759
+	 */
760
+	protected function _edit_event_warning()
761
+	{
762
+		// we don't want to add warnings during these requests
763
+		if ($this->request->getRequestParam('action') === 'editpost') {
764
+			return;
765
+		}
766
+		EE_Error::add_attention(
767
+			sprintf(
768
+				esc_html__(
769
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
770
+					'event_espresso'
771
+				),
772
+				'<a class="espresso-help-tab-lnk ee-help-tab-link">',
773
+				'</a>'
774
+			)
775
+		);
776
+	}
777
+
778
+
779
+	/**
780
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
781
+	 * Otherwise, do the normal logic
782
+	 *
783
+	 * @return void
784
+	 * @throws EE_Error
785
+	 * @throws InvalidArgumentException
786
+	 * @throws InvalidDataTypeException
787
+	 * @throws InvalidInterfaceException
788
+	 * @throws ReflectionException
789
+	 */
790
+	protected function _create_new_cpt_item()
791
+	{
792
+		$has_timezone_string = get_option('timezone_string');
793
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
794
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
795
+			EE_Error::add_attention(
796
+				sprintf(
797
+					esc_html__(
798
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
799
+						'event_espresso'
800
+					),
801
+					'<br>',
802
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
803
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
804
+					. '</select>',
805
+					'<button class="button button--secondary timezone-submit">',
806
+					'</button><span class="spinner"></span>'
807
+				),
808
+				__FILE__,
809
+				__FUNCTION__,
810
+				__LINE__
811
+			);
812
+		}
813
+		parent::_create_new_cpt_item();
814
+	}
815
+
816
+
817
+	/**
818
+	 * Sets the _views property for the default route in this admin page group.
819
+	 */
820
+	protected function _set_list_table_views_default()
821
+	{
822
+		$this->_views = [
823
+			'all'   => [
824
+				'slug'        => 'all',
825
+				'label'       => esc_html__('View All Events', 'event_espresso'),
826
+				'count'       => 0,
827
+				'bulk_action' => [
828
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
829
+				],
830
+			],
831
+			'draft' => [
832
+				'slug'        => 'draft',
833
+				'label'       => esc_html__('Draft', 'event_espresso'),
834
+				'count'       => 0,
835
+				'bulk_action' => [
836
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
837
+				],
838
+			],
839
+		];
840
+		if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
841
+			$this->_views['trash'] = [
842
+				'slug'        => 'trash',
843
+				'label'       => esc_html__('Trash', 'event_espresso'),
844
+				'count'       => 0,
845
+				'bulk_action' => [
846
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
847
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
848
+				],
849
+			];
850
+		}
851
+	}
852
+
853
+
854
+	/**
855
+	 * Provides the legend item array for the default list table view.
856
+	 *
857
+	 * @return array
858
+	 * @throws EE_Error
859
+	 * @throws EE_Error
860
+	 */
861
+	protected function _event_legend_items(): array
862
+	{
863
+		$items    = [
864
+			'view_details'   => [
865
+				'class' => 'dashicons dashicons-visibility',
866
+				'desc'  => esc_html__('View Event', 'event_espresso'),
867
+			],
868
+			'edit_event'     => [
869
+				'class' => 'dashicons dashicons-calendar-alt',
870
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
871
+			],
872
+			'view_attendees' => [
873
+				'class' => 'dashicons dashicons-groups',
874
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
875
+			],
876
+		];
877
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
878
+		$statuses = [
879
+			'sold_out_status'  => [
880
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
881
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
882
+			],
883
+			'active_status'    => [
884
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
885
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
886
+			],
887
+			'upcoming_status'  => [
888
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
889
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
890
+			],
891
+			'postponed_status' => [
892
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
893
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
894
+			],
895
+			'cancelled_status' => [
896
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
897
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
898
+			],
899
+			'expired_status'   => [
900
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
901
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
902
+			],
903
+			'inactive_status'  => [
904
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
905
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
906
+			],
907
+		];
908
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
909
+		return array_merge($items, $statuses);
910
+	}
911
+
912
+
913
+	/**
914
+	 * @return EEM_Event
915
+	 * @throws EE_Error
916
+	 * @throws InvalidArgumentException
917
+	 * @throws InvalidDataTypeException
918
+	 * @throws InvalidInterfaceException
919
+	 * @throws ReflectionException
920
+	 */
921
+	private function _event_model(): EEM_Event
922
+	{
923
+		if (! $this->_event_model instanceof EEM_Event) {
924
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
925
+		}
926
+		return $this->_event_model;
927
+	}
928
+
929
+
930
+	/**
931
+	 * Adds extra buttons to the WP CPT permalink field row.
932
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
933
+	 *
934
+	 * @param string      $return    the current html
935
+	 * @param int         $id        the post id for the page
936
+	 * @param string|null $new_title What the title is
937
+	 * @param string|null $new_slug  what the slug is
938
+	 * @return string            The new html string for the permalink area
939
+	 * @deprecated 5.0.0.p
940
+	 * @see        TicketSelectorShortcodeButton::addButton
941
+	 */
942
+	public function extra_permalink_field_buttons(
943
+		string $return,
944
+		int $id,
945
+		?string $new_title,
946
+		?string $new_slug
947
+	): string {
948
+		return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
949
+	}
950
+
951
+
952
+	/**
953
+	 * _events_overview_list_table
954
+	 * This contains the logic for showing the events_overview list
955
+	 *
956
+	 * @access protected
957
+	 * @return void
958
+	 * @throws DomainException
959
+	 * @throws EE_Error
960
+	 * @throws InvalidArgumentException
961
+	 * @throws InvalidDataTypeException
962
+	 * @throws InvalidInterfaceException
963
+	 */
964
+	protected function _events_overview_list_table()
965
+	{
966
+		$after_list_table = [];
967
+		$links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
968
+		$links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
969
+		$links_html       .= EEH_HTML::div(
970
+			EEH_Template::get_button_or_link(
971
+				get_post_type_archive_link('espresso_events'),
972
+				esc_html__('View Event Archive Page', 'event_espresso'),
973
+				'button button--small button--secondary'
974
+			),
975
+			'',
976
+			'ee-admin-button-row ee-admin-button-row--align-start'
977
+		);
978
+		$links_html       .= EEH_HTML::divx();
979
+
980
+		$after_list_table['view_event_list_button'] = $links_html;
981
+
982
+		$after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
983
+		$this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
984
+				'create_new',
985
+				'add',
986
+				[],
987
+				'add-new-h2'
988
+			);
989
+
990
+		$this->_template_args['after_list_table'] = array_merge(
991
+			(array) $this->_template_args['after_list_table'],
992
+			$after_list_table
993
+		);
994
+		$this->display_admin_list_table_page_with_no_sidebar();
995
+	}
996
+
997
+
998
+	/**
999
+	 * this allows for extra misc actions in the default WP publish box
1000
+	 *
1001
+	 * @return void
1002
+	 * @throws DomainException
1003
+	 * @throws EE_Error
1004
+	 * @throws InvalidArgumentException
1005
+	 * @throws InvalidDataTypeException
1006
+	 * @throws InvalidInterfaceException
1007
+	 * @throws ReflectionException
1008
+	 */
1009
+	public function extra_misc_actions_publish_box()
1010
+	{
1011
+		$this->_generate_publish_box_extra_content();
1012
+	}
1013
+
1014
+
1015
+	/**
1016
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1017
+	 * saved.
1018
+	 * Typically you would use this to save any additional data.
1019
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1020
+	 * ALSO very important.  When a post transitions from scheduled to published,
1021
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1022
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1023
+	 *
1024
+	 * @access protected
1025
+	 * @abstract
1026
+	 * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1027
+	 * @param WP_Post $post    The post object of the cpt that was saved.
1028
+	 * @return void
1029
+	 * @throws EE_Error
1030
+	 * @throws InvalidArgumentException
1031
+	 * @throws InvalidDataTypeException
1032
+	 * @throws InvalidInterfaceException
1033
+	 * @throws ReflectionException
1034
+	 */
1035
+	protected function _insert_update_cpt_item($post_id, $post)
1036
+	{
1037
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1038
+			// get out we're not processing an event save.
1039
+			return;
1040
+		}
1041
+		$event_values = [
1042
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1043
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1044
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1045
+		];
1046
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1047
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1049
+				'display_ticket_selector',
1050
+				false,
1051
+				'bool'
1052
+			);
1053
+			$event_values['EVT_additional_limit']            = min(
1054
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1055
+				$this->request->getRequestParam(
1056
+					'additional_limit',
1057
+					EEM_Event::get_default_additional_limit(),
1058
+					'int'
1059
+				)
1060
+			);
1061
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1062
+				'EVT_default_registration_status',
1063
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1064
+			);
1065
+
1066
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1067
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1068
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1069
+		} elseif ($post instanceof WP_Post) {
1070
+			$event_values['EVT_name'] = $post->post_title;
1071
+			$event_values['EVT_desc'] = $post->post_content;
1072
+		}
1073
+		// update event
1074
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
+		// get event_object for other metaboxes...
1076
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
+		// i have to setup where conditions to override the filters in the model
1078
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1079
+		/** @var EE_Event $event */
1080
+		$event = $this->_event_model()->get_one(
1081
+			[
1082
+				[
1083
+					$this->_event_model()->primary_key_name() => $post_id,
1084
+					'OR'                                      => [
1085
+						'status'   => $post->post_status,
1086
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1087
+						// but the returned object here has a status of "publish", so use the original post status as well
1088
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1089
+					],
1090
+					'status' => ['NOT IN', ['auto-draft']],
1091
+				],
1092
+			]
1093
+		);
1094
+
1095
+		// the following are default callbacks for event attachment updates
1096
+		// that can be overridden by caffeinated functionality and/or addons.
1097
+		$event_update_callbacks = [];
1098
+		if (! $this->admin_config->useAdvancedEditor()) {
1099
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1100
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1101
+		}
1102
+		$event_update_callbacks = apply_filters(
1103
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1104
+			$event_update_callbacks
1105
+		);
1106
+
1107
+		$att_success = true;
1108
+		foreach ($event_update_callbacks as $e_callback) {
1109
+			$_success = is_callable($e_callback)
1110
+				? $e_callback($event, $this->request->requestParams())
1111
+				: false;
1112
+			// if ANY of these updates fail then we want the appropriate global error message
1113
+			$att_success = $_success !== false ? $att_success : false;
1114
+		}
1115
+		// any errors?
1116
+		if ($success && $att_success === false) {
1117
+			EE_Error::add_error(
1118
+				esc_html__(
1119
+					'Event Details saved successfully but something went wrong with saving attachments.',
1120
+					'event_espresso'
1121
+				),
1122
+				__FILE__,
1123
+				__FUNCTION__,
1124
+				__LINE__
1125
+			);
1126
+		} elseif ($success === false) {
1127
+			EE_Error::add_error(
1128
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1129
+				__FILE__,
1130
+				__FUNCTION__,
1131
+				__LINE__
1132
+			);
1133
+		}
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * @param int $post_id
1139
+	 * @param int $revision_id
1140
+	 * @throws EE_Error
1141
+	 * @throws EE_Error
1142
+	 * @throws ReflectionException
1143
+	 * @see parent::restore_item()
1144
+	 */
1145
+	protected function _restore_cpt_item(int $post_id, int $revision_id)
1146
+	{
1147
+		// copy existing event meta to new post
1148
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1149
+		if ($post_evt instanceof EE_Event) {
1150
+			// meta revision restore
1151
+			$post_evt->restore_revision($revision_id);
1152
+			// related objs restore
1153
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1154
+		}
1155
+	}
1156
+
1157
+
1158
+	/**
1159
+	 * Attach the venue to the Event
1160
+	 *
1161
+	 * @param EE_Event $event Event Object to add the venue to
1162
+	 * @param array    $data  The request data from the form
1163
+	 * @return bool           Success or fail.
1164
+	 * @throws EE_Error
1165
+	 * @throws ReflectionException
1166
+	 */
1167
+	protected function _default_venue_update(EE_Event $event, array $data): bool
1168
+	{
1169
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1170
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1171
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1172
+		// very important.  If we don't have a venue name...
1173
+		// then we'll get out because not necessary to create empty venue
1174
+		if (empty($data['venue_title'])) {
1175
+			return false;
1176
+		}
1177
+		$venue_array = [
1178
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1179
+			'VNU_name'            => $data['venue_title'],
1180
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1181
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1182
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1183
+				? $data['venue_short_description']
1184
+				: null,
1185
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1186
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1187
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1188
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1189
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1190
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1191
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1192
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1193
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1194
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1195
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1196
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1197
+			'status'              => 'publish',
1198
+		];
1199
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1200
+		if (! empty($venue_id)) {
1201
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1202
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1203
+			// we've gotta make sure that the venue is always attached to a revision..
1204
+			// add_relation_to should take care of making sure that the relation is already present.
1205
+			$event->_add_relation_to($venue_id, 'Venue');
1206
+			return $rows_affected > 0;
1207
+		}
1208
+		// we insert the venue
1209
+		$venue_id = $venue_model->insert($venue_array);
1210
+		$event->_add_relation_to($venue_id, 'Venue');
1211
+		return ! empty($venue_id);
1212
+		// when we have the ancestor come in it's already been handled by the revision save.
1213
+	}
1214
+
1215
+
1216
+	/**
1217
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1218
+	 *
1219
+	 * @param EE_Event $event The Event object we're attaching data to
1220
+	 * @param array    $data  The request data from the form
1221
+	 * @return array
1222
+	 * @throws EE_Error
1223
+	 * @throws ReflectionException
1224
+	 * @throws Exception
1225
+	 */
1226
+	protected function _default_tickets_update(EE_Event $event, array $data): array
1227
+	{
1228
+		if ($this->admin_config->useAdvancedEditor()) {
1229
+			return [];
1230
+		}
1231
+		$datetime       = null;
1232
+		$saved_tickets  = [];
1233
+		$event_timezone = $event->get_timezone();
1234
+		$date_formats   = ['Y-m-d', 'h:i a'];
1235
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1236
+			// trim all values to ensure any excess whitespace is removed.
1237
+			$datetime_data                = array_map('trim', $datetime_data);
1238
+			$datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1239
+					? $datetime_data['DTT_EVT_end']
1240
+					: $datetime_data['DTT_EVT_start'];
1241
+			$datetime_values              = [
1242
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1243
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1244
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1245
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1246
+				'DTT_order'     => $row,
1247
+			];
1248
+			// if we have an id then let's get existing object first and then set the new values.
1249
+			//  Otherwise we instantiate a new object for save.
1250
+			if (! empty($datetime_data['DTT_ID'])) {
1251
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1252
+				if (! $datetime instanceof EE_Datetime) {
1253
+					throw new RuntimeException(
1254
+						sprintf(
1255
+							esc_html__(
1256
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1257
+								'event_espresso'
1258
+							),
1259
+							$datetime_data['DTT_ID']
1260
+						)
1261
+					);
1262
+				}
1263
+				$datetime->set_date_format($date_formats[0]);
1264
+				$datetime->set_time_format($date_formats[1]);
1265
+				foreach ($datetime_values as $field => $value) {
1266
+					$datetime->set($field, $value);
1267
+				}
1268
+			} else {
1269
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1270
+			}
1271
+			if (! $datetime instanceof EE_Datetime) {
1272
+				throw new RuntimeException(
1273
+					sprintf(
1274
+						esc_html__(
1275
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1276
+							'event_espresso'
1277
+						),
1278
+						print_r($datetime_values, true)
1279
+					)
1280
+				);
1281
+			}
1282
+			// before going any further make sure our dates are setup correctly
1283
+			// so that the end date is always equal or greater than the start date.
1284
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1285
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1286
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1287
+			}
1288
+			$datetime->save();
1289
+			$event->_add_relation_to($datetime, 'Datetime');
1290
+		}
1291
+		// no datetimes get deleted so we don't do any of that logic here.
1292
+		// update tickets next
1293
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1294
+
1295
+		// set up some default start and end dates in case those are not present in the incoming data
1296
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1297
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1298
+		// use the start date of the first datetime for the end date
1299
+		$first_datetime   = $event->first_datetime();
1300
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1301
+
1302
+		// now process the incoming data
1303
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1304
+			$update_prices = false;
1305
+			$ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1306
+			// trim inputs to ensure any excess whitespace is removed.
1307
+			$ticket_data   = array_map('trim', $ticket_data);
1308
+			$ticket_values = [
1309
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1310
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1311
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1312
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1313
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1314
+					? $ticket_data['TKT_start_date']
1315
+					: $default_start_date,
1316
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1317
+					? $ticket_data['TKT_end_date']
1318
+					: $default_end_date,
1319
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1320
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1321
+					? $ticket_data['TKT_qty']
1322
+					: EE_INF,
1323
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1324
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1325
+					? $ticket_data['TKT_uses']
1326
+					: EE_INF,
1327
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1328
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1329
+				'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1330
+				'TKT_price'       => $ticket_price,
1331
+				'TKT_row'         => $row,
1332
+			];
1333
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1334
+			// which means in turn that the prices will become new prices as well.
1335
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1336
+				$ticket_values['TKT_ID']         = 0;
1337
+				$ticket_values['TKT_is_default'] = 0;
1338
+				$update_prices                   = true;
1339
+			}
1340
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1341
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1342
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1343
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1344
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1345
+			if (! empty($ticket_data['TKT_ID'])) {
1346
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1347
+				if (! $existing_ticket instanceof EE_Ticket) {
1348
+					throw new RuntimeException(
1349
+						sprintf(
1350
+							esc_html__(
1351
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1352
+								'event_espresso'
1353
+							),
1354
+							$ticket_data['TKT_ID']
1355
+						)
1356
+					);
1357
+				}
1358
+				$ticket_sold = $existing_ticket->count_related(
1359
+						'Registration',
1360
+						[
1361
+							[
1362
+								'STS_ID' => [
1363
+									'NOT IN',
1364
+									[EEM_Registration::status_id_incomplete],
1365
+								],
1366
+							],
1367
+						]
1368
+					) > 0;
1369
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1370
+				// if they are different then we create a new ticket (if $ticket_sold)
1371
+				// if they aren't different then we go ahead and modify existing ticket.
1372
+				$create_new_ticket = $ticket_sold
1373
+									 && $ticket_price !== $existing_ticket->price()
1374
+									 && ! $existing_ticket->deleted();
1375
+				$existing_ticket->set_date_format($date_formats[0]);
1376
+				$existing_ticket->set_time_format($date_formats[1]);
1377
+				// set new values
1378
+				foreach ($ticket_values as $field => $value) {
1379
+					if ($field == 'TKT_qty') {
1380
+						$existing_ticket->set_qty($value);
1381
+					} elseif ($field == 'TKT_price') {
1382
+						$existing_ticket->set('TKT_price', $ticket_price);
1383
+					} else {
1384
+						$existing_ticket->set($field, $value);
1385
+					}
1386
+				}
1387
+				$ticket = $existing_ticket;
1388
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1389
+				//  Otherwise we have to create a new ticket.
1390
+				if ($create_new_ticket) {
1391
+					// archive the old ticket first
1392
+					$existing_ticket->set('TKT_deleted', 1);
1393
+					$existing_ticket->save();
1394
+					// make sure this ticket is still recorded in our $saved_tickets
1395
+					// so we don't run it through the regular trash routine.
1396
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1397
+					// create new ticket that's a copy of the existing except,
1398
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1399
+					$new_ticket = clone $existing_ticket;
1400
+					$new_ticket->set('TKT_ID', 0);
1401
+					$new_ticket->set('TKT_deleted', 0);
1402
+					$new_ticket->set('TKT_sold', 0);
1403
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1404
+					$update_prices = true;
1405
+					$ticket        = $new_ticket;
1406
+				}
1407
+			} else {
1408
+				// no TKT_id so a new ticket
1409
+				$ticket_values['TKT_price'] = $ticket_price;
1410
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1411
+				$update_prices              = true;
1412
+			}
1413
+			if (! $ticket instanceof EE_Ticket) {
1414
+				throw new RuntimeException(
1415
+					sprintf(
1416
+						esc_html__(
1417
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1418
+							'event_espresso'
1419
+						),
1420
+						print_r($ticket_values, true)
1421
+					)
1422
+				);
1423
+			}
1424
+			// cap ticket qty by datetime reg limits
1425
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1426
+			// update ticket.
1427
+			$ticket->save();
1428
+			// before going any further make sure our dates are setup correctly
1429
+			// so that the end date is always equal or greater than the start date.
1430
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1431
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1432
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1433
+				$ticket->save();
1434
+			}
1435
+			// initially let's add the ticket to the datetime
1436
+			$datetime->_add_relation_to($ticket, 'Ticket');
1437
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1438
+			// add prices to ticket
1439
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1440
+				? $data['edit_prices'][ $row ]
1441
+				: [];
1442
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1443
+		}
1444
+		// however now we need to handle permanently deleting tickets via the ui.
1445
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1446
+		// However, it does allow for deleting tickets that have no tickets sold,
1447
+		// in which case we want to get rid of permanently because there is no need to save in db.
1448
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1449
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1450
+		foreach ($tickets_removed as $id) {
1451
+			$id = absint($id);
1452
+			// get the ticket for this id
1453
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1454
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1455
+				continue;
1456
+			}
1457
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1458
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1459
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1460
+			foreach ($related_datetimes as $related_datetime) {
1461
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1462
+			}
1463
+			// need to do the same for prices (except these prices can also be deleted because again,
1464
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1465
+			$ticket_to_remove->delete_related_permanently('Price');
1466
+			// finally let's delete this ticket
1467
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1468
+			$ticket_to_remove->delete_permanently();
1469
+		}
1470
+		return [$datetime, $saved_tickets];
1471
+	}
1472
+
1473
+
1474
+	/**
1475
+	 * This attaches a list of given prices to a ticket.
1476
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1477
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1478
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1479
+	 *
1480
+	 * @access  private
1481
+	 * @param array     $prices_data Array of prices from the form.
1482
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1483
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1484
+	 * @return  void
1485
+	 * @throws EE_Error
1486
+	 * @throws ReflectionException
1487
+	 */
1488
+	private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1489
+	{
1490
+		$timezone = $ticket->get_timezone();
1491
+		foreach ($prices_data as $row => $price_data) {
1492
+			$price_values = [
1493
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1494
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1495
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1496
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1497
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1498
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1499
+				'PRC_order'      => $row,
1500
+			];
1501
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1502
+				$price_values['PRC_ID'] = 0;
1503
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1504
+			} else {
1505
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1506
+				// update this price with new values
1507
+				foreach ($price_values as $field => $new_price) {
1508
+					$price->set($field, $new_price);
1509
+				}
1510
+			}
1511
+			if (! $price instanceof EE_Price) {
1512
+				throw new RuntimeException(
1513
+					sprintf(
1514
+						esc_html__(
1515
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1516
+							'event_espresso'
1517
+						),
1518
+						print_r($price_values, true)
1519
+					)
1520
+				);
1521
+			}
1522
+			$price->save();
1523
+			$ticket->_add_relation_to($price, 'Price');
1524
+		}
1525
+	}
1526
+
1527
+
1528
+	/**
1529
+	 * Add in our autosave ajax handlers
1530
+	 */
1531
+	protected function _ee_autosave_create_new()
1532
+	{
1533
+	}
1534
+
1535
+
1536
+	/**
1537
+	 * More autosave handlers.
1538
+	 */
1539
+	protected function _ee_autosave_edit()
1540
+	{
1541
+	}
1542
+
1543
+
1544
+	/**
1545
+	 * @throws EE_Error
1546
+	 * @throws ReflectionException
1547
+	 */
1548
+	private function _generate_publish_box_extra_content()
1549
+	{
1550
+		// load formatter helper
1551
+		// args for getting related registrations
1552
+		$approved_query_args        = [
1553
+			[
1554
+				'REG_deleted' => 0,
1555
+				'STS_ID'      => EEM_Registration::status_id_approved,
1556
+			],
1557
+		];
1558
+		$not_approved_query_args    = [
1559
+			[
1560
+				'REG_deleted' => 0,
1561
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1562
+			],
1563
+		];
1564
+		$pending_payment_query_args = [
1565
+			[
1566
+				'REG_deleted' => 0,
1567
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1568
+			],
1569
+		];
1570
+		// publish box
1571
+		$publish_box_extra_args = [
1572
+			'view_approved_reg_url'        => add_query_arg(
1573
+				[
1574
+					'action'      => 'default',
1575
+					'event_id'    => $this->_cpt_model_obj->ID(),
1576
+					'_reg_status' => EEM_Registration::status_id_approved,
1577
+					'use_filters' => true,
1578
+				],
1579
+				REG_ADMIN_URL
1580
+			),
1581
+			'view_not_approved_reg_url'    => add_query_arg(
1582
+				[
1583
+					'action'      => 'default',
1584
+					'event_id'    => $this->_cpt_model_obj->ID(),
1585
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1586
+					'use_filters' => true,
1587
+				],
1588
+				REG_ADMIN_URL
1589
+			),
1590
+			'view_pending_payment_reg_url' => add_query_arg(
1591
+				[
1592
+					'action'      => 'default',
1593
+					'event_id'    => $this->_cpt_model_obj->ID(),
1594
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1595
+					'use_filters' => true,
1596
+				],
1597
+				REG_ADMIN_URL
1598
+			),
1599
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1600
+				'Registration',
1601
+				$approved_query_args
1602
+			),
1603
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1604
+				'Registration',
1605
+				$not_approved_query_args
1606
+			),
1607
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1608
+				'Registration',
1609
+				$pending_payment_query_args
1610
+			),
1611
+			'misc_pub_section_class'       => apply_filters(
1612
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1613
+				'misc-pub-section'
1614
+			),
1615
+		];
1616
+		ob_start();
1617
+		do_action(
1618
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1619
+			$this->_cpt_model_obj
1620
+		);
1621
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1622
+		// load template
1623
+		EEH_Template::display_template(
1624
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1625
+			$publish_box_extra_args
1626
+		);
1627
+	}
1628
+
1629
+
1630
+	/**
1631
+	 * @return EE_Event
1632
+	 */
1633
+	public function get_event_object()
1634
+	{
1635
+		return $this->_cpt_model_obj;
1636
+	}
1637
+
1638
+
1639
+
1640
+
1641
+	/** METABOXES * */
1642
+	/**
1643
+	 * _register_event_editor_meta_boxes
1644
+	 * add all metaboxes related to the event_editor
1645
+	 *
1646
+	 * @return void
1647
+	 * @throws EE_Error
1648
+	 * @throws ReflectionException
1649
+	 */
1650
+	protected function _register_event_editor_meta_boxes()
1651
+	{
1652
+		$this->verify_cpt_object();
1653
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1654
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1655
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1656
+			$this->addMetaBox(
1657
+				'espresso_event_editor_event_options',
1658
+				esc_html__('Event Registration Options', 'event_espresso'),
1659
+				[$this, 'registration_options_meta_box'],
1660
+				$this->page_slug,
1661
+				'side'
1662
+			);
1663
+		}
1664
+		if (! $use_advanced_editor) {
1665
+			$this->addMetaBox(
1666
+				'espresso_event_editor_tickets',
1667
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1668
+				[$this, 'ticket_metabox'],
1669
+				$this->page_slug,
1670
+				'normal',
1671
+				'high'
1672
+			);
1673
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1674
+			add_action(
1675
+				'add_meta_boxes_espresso_events',
1676
+				function () {
1677
+					global $current_screen;
1678
+					remove_meta_box('authordiv', $current_screen, 'normal');
1679
+				},
1680
+				99
1681
+			);
1682
+		}
1683
+		// NOTE: if you're looking for other metaboxes in here,
1684
+		// where a metabox has a related management page in the admin
1685
+		// you will find it setup in the related management page's "_Hooks" file.
1686
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1687
+	}
1688
+
1689
+
1690
+	/**
1691
+	 * @throws DomainException
1692
+	 * @throws EE_Error
1693
+	 * @throws ReflectionException
1694
+	 */
1695
+	public function ticket_metabox()
1696
+	{
1697
+		$existing_datetime_ids = $existing_ticket_ids = [];
1698
+		// defaults for template args
1699
+		$template_args = [
1700
+			'ticket_rows'       => '',
1701
+			'total_ticket_rows' => 1,
1702
+			'trash_icon'        => 'dashicons dashicons-lock',
1703
+			'disabled'          => '',
1704
+		];
1705
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1706
+		/**
1707
+		 * 1. Start with retrieving Datetimes
1708
+		 * 2. Fore each datetime get related tickets
1709
+		 * 3. For each ticket get related prices
1710
+		 */
1711
+		/** @var EEM_Datetime $datetime_model */
1712
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1713
+		/** @var EEM_Ticket $datetime_model */
1714
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1715
+		$times        = $datetime_model->get_all_event_dates($event_id);
1716
+		/** @type EE_Datetime $first_datetime */
1717
+		$first_datetime = reset($times);
1718
+		// do we get related tickets?
1719
+		if (
1720
+			$first_datetime instanceof EE_Datetime
1721
+			&& $first_datetime->ID() !== 0
1722
+		) {
1723
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1724
+			$template_args['time']   = $first_datetime;
1725
+			$related_tickets         = $first_datetime->tickets(
1726
+				[
1727
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1728
+					'default_where_conditions' => 'none',
1729
+				]
1730
+			);
1731
+			if (! empty($related_tickets)) {
1732
+				$template_args['total_ticket_rows'] = count($related_tickets);
1733
+				$row                                = 0;
1734
+				foreach ($related_tickets as $ticket) {
1735
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1736
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1737
+					$row++;
1738
+				}
1739
+			} else {
1740
+				$template_args['total_ticket_rows'] = 1;
1741
+				/** @type EE_Ticket $ticket */
1742
+				$ticket                       = $ticket_model->create_default_object();
1743
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1744
+			}
1745
+		} else {
1746
+			$template_args['time'] = $times[0];
1747
+			/** @type EE_Ticket[] $tickets */
1748
+			$tickets                      = $ticket_model->get_all_default_tickets();
1749
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1750
+			// NOTE: we're just sending the first default row
1751
+			// (decaf can't manage default tickets so this should be sufficient);
1752
+		}
1753
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1754
+			'event_editor_event_datetimes_help_tab'
1755
+		);
1756
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1757
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1758
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1759
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1760
+			$ticket_model->create_default_object(),
1761
+			true
1762
+		);
1763
+		$template                                  = apply_filters(
1764
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1765
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1766
+		);
1767
+		EEH_Template::display_template($template, $template_args);
1768
+	}
1769
+
1770
+
1771
+	/**
1772
+	 * Setup an individual ticket form for the decaf event editor page
1773
+	 *
1774
+	 * @access private
1775
+	 * @param EE_Ticket $ticket   the ticket object
1776
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1777
+	 * @param int       $row
1778
+	 * @return string generated html for the ticket row.
1779
+	 * @throws EE_Error
1780
+	 * @throws ReflectionException
1781
+	 */
1782
+	private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1783
+	{
1784
+		$template_args = [
1785
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1786
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1787
+				: '',
1788
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1789
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1790
+			'TKT_name'            => $ticket->get('TKT_name'),
1791
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1792
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1793
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1794
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1795
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1796
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1797
+			'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1798
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1799
+				? 'dashicons dashicons-post-trash clickable'
1800
+				: 'dashicons dashicons-lock',
1801
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1802
+				: ' disabled=disabled',
1803
+		];
1804
+		$price         = $ticket->ID() !== 0
1805
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1806
+			: null;
1807
+		$price         = $price instanceof EE_Price
1808
+			? $price
1809
+			: EEM_Price::instance()->create_default_object();
1810
+		$price_args    = [
1811
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1812
+			'PRC_amount'            => $price->get('PRC_amount'),
1813
+			'PRT_ID'                => $price->get('PRT_ID'),
1814
+			'PRC_ID'                => $price->get('PRC_ID'),
1815
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1816
+		];
1817
+		// make sure we have default start and end dates if skeleton
1818
+		// handle rows that should NOT be empty
1819
+		if (empty($template_args['TKT_start_date'])) {
1820
+			// if empty then the start date will be now.
1821
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1822
+		}
1823
+		if (empty($template_args['TKT_end_date'])) {
1824
+			// get the earliest datetime (if present);
1825
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1826
+				? $this->_cpt_model_obj->get_first_related(
1827
+					'Datetime',
1828
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1829
+				)
1830
+				: null;
1831
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1832
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1833
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1834
+		}
1835
+		$template_args = array_merge($template_args, $price_args);
1836
+		$template      = apply_filters(
1837
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1838
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1839
+			$ticket
1840
+		);
1841
+		return EEH_Template::display_template($template, $template_args, true);
1842
+	}
1843
+
1844
+
1845
+	/**
1846
+	 * @throws EE_Error
1847
+	 * @throws ReflectionException
1848
+	 */
1849
+	public function registration_options_meta_box()
1850
+	{
1851
+		$yes_no_values             = [
1852
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1853
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1854
+		];
1855
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1856
+			[
1857
+				EEM_Registration::status_id_cancelled,
1858
+				EEM_Registration::status_id_declined,
1859
+				EEM_Registration::status_id_incomplete,
1860
+			],
1861
+			true
1862
+		);
1863
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1864
+		$template_args['_event']                          = $this->_cpt_model_obj;
1865
+		$template_args['event']                           = $this->_cpt_model_obj;
1866
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1867
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1868
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1869
+			'default_reg_status',
1870
+			$default_reg_status_values,
1871
+			$this->_cpt_model_obj->default_registration_status(),
1872
+			'',
1873
+			'ee-input-width--reg',
1874
+			false
1875
+		);
1876
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1877
+			'display_desc',
1878
+			$yes_no_values,
1879
+			$this->_cpt_model_obj->display_description()
1880
+		);
1881
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1882
+			'display_ticket_selector',
1883
+			$yes_no_values,
1884
+			$this->_cpt_model_obj->display_ticket_selector(),
1885
+			'',
1886
+			'ee-input-width--small',
1887
+			false
1888
+		);
1889
+		$template_args['additional_registration_options'] = apply_filters(
1890
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1891
+			'',
1892
+			$template_args,
1893
+			$yes_no_values,
1894
+			$default_reg_status_values
1895
+		);
1896
+		EEH_Template::display_template(
1897
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1898
+			$template_args
1899
+		);
1900
+	}
1901
+
1902
+
1903
+	/**
1904
+	 * _get_events()
1905
+	 * This method simply returns all the events (for the given _view and paging)
1906
+	 *
1907
+	 * @access public
1908
+	 * @param int  $per_page     count of items per page (20 default);
1909
+	 * @param int  $current_page what is the current page being viewed.
1910
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1911
+	 *                           If FALSE then we return an array of event objects
1912
+	 *                           that match the given _view and paging parameters.
1913
+	 * @return array|int         an array of event objects or a count of them.
1914
+	 * @throws Exception
1915
+	 */
1916
+	public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1917
+	{
1918
+		$EEM_Event   = $this->_event_model();
1919
+		$offset      = ($current_page - 1) * $per_page;
1920
+		$limit       = $count ? null : $offset . ',' . $per_page;
1921
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1922
+		$order       = $this->request->getRequestParam('order', 'DESC');
1923
+		$month_range = $this->request->getRequestParam('month_range');
1924
+		if ($month_range) {
1925
+			$pieces = explode(' ', $month_range, 3);
1926
+			// simulate the FIRST day of the month, that fixes issues for months like February
1927
+			// where PHP doesn't know what to assume for date.
1928
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1929
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1930
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1931
+		}
1932
+		$where  = [];
1933
+		$status = $this->request->getRequestParam('status');
1934
+		// determine what post_status our condition will have for the query.
1935
+		switch ($status) {
1936
+			case 'month':
1937
+			case 'today':
1938
+			case null:
1939
+			case 'all':
1940
+				break;
1941
+			case 'draft':
1942
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1943
+				break;
1944
+			default:
1945
+				$where['status'] = $status;
1946
+		}
1947
+		// categories? The default for all categories is -1
1948
+		$category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1949
+		if ($category !== -1) {
1950
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1951
+			$where['Term_Taxonomy.term_id']  = $category;
1952
+		}
1953
+		// date where conditions
1954
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1955
+		if ($month_range) {
1956
+			$DateTime = new DateTime(
1957
+				$year_r . '-' . $month_r . '-01 00:00:00',
1958
+				new DateTimeZone('UTC')
1959
+			);
1960
+			$start    = $DateTime->getTimestamp();
1961
+			// set the datetime to be the end of the month
1962
+			$DateTime->setDate(
1963
+				$year_r,
1964
+				$month_r,
1965
+				$DateTime->format('t')
1966
+			)->setTime(23, 59, 59);
1967
+			$end                             = $DateTime->getTimestamp();
1968
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1969
+		} elseif ($status === 'today') {
1970
+			$DateTime                        =
1971
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1972
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1973
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1974
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1975
+		} elseif ($status === 'month') {
1976
+			$now                             = date('Y-m-01');
1977
+			$DateTime                        =
1978
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1979
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1980
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1981
+														->setTime(23, 59, 59)
1982
+														->format(implode(' ', $start_formats));
1983
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1984
+		}
1985
+		if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1986
+			$where['EVT_wp_user'] = get_current_user_id();
1987
+		} else {
1988
+			if (! isset($where['status'])) {
1989
+				if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1990
+					$where['OR'] = [
1991
+						'status*restrict_private' => ['!=', 'private'],
1992
+						'AND'                     => [
1993
+							'status*inclusive' => ['=', 'private'],
1994
+							'EVT_wp_user'      => get_current_user_id(),
1995
+						],
1996
+					];
1997
+				}
1998
+			}
1999
+		}
2000
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2001
+		if (
2002
+			$wp_user
2003
+			&& $wp_user !== get_current_user_id()
2004
+			&& $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2005
+		) {
2006
+			$where['EVT_wp_user'] = $wp_user;
2007
+		}
2008
+		// search query handling
2009
+		$search_term = $this->request->getRequestParam('s');
2010
+		if ($search_term) {
2011
+			$search_term = '%' . $search_term . '%';
2012
+			$where['OR'] = [
2013
+				'EVT_name'       => ['LIKE', $search_term],
2014
+				'EVT_desc'       => ['LIKE', $search_term],
2015
+				'EVT_short_desc' => ['LIKE', $search_term],
2016
+			];
2017
+		}
2018
+		// filter events by venue.
2019
+		$venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2020
+		if ($venue) {
2021
+			$where['Venue.VNU_ID'] = $venue;
2022
+		}
2023
+		$request_params = $this->request->requestParams();
2024
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2025
+		$query_params   = apply_filters(
2026
+			'FHEE__Events_Admin_Page__get_events__query_params',
2027
+			[
2028
+				$where,
2029
+				'limit'    => $limit,
2030
+				'order_by' => $orderby,
2031
+				'order'    => $order,
2032
+				'group_by' => 'EVT_ID',
2033
+			],
2034
+			$request_params
2035
+		);
2036
+
2037
+		// let's first check if we have special requests coming in.
2038
+		$active_status = $this->request->getRequestParam('active_status');
2039
+		if ($active_status) {
2040
+			switch ($active_status) {
2041
+				case 'upcoming':
2042
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2043
+				case 'expired':
2044
+					return $EEM_Event->get_expired_events($query_params, $count);
2045
+				case 'active':
2046
+					return $EEM_Event->get_active_events($query_params, $count);
2047
+				case 'inactive':
2048
+					return $EEM_Event->get_inactive_events($query_params, $count);
2049
+			}
2050
+		}
2051
+
2052
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2053
+	}
2054
+
2055
+
2056
+	/**
2057
+	 * handling for WordPress CPT actions (trash, restore, delete)
2058
+	 *
2059
+	 * @param string $post_id
2060
+	 * @throws EE_Error
2061
+	 * @throws ReflectionException
2062
+	 */
2063
+	public function trash_cpt_item($post_id)
2064
+	{
2065
+		$this->request->setRequestParam('EVT_ID', $post_id);
2066
+		$this->_trash_or_restore_event('trash', false);
2067
+	}
2068
+
2069
+
2070
+	/**
2071
+	 * @param string $post_id
2072
+	 * @throws EE_Error
2073
+	 * @throws ReflectionException
2074
+	 */
2075
+	public function restore_cpt_item($post_id)
2076
+	{
2077
+		$this->request->setRequestParam('EVT_ID', $post_id);
2078
+		$this->_trash_or_restore_event('draft', false);
2079
+	}
2080
+
2081
+
2082
+	/**
2083
+	 * @param string $post_id
2084
+	 * @throws EE_Error
2085
+	 * @throws EE_Error
2086
+	 */
2087
+	public function delete_cpt_item($post_id)
2088
+	{
2089
+		throw new EE_Error(
2090
+			esc_html__(
2091
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2092
+				'event_espresso'
2093
+			)
2094
+		);
2095
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2096
+		// $this->_delete_event();
2097
+	}
2098
+
2099
+
2100
+	/**
2101
+	 * _trash_or_restore_event
2102
+	 *
2103
+	 * @access protected
2104
+	 * @param string $event_status
2105
+	 * @param bool   $redirect_after
2106
+	 * @throws EE_Error
2107
+	 * @throws EE_Error
2108
+	 * @throws ReflectionException
2109
+	 */
2110
+	protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2111
+	{
2112
+		// loop thru events
2113
+		if ($this->EVT_ID) {
2114
+			// clean status
2115
+			$event_status = sanitize_key($event_status);
2116
+			// grab status
2117
+			if (! empty($event_status)) {
2118
+				$success = $this->_change_event_status($this->EVT_ID, $event_status);
2119
+			} else {
2120
+				$success = false;
2121
+				$msg     = esc_html__(
2122
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2123
+					'event_espresso'
2124
+				);
2125
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2126
+			}
2127
+		} else {
2128
+			$success = false;
2129
+			$msg     = esc_html__(
2130
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2131
+				'event_espresso'
2132
+			);
2133
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2134
+		}
2135
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2136
+		if ($redirect_after) {
2137
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2138
+		}
2139
+	}
2140
+
2141
+
2142
+	/**
2143
+	 * _trash_or_restore_events
2144
+	 *
2145
+	 * @access protected
2146
+	 * @param string $event_status
2147
+	 * @return void
2148
+	 * @throws EE_Error
2149
+	 * @throws EE_Error
2150
+	 * @throws ReflectionException
2151
+	 */
2152
+	protected function _trash_or_restore_events(string $event_status = 'trash')
2153
+	{
2154
+		// clean status
2155
+		$event_status = sanitize_key($event_status);
2156
+		// grab status
2157
+		if (! empty($event_status)) {
2158
+			$success = true;
2159
+			// determine the event id and set to array.
2160
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2161
+			// loop thru events
2162
+			foreach ($EVT_IDs as $EVT_ID) {
2163
+				if ($EVT_ID = absint($EVT_ID)) {
2164
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2165
+					$success = $results !== false ? $success : false;
2166
+				} else {
2167
+					$msg = sprintf(
2168
+						esc_html__(
2169
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2170
+							'event_espresso'
2171
+						),
2172
+						$EVT_ID
2173
+					);
2174
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2175
+					$success = false;
2176
+				}
2177
+			}
2178
+		} else {
2179
+			$success = false;
2180
+			$msg     = esc_html__(
2181
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2182
+				'event_espresso'
2183
+			);
2184
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
+		}
2186
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2187
+		$success = $success ? 2 : false;
2188
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2189
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2190
+	}
2191
+
2192
+
2193
+	/**
2194
+	 * @param int    $EVT_ID
2195
+	 * @param string $event_status
2196
+	 * @return bool
2197
+	 * @throws EE_Error
2198
+	 * @throws ReflectionException
2199
+	 */
2200
+	private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2201
+	{
2202
+		// grab event id
2203
+		if (! $EVT_ID) {
2204
+			$msg = esc_html__(
2205
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2206
+				'event_espresso'
2207
+			);
2208
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2209
+			return false;
2210
+		}
2211
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2212
+		// clean status
2213
+		$event_status = sanitize_key($event_status);
2214
+		// grab status
2215
+		if (empty($event_status)) {
2216
+			$msg = esc_html__(
2217
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2218
+				'event_espresso'
2219
+			);
2220
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2221
+			return false;
2222
+		}
2223
+		// was event trashed or restored ?
2224
+		switch ($event_status) {
2225
+			case 'draft':
2226
+				$action = 'restored from the trash';
2227
+				$hook   = 'AHEE_event_restored_from_trash';
2228
+				break;
2229
+			case 'trash':
2230
+				$action = 'moved to the trash';
2231
+				$hook   = 'AHEE_event_moved_to_trash';
2232
+				break;
2233
+			default:
2234
+				$action = 'updated';
2235
+				$hook   = false;
2236
+		}
2237
+		// use class to change status
2238
+		$this->_cpt_model_obj->set_status($event_status);
2239
+		$success = $this->_cpt_model_obj->save();
2240
+		if (! $success) {
2241
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2242
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2243
+			return false;
2244
+		}
2245
+		if ($hook) {
2246
+			do_action($hook);
2247
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2248
+			// because events side step that and it otherwise won't get called
2249
+			do_action(
2250
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2251
+				$this->_cpt_model_obj,
2252
+				$hook === 'AHEE_event_moved_to_trash',
2253
+				$success
2254
+			);
2255
+		}
2256
+		return true;
2257
+	}
2258
+
2259
+
2260
+	/**
2261
+	 * @param array $event_ids
2262
+	 * @return array
2263
+	 * @since   4.10.23.p
2264
+	 */
2265
+	private function cleanEventIds(array $event_ids): array
2266
+	{
2267
+		return array_map('absint', $event_ids);
2268
+	}
2269
+
2270
+
2271
+	/**
2272
+	 * @return array
2273
+	 * @since   4.10.23.p
2274
+	 */
2275
+	private function getEventIdsFromRequest(): array
2276
+	{
2277
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2278
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2279
+		} else {
2280
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2281
+		}
2282
+	}
2283
+
2284
+
2285
+	/**
2286
+	 * @param bool $preview_delete
2287
+	 * @throws EE_Error
2288
+	 * @throws ReflectionException
2289
+	 */
2290
+	protected function _delete_event(bool $preview_delete = true)
2291
+	{
2292
+		$this->_delete_events($preview_delete);
2293
+	}
2294
+
2295
+
2296
+	/**
2297
+	 * Gets the tree traversal batch persister.
2298
+	 *
2299
+	 * @return NodeGroupDao
2300
+	 * @throws InvalidArgumentException
2301
+	 * @throws InvalidDataTypeException
2302
+	 * @throws InvalidInterfaceException
2303
+	 * @since 4.10.12.p
2304
+	 */
2305
+	protected function getModelObjNodeGroupPersister(): NodeGroupDao
2306
+	{
2307
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2308
+			$this->model_obj_node_group_persister =
2309
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2310
+		}
2311
+		return $this->model_obj_node_group_persister;
2312
+	}
2313
+
2314
+
2315
+	/**
2316
+	 * @param bool $preview_delete
2317
+	 * @return void
2318
+	 * @throws EE_Error
2319
+	 * @throws ReflectionException
2320
+	 */
2321
+	protected function _delete_events(bool $preview_delete = true)
2322
+	{
2323
+		$event_ids = $this->getEventIdsFromRequest();
2324
+		if ($preview_delete) {
2325
+			$this->generateDeletionPreview($event_ids);
2326
+		} else {
2327
+			foreach ($event_ids as $event_id) {
2328
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2329
+				if ($event instanceof EE_Event) {
2330
+					$event->delete_permanently();
2331
+				}
2332
+			}
2333
+		}
2334
+	}
2335
+
2336
+
2337
+	/**
2338
+	 * @param array $event_ids
2339
+	 */
2340
+	protected function generateDeletionPreview(array $event_ids)
2341
+	{
2342
+		$event_ids = $this->cleanEventIds($event_ids);
2343
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2344
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2345
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2346
+			[
2347
+				'action'            => 'preview_deletion',
2348
+				'deletion_job_code' => $deletion_job_code,
2349
+			],
2350
+			$this->_admin_base_url
2351
+		);
2352
+		EEH_URL::safeRedirectAndExit(
2353
+			EE_Admin_Page::add_query_args_and_nonce(
2354
+				[
2355
+					'page'              => EED_Batch::PAGE_SLUG,
2356
+					'batch'             => EED_Batch::batch_job,
2357
+					'EVT_IDs'           => $event_ids,
2358
+					'deletion_job_code' => $deletion_job_code,
2359
+					'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2360
+					'return_url'        => urlencode($return_url),
2361
+				],
2362
+				admin_url()
2363
+			)
2364
+		);
2365
+	}
2366
+
2367
+
2368
+	/**
2369
+	 * Checks for a POST submission
2370
+	 *
2371
+	 * @since 4.10.12.p
2372
+	 */
2373
+	protected function confirmDeletion()
2374
+	{
2375
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2376
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2377
+		);
2378
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2379
+	}
2380
+
2381
+
2382
+	/**
2383
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2384
+	 *
2385
+	 * @throws EE_Error
2386
+	 * @since 4.10.12.p
2387
+	 */
2388
+	protected function previewDeletion()
2389
+	{
2390
+		$preview_deletion_logic = $this->getLoader()->getShared(
2391
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2392
+		);
2393
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2394
+		$this->display_admin_page_with_no_sidebar();
2395
+	}
2396
+
2397
+
2398
+	/**
2399
+	 * get total number of events
2400
+	 *
2401
+	 * @access public
2402
+	 * @return int
2403
+	 * @throws EE_Error
2404
+	 * @throws EE_Error
2405
+	 * @throws ReflectionException
2406
+	 */
2407
+	public function total_events(): int
2408
+	{
2409
+		return EEM_Event::instance()->count(
2410
+			['caps' => 'read_admin'],
2411
+			'EVT_ID',
2412
+			true
2413
+		);
2414
+	}
2415
+
2416
+
2417
+	/**
2418
+	 * get total number of draft events
2419
+	 *
2420
+	 * @access public
2421
+	 * @return int
2422
+	 * @throws EE_Error
2423
+	 * @throws EE_Error
2424
+	 * @throws ReflectionException
2425
+	 */
2426
+	public function total_events_draft(): int
2427
+	{
2428
+		return EEM_Event::instance()->count(
2429
+			[
2430
+				['status' => ['IN', ['draft', 'auto-draft']]],
2431
+				'caps' => 'read_admin',
2432
+			],
2433
+			'EVT_ID',
2434
+			true
2435
+		);
2436
+	}
2437
+
2438
+
2439
+	/**
2440
+	 * get total number of trashed events
2441
+	 *
2442
+	 * @access public
2443
+	 * @return int
2444
+	 * @throws EE_Error
2445
+	 * @throws EE_Error
2446
+	 * @throws ReflectionException
2447
+	 */
2448
+	public function total_trashed_events(): int
2449
+	{
2450
+		return EEM_Event::instance()->count(
2451
+			[
2452
+				['status' => 'trash'],
2453
+				'caps' => 'read_admin',
2454
+			],
2455
+			'EVT_ID',
2456
+			true
2457
+		);
2458
+	}
2459
+
2460
+
2461
+	/**
2462
+	 *    _default_event_settings
2463
+	 *    This generates the Default Settings Tab
2464
+	 *
2465
+	 * @return void
2466
+	 * @throws DomainException
2467
+	 * @throws EE_Error
2468
+	 * @throws InvalidArgumentException
2469
+	 * @throws InvalidDataTypeException
2470
+	 * @throws InvalidInterfaceException
2471
+	 * @throws ReflectionException
2472
+	 */
2473
+	protected function _default_event_settings()
2474
+	{
2475
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2476
+		$this->_set_publish_post_box_vars();
2477
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
2478
+			$this->_default_event_settings_form()->get_html(),
2479
+			'',
2480
+			'padding'
2481
+		);
2482
+		$this->display_admin_page_with_sidebar();
2483
+	}
2484
+
2485
+
2486
+	/**
2487
+	 * Return the form for event settings.
2488
+	 *
2489
+	 * @return EE_Form_Section_Proper
2490
+	 * @throws EE_Error
2491
+	 * @throws ReflectionException
2492
+	 */
2493
+	protected function _default_event_settings_form(): EE_Form_Section_Proper
2494
+	{
2495
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2496
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2497
+		// exclude
2498
+			[
2499
+				EEM_Registration::status_id_cancelled,
2500
+				EEM_Registration::status_id_declined,
2501
+				EEM_Registration::status_id_incomplete,
2502
+				EEM_Registration::status_id_wait_list,
2503
+			],
2504
+			true
2505
+		);
2506
+		// setup Advanced Editor ???
2507
+		if (
2508
+			$this->raw_req_action === 'default_event_settings'
2509
+			|| $this->raw_req_action === 'update_default_event_settings'
2510
+		) {
2511
+			$this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2512
+		}
2513
+		return new EE_Form_Section_Proper(
2514
+			[
2515
+				'name'            => 'update_default_event_settings',
2516
+				'html_id'         => 'update_default_event_settings',
2517
+				'html_class'      => 'form-table',
2518
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2519
+				'subsections'     => apply_filters(
2520
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2521
+					[
2522
+						'defaults_section_header' => new EE_Form_Section_HTML(
2523
+							EEH_HTML::h2(
2524
+								esc_html__('Default Settings', 'event_espresso'),
2525
+								'',
2526
+								'ee-admin-settings-hdr'
2527
+							)
2528
+						),
2529
+						'default_reg_status'      => new EE_Select_Input(
2530
+							$registration_stati_for_selection,
2531
+							[
2532
+								'default'         => isset($registration_config->default_STS_ID)
2533
+													 && array_key_exists(
2534
+														 $registration_config->default_STS_ID,
2535
+														 $registration_stati_for_selection
2536
+													 )
2537
+									? sanitize_text_field($registration_config->default_STS_ID)
2538
+									: EEM_Registration::status_id_pending_payment,
2539
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2540
+													 . EEH_Template::get_help_tab_link(
2541
+										'default_settings_status_help_tab'
2542
+									),
2543
+								'html_help_text'  => esc_html__(
2544
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2545
+									'event_espresso'
2546
+								),
2547
+							]
2548
+						),
2549
+						'default_max_tickets'     => new EE_Integer_Input(
2550
+							[
2551
+								'default'         => $registration_config->default_maximum_number_of_tickets
2552
+													 ?? EEM_Event::get_default_additional_limit(),
2553
+								'html_label_text' => esc_html__(
2554
+														 'Default Maximum Tickets Allowed Per Order:',
2555
+														 'event_espresso'
2556
+													 )
2557
+													 . EEH_Template::get_help_tab_link(
2558
+										'default_maximum_tickets_help_tab"'
2559
+									),
2560
+								'html_help_text'  => esc_html__(
2561
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2562
+									'event_espresso'
2563
+								),
2564
+							]
2565
+						),
2566
+					]
2567
+				),
2568
+			]
2569
+		);
2570
+	}
2571
+
2572
+
2573
+	/**
2574
+	 * @return void
2575
+	 * @throws EE_Error
2576
+	 * @throws InvalidArgumentException
2577
+	 * @throws InvalidDataTypeException
2578
+	 * @throws InvalidInterfaceException
2579
+	 * @throws ReflectionException
2580
+	 */
2581
+	protected function _update_default_event_settings()
2582
+	{
2583
+		$form = $this->_default_event_settings_form();
2584
+		if ($form->was_submitted()) {
2585
+			$form->receive_form_submission();
2586
+			if ($form->is_valid()) {
2587
+				$registration_config = EE_Registry::instance()->CFG->registration;
2588
+				$valid_data          = $form->valid_data();
2589
+				if (isset($valid_data['default_reg_status'])) {
2590
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2591
+				}
2592
+				if (isset($valid_data['default_max_tickets'])) {
2593
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2594
+				}
2595
+				do_action(
2596
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2597
+					$valid_data,
2598
+					EE_Registry::instance()->CFG,
2599
+					$this
2600
+				);
2601
+				// update because data was valid!
2602
+				EE_Registry::instance()->CFG->update_espresso_config();
2603
+				EE_Error::overwrite_success();
2604
+				EE_Error::add_success(
2605
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2606
+				);
2607
+			}
2608
+		}
2609
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2610
+	}
2611
+
2612
+
2613
+	/*************        Templates        *************
1773 2614
      *
1774
-     * @access private
1775
-     * @param EE_Ticket $ticket   the ticket object
1776
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1777
-     * @param int       $row
1778
-     * @return string generated html for the ticket row.
1779
-     * @throws EE_Error
1780
-     * @throws ReflectionException
1781
-     */
1782
-    private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1783
-    {
1784
-        $template_args = [
1785
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1786
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1787
-                : '',
1788
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1789
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1790
-            'TKT_name'            => $ticket->get('TKT_name'),
1791
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1792
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1793
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1794
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1795
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1796
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1797
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1798
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1799
-                ? 'dashicons dashicons-post-trash clickable'
1800
-                : 'dashicons dashicons-lock',
1801
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1802
-                : ' disabled=disabled',
1803
-        ];
1804
-        $price         = $ticket->ID() !== 0
1805
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1806
-            : null;
1807
-        $price         = $price instanceof EE_Price
1808
-            ? $price
1809
-            : EEM_Price::instance()->create_default_object();
1810
-        $price_args    = [
1811
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1812
-            'PRC_amount'            => $price->get('PRC_amount'),
1813
-            'PRT_ID'                => $price->get('PRT_ID'),
1814
-            'PRC_ID'                => $price->get('PRC_ID'),
1815
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1816
-        ];
1817
-        // make sure we have default start and end dates if skeleton
1818
-        // handle rows that should NOT be empty
1819
-        if (empty($template_args['TKT_start_date'])) {
1820
-            // if empty then the start date will be now.
1821
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1822
-        }
1823
-        if (empty($template_args['TKT_end_date'])) {
1824
-            // get the earliest datetime (if present);
1825
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1826
-                ? $this->_cpt_model_obj->get_first_related(
1827
-                    'Datetime',
1828
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1829
-                )
1830
-                : null;
1831
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1832
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1833
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1834
-        }
1835
-        $template_args = array_merge($template_args, $price_args);
1836
-        $template      = apply_filters(
1837
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1838
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1839
-            $ticket
1840
-        );
1841
-        return EEH_Template::display_template($template, $template_args, true);
1842
-    }
1843
-
1844
-
1845
-    /**
1846
-     * @throws EE_Error
1847
-     * @throws ReflectionException
1848
-     */
1849
-    public function registration_options_meta_box()
1850
-    {
1851
-        $yes_no_values             = [
1852
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1853
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1854
-        ];
1855
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1856
-            [
1857
-                EEM_Registration::status_id_cancelled,
1858
-                EEM_Registration::status_id_declined,
1859
-                EEM_Registration::status_id_incomplete,
1860
-            ],
1861
-            true
1862
-        );
1863
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1864
-        $template_args['_event']                          = $this->_cpt_model_obj;
1865
-        $template_args['event']                           = $this->_cpt_model_obj;
1866
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1867
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1868
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1869
-            'default_reg_status',
1870
-            $default_reg_status_values,
1871
-            $this->_cpt_model_obj->default_registration_status(),
1872
-            '',
1873
-            'ee-input-width--reg',
1874
-            false
1875
-        );
1876
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1877
-            'display_desc',
1878
-            $yes_no_values,
1879
-            $this->_cpt_model_obj->display_description()
1880
-        );
1881
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1882
-            'display_ticket_selector',
1883
-            $yes_no_values,
1884
-            $this->_cpt_model_obj->display_ticket_selector(),
1885
-            '',
1886
-            'ee-input-width--small',
1887
-            false
1888
-        );
1889
-        $template_args['additional_registration_options'] = apply_filters(
1890
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1891
-            '',
1892
-            $template_args,
1893
-            $yes_no_values,
1894
-            $default_reg_status_values
1895
-        );
1896
-        EEH_Template::display_template(
1897
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1898
-            $template_args
1899
-        );
1900
-    }
1901
-
1902
-
1903
-    /**
1904
-     * _get_events()
1905
-     * This method simply returns all the events (for the given _view and paging)
1906
-     *
1907
-     * @access public
1908
-     * @param int  $per_page     count of items per page (20 default);
1909
-     * @param int  $current_page what is the current page being viewed.
1910
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1911
-     *                           If FALSE then we return an array of event objects
1912
-     *                           that match the given _view and paging parameters.
1913
-     * @return array|int         an array of event objects or a count of them.
1914
-     * @throws Exception
1915
-     */
1916
-    public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1917
-    {
1918
-        $EEM_Event   = $this->_event_model();
1919
-        $offset      = ($current_page - 1) * $per_page;
1920
-        $limit       = $count ? null : $offset . ',' . $per_page;
1921
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1922
-        $order       = $this->request->getRequestParam('order', 'DESC');
1923
-        $month_range = $this->request->getRequestParam('month_range');
1924
-        if ($month_range) {
1925
-            $pieces = explode(' ', $month_range, 3);
1926
-            // simulate the FIRST day of the month, that fixes issues for months like February
1927
-            // where PHP doesn't know what to assume for date.
1928
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1929
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1930
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1931
-        }
1932
-        $where  = [];
1933
-        $status = $this->request->getRequestParam('status');
1934
-        // determine what post_status our condition will have for the query.
1935
-        switch ($status) {
1936
-            case 'month':
1937
-            case 'today':
1938
-            case null:
1939
-            case 'all':
1940
-                break;
1941
-            case 'draft':
1942
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1943
-                break;
1944
-            default:
1945
-                $where['status'] = $status;
1946
-        }
1947
-        // categories? The default for all categories is -1
1948
-        $category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1949
-        if ($category !== -1) {
1950
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1951
-            $where['Term_Taxonomy.term_id']  = $category;
1952
-        }
1953
-        // date where conditions
1954
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1955
-        if ($month_range) {
1956
-            $DateTime = new DateTime(
1957
-                $year_r . '-' . $month_r . '-01 00:00:00',
1958
-                new DateTimeZone('UTC')
1959
-            );
1960
-            $start    = $DateTime->getTimestamp();
1961
-            // set the datetime to be the end of the month
1962
-            $DateTime->setDate(
1963
-                $year_r,
1964
-                $month_r,
1965
-                $DateTime->format('t')
1966
-            )->setTime(23, 59, 59);
1967
-            $end                             = $DateTime->getTimestamp();
1968
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1969
-        } elseif ($status === 'today') {
1970
-            $DateTime                        =
1971
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1972
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1973
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1974
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1975
-        } elseif ($status === 'month') {
1976
-            $now                             = date('Y-m-01');
1977
-            $DateTime                        =
1978
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1979
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1980
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1981
-                                                        ->setTime(23, 59, 59)
1982
-                                                        ->format(implode(' ', $start_formats));
1983
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1984
-        }
1985
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1986
-            $where['EVT_wp_user'] = get_current_user_id();
1987
-        } else {
1988
-            if (! isset($where['status'])) {
1989
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1990
-                    $where['OR'] = [
1991
-                        'status*restrict_private' => ['!=', 'private'],
1992
-                        'AND'                     => [
1993
-                            'status*inclusive' => ['=', 'private'],
1994
-                            'EVT_wp_user'      => get_current_user_id(),
1995
-                        ],
1996
-                    ];
1997
-                }
1998
-            }
1999
-        }
2000
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2001
-        if (
2002
-            $wp_user
2003
-            && $wp_user !== get_current_user_id()
2004
-            && $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2005
-        ) {
2006
-            $where['EVT_wp_user'] = $wp_user;
2007
-        }
2008
-        // search query handling
2009
-        $search_term = $this->request->getRequestParam('s');
2010
-        if ($search_term) {
2011
-            $search_term = '%' . $search_term . '%';
2012
-            $where['OR'] = [
2013
-                'EVT_name'       => ['LIKE', $search_term],
2014
-                'EVT_desc'       => ['LIKE', $search_term],
2015
-                'EVT_short_desc' => ['LIKE', $search_term],
2016
-            ];
2017
-        }
2018
-        // filter events by venue.
2019
-        $venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2020
-        if ($venue) {
2021
-            $where['Venue.VNU_ID'] = $venue;
2022
-        }
2023
-        $request_params = $this->request->requestParams();
2024
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2025
-        $query_params   = apply_filters(
2026
-            'FHEE__Events_Admin_Page__get_events__query_params',
2027
-            [
2028
-                $where,
2029
-                'limit'    => $limit,
2030
-                'order_by' => $orderby,
2031
-                'order'    => $order,
2032
-                'group_by' => 'EVT_ID',
2033
-            ],
2034
-            $request_params
2035
-        );
2036
-
2037
-        // let's first check if we have special requests coming in.
2038
-        $active_status = $this->request->getRequestParam('active_status');
2039
-        if ($active_status) {
2040
-            switch ($active_status) {
2041
-                case 'upcoming':
2042
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2043
-                case 'expired':
2044
-                    return $EEM_Event->get_expired_events($query_params, $count);
2045
-                case 'active':
2046
-                    return $EEM_Event->get_active_events($query_params, $count);
2047
-                case 'inactive':
2048
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2049
-            }
2050
-        }
2051
-
2052
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2053
-    }
2054
-
2055
-
2056
-    /**
2057
-     * handling for WordPress CPT actions (trash, restore, delete)
2058
-     *
2059
-     * @param string $post_id
2060
-     * @throws EE_Error
2061
-     * @throws ReflectionException
2062
-     */
2063
-    public function trash_cpt_item($post_id)
2064
-    {
2065
-        $this->request->setRequestParam('EVT_ID', $post_id);
2066
-        $this->_trash_or_restore_event('trash', false);
2067
-    }
2068
-
2069
-
2070
-    /**
2071
-     * @param string $post_id
2072
-     * @throws EE_Error
2073
-     * @throws ReflectionException
2074
-     */
2075
-    public function restore_cpt_item($post_id)
2076
-    {
2077
-        $this->request->setRequestParam('EVT_ID', $post_id);
2078
-        $this->_trash_or_restore_event('draft', false);
2079
-    }
2080
-
2081
-
2082
-    /**
2083
-     * @param string $post_id
2084
-     * @throws EE_Error
2085
-     * @throws EE_Error
2086
-     */
2087
-    public function delete_cpt_item($post_id)
2088
-    {
2089
-        throw new EE_Error(
2090
-            esc_html__(
2091
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2092
-                'event_espresso'
2093
-            )
2094
-        );
2095
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2096
-        // $this->_delete_event();
2097
-    }
2098
-
2099
-
2100
-    /**
2101
-     * _trash_or_restore_event
2102
-     *
2103
-     * @access protected
2104
-     * @param string $event_status
2105
-     * @param bool   $redirect_after
2106
-     * @throws EE_Error
2107
-     * @throws EE_Error
2108
-     * @throws ReflectionException
2109
-     */
2110
-    protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2111
-    {
2112
-        // loop thru events
2113
-        if ($this->EVT_ID) {
2114
-            // clean status
2115
-            $event_status = sanitize_key($event_status);
2116
-            // grab status
2117
-            if (! empty($event_status)) {
2118
-                $success = $this->_change_event_status($this->EVT_ID, $event_status);
2119
-            } else {
2120
-                $success = false;
2121
-                $msg     = esc_html__(
2122
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2123
-                    'event_espresso'
2124
-                );
2125
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2126
-            }
2127
-        } else {
2128
-            $success = false;
2129
-            $msg     = esc_html__(
2130
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2131
-                'event_espresso'
2132
-            );
2133
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2134
-        }
2135
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2136
-        if ($redirect_after) {
2137
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2138
-        }
2139
-    }
2140
-
2141
-
2142
-    /**
2143
-     * _trash_or_restore_events
2144
-     *
2145
-     * @access protected
2146
-     * @param string $event_status
2147
-     * @return void
2148
-     * @throws EE_Error
2149
-     * @throws EE_Error
2150
-     * @throws ReflectionException
2151
-     */
2152
-    protected function _trash_or_restore_events(string $event_status = 'trash')
2153
-    {
2154
-        // clean status
2155
-        $event_status = sanitize_key($event_status);
2156
-        // grab status
2157
-        if (! empty($event_status)) {
2158
-            $success = true;
2159
-            // determine the event id and set to array.
2160
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2161
-            // loop thru events
2162
-            foreach ($EVT_IDs as $EVT_ID) {
2163
-                if ($EVT_ID = absint($EVT_ID)) {
2164
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2165
-                    $success = $results !== false ? $success : false;
2166
-                } else {
2167
-                    $msg = sprintf(
2168
-                        esc_html__(
2169
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2170
-                            'event_espresso'
2171
-                        ),
2172
-                        $EVT_ID
2173
-                    );
2174
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2175
-                    $success = false;
2176
-                }
2177
-            }
2178
-        } else {
2179
-            $success = false;
2180
-            $msg     = esc_html__(
2181
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2182
-                'event_espresso'
2183
-            );
2184
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
-        }
2186
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2187
-        $success = $success ? 2 : false;
2188
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2189
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2190
-    }
2191
-
2192
-
2193
-    /**
2194
-     * @param int    $EVT_ID
2195
-     * @param string $event_status
2196
-     * @return bool
2197
-     * @throws EE_Error
2198
-     * @throws ReflectionException
2199
-     */
2200
-    private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2201
-    {
2202
-        // grab event id
2203
-        if (! $EVT_ID) {
2204
-            $msg = esc_html__(
2205
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2206
-                'event_espresso'
2207
-            );
2208
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2209
-            return false;
2210
-        }
2211
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2212
-        // clean status
2213
-        $event_status = sanitize_key($event_status);
2214
-        // grab status
2215
-        if (empty($event_status)) {
2216
-            $msg = esc_html__(
2217
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2218
-                'event_espresso'
2219
-            );
2220
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2221
-            return false;
2222
-        }
2223
-        // was event trashed or restored ?
2224
-        switch ($event_status) {
2225
-            case 'draft':
2226
-                $action = 'restored from the trash';
2227
-                $hook   = 'AHEE_event_restored_from_trash';
2228
-                break;
2229
-            case 'trash':
2230
-                $action = 'moved to the trash';
2231
-                $hook   = 'AHEE_event_moved_to_trash';
2232
-                break;
2233
-            default:
2234
-                $action = 'updated';
2235
-                $hook   = false;
2236
-        }
2237
-        // use class to change status
2238
-        $this->_cpt_model_obj->set_status($event_status);
2239
-        $success = $this->_cpt_model_obj->save();
2240
-        if (! $success) {
2241
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2242
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2243
-            return false;
2244
-        }
2245
-        if ($hook) {
2246
-            do_action($hook);
2247
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2248
-            // because events side step that and it otherwise won't get called
2249
-            do_action(
2250
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2251
-                $this->_cpt_model_obj,
2252
-                $hook === 'AHEE_event_moved_to_trash',
2253
-                $success
2254
-            );
2255
-        }
2256
-        return true;
2257
-    }
2258
-
2259
-
2260
-    /**
2261
-     * @param array $event_ids
2262
-     * @return array
2263
-     * @since   4.10.23.p
2264
-     */
2265
-    private function cleanEventIds(array $event_ids): array
2266
-    {
2267
-        return array_map('absint', $event_ids);
2268
-    }
2269
-
2270
-
2271
-    /**
2272
-     * @return array
2273
-     * @since   4.10.23.p
2274
-     */
2275
-    private function getEventIdsFromRequest(): array
2276
-    {
2277
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2278
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2279
-        } else {
2280
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2281
-        }
2282
-    }
2283
-
2284
-
2285
-    /**
2286
-     * @param bool $preview_delete
2287
-     * @throws EE_Error
2288
-     * @throws ReflectionException
2289
-     */
2290
-    protected function _delete_event(bool $preview_delete = true)
2291
-    {
2292
-        $this->_delete_events($preview_delete);
2293
-    }
2294
-
2295
-
2296
-    /**
2297
-     * Gets the tree traversal batch persister.
2298
-     *
2299
-     * @return NodeGroupDao
2300
-     * @throws InvalidArgumentException
2301
-     * @throws InvalidDataTypeException
2302
-     * @throws InvalidInterfaceException
2303
-     * @since 4.10.12.p
2304
-     */
2305
-    protected function getModelObjNodeGroupPersister(): NodeGroupDao
2306
-    {
2307
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2308
-            $this->model_obj_node_group_persister =
2309
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2310
-        }
2311
-        return $this->model_obj_node_group_persister;
2312
-    }
2313
-
2314
-
2315
-    /**
2316
-     * @param bool $preview_delete
2317
-     * @return void
2318
-     * @throws EE_Error
2319
-     * @throws ReflectionException
2320
-     */
2321
-    protected function _delete_events(bool $preview_delete = true)
2322
-    {
2323
-        $event_ids = $this->getEventIdsFromRequest();
2324
-        if ($preview_delete) {
2325
-            $this->generateDeletionPreview($event_ids);
2326
-        } else {
2327
-            foreach ($event_ids as $event_id) {
2328
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2329
-                if ($event instanceof EE_Event) {
2330
-                    $event->delete_permanently();
2331
-                }
2332
-            }
2333
-        }
2334
-    }
2335
-
2336
-
2337
-    /**
2338
-     * @param array $event_ids
2339
-     */
2340
-    protected function generateDeletionPreview(array $event_ids)
2341
-    {
2342
-        $event_ids = $this->cleanEventIds($event_ids);
2343
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2344
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2345
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2346
-            [
2347
-                'action'            => 'preview_deletion',
2348
-                'deletion_job_code' => $deletion_job_code,
2349
-            ],
2350
-            $this->_admin_base_url
2351
-        );
2352
-        EEH_URL::safeRedirectAndExit(
2353
-            EE_Admin_Page::add_query_args_and_nonce(
2354
-                [
2355
-                    'page'              => EED_Batch::PAGE_SLUG,
2356
-                    'batch'             => EED_Batch::batch_job,
2357
-                    'EVT_IDs'           => $event_ids,
2358
-                    'deletion_job_code' => $deletion_job_code,
2359
-                    'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2360
-                    'return_url'        => urlencode($return_url),
2361
-                ],
2362
-                admin_url()
2363
-            )
2364
-        );
2365
-    }
2366
-
2367
-
2368
-    /**
2369
-     * Checks for a POST submission
2370
-     *
2371
-     * @since 4.10.12.p
2372
-     */
2373
-    protected function confirmDeletion()
2374
-    {
2375
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2376
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2377
-        );
2378
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2379
-    }
2380
-
2381
-
2382
-    /**
2383
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2384
-     *
2385
-     * @throws EE_Error
2386
-     * @since 4.10.12.p
2387
-     */
2388
-    protected function previewDeletion()
2389
-    {
2390
-        $preview_deletion_logic = $this->getLoader()->getShared(
2391
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2392
-        );
2393
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2394
-        $this->display_admin_page_with_no_sidebar();
2395
-    }
2396
-
2397
-
2398
-    /**
2399
-     * get total number of events
2400
-     *
2401
-     * @access public
2402
-     * @return int
2403
-     * @throws EE_Error
2404
-     * @throws EE_Error
2405
-     * @throws ReflectionException
2406
-     */
2407
-    public function total_events(): int
2408
-    {
2409
-        return EEM_Event::instance()->count(
2410
-            ['caps' => 'read_admin'],
2411
-            'EVT_ID',
2412
-            true
2413
-        );
2414
-    }
2415
-
2416
-
2417
-    /**
2418
-     * get total number of draft events
2419
-     *
2420
-     * @access public
2421
-     * @return int
2422
-     * @throws EE_Error
2423
-     * @throws EE_Error
2424
-     * @throws ReflectionException
2425
-     */
2426
-    public function total_events_draft(): int
2427
-    {
2428
-        return EEM_Event::instance()->count(
2429
-            [
2430
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2431
-                'caps' => 'read_admin',
2432
-            ],
2433
-            'EVT_ID',
2434
-            true
2435
-        );
2436
-    }
2437
-
2438
-
2439
-    /**
2440
-     * get total number of trashed events
2441
-     *
2442
-     * @access public
2443
-     * @return int
2444
-     * @throws EE_Error
2445
-     * @throws EE_Error
2446
-     * @throws ReflectionException
2447
-     */
2448
-    public function total_trashed_events(): int
2449
-    {
2450
-        return EEM_Event::instance()->count(
2451
-            [
2452
-                ['status' => 'trash'],
2453
-                'caps' => 'read_admin',
2454
-            ],
2455
-            'EVT_ID',
2456
-            true
2457
-        );
2458
-    }
2459
-
2460
-
2461
-    /**
2462
-     *    _default_event_settings
2463
-     *    This generates the Default Settings Tab
2464
-     *
2465
-     * @return void
2466
-     * @throws DomainException
2467
-     * @throws EE_Error
2468
-     * @throws InvalidArgumentException
2469
-     * @throws InvalidDataTypeException
2470
-     * @throws InvalidInterfaceException
2471
-     * @throws ReflectionException
2472
-     */
2473
-    protected function _default_event_settings()
2474
-    {
2475
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2476
-        $this->_set_publish_post_box_vars();
2477
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
2478
-            $this->_default_event_settings_form()->get_html(),
2479
-            '',
2480
-            'padding'
2481
-        );
2482
-        $this->display_admin_page_with_sidebar();
2483
-    }
2484
-
2485
-
2486
-    /**
2487
-     * Return the form for event settings.
2488
-     *
2489
-     * @return EE_Form_Section_Proper
2490
-     * @throws EE_Error
2491
-     * @throws ReflectionException
2492
-     */
2493
-    protected function _default_event_settings_form(): EE_Form_Section_Proper
2494
-    {
2495
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2496
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2497
-        // exclude
2498
-            [
2499
-                EEM_Registration::status_id_cancelled,
2500
-                EEM_Registration::status_id_declined,
2501
-                EEM_Registration::status_id_incomplete,
2502
-                EEM_Registration::status_id_wait_list,
2503
-            ],
2504
-            true
2505
-        );
2506
-        // setup Advanced Editor ???
2507
-        if (
2508
-            $this->raw_req_action === 'default_event_settings'
2509
-            || $this->raw_req_action === 'update_default_event_settings'
2510
-        ) {
2511
-            $this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2512
-        }
2513
-        return new EE_Form_Section_Proper(
2514
-            [
2515
-                'name'            => 'update_default_event_settings',
2516
-                'html_id'         => 'update_default_event_settings',
2517
-                'html_class'      => 'form-table',
2518
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2519
-                'subsections'     => apply_filters(
2520
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2521
-                    [
2522
-                        'defaults_section_header' => new EE_Form_Section_HTML(
2523
-                            EEH_HTML::h2(
2524
-                                esc_html__('Default Settings', 'event_espresso'),
2525
-                                '',
2526
-                                'ee-admin-settings-hdr'
2527
-                            )
2528
-                        ),
2529
-                        'default_reg_status'      => new EE_Select_Input(
2530
-                            $registration_stati_for_selection,
2531
-                            [
2532
-                                'default'         => isset($registration_config->default_STS_ID)
2533
-                                                     && array_key_exists(
2534
-                                                         $registration_config->default_STS_ID,
2535
-                                                         $registration_stati_for_selection
2536
-                                                     )
2537
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2538
-                                    : EEM_Registration::status_id_pending_payment,
2539
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2540
-                                                     . EEH_Template::get_help_tab_link(
2541
-                                        'default_settings_status_help_tab'
2542
-                                    ),
2543
-                                'html_help_text'  => esc_html__(
2544
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2545
-                                    'event_espresso'
2546
-                                ),
2547
-                            ]
2548
-                        ),
2549
-                        'default_max_tickets'     => new EE_Integer_Input(
2550
-                            [
2551
-                                'default'         => $registration_config->default_maximum_number_of_tickets
2552
-                                                     ?? EEM_Event::get_default_additional_limit(),
2553
-                                'html_label_text' => esc_html__(
2554
-                                                         'Default Maximum Tickets Allowed Per Order:',
2555
-                                                         'event_espresso'
2556
-                                                     )
2557
-                                                     . EEH_Template::get_help_tab_link(
2558
-                                        'default_maximum_tickets_help_tab"'
2559
-                                    ),
2560
-                                'html_help_text'  => esc_html__(
2561
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2562
-                                    'event_espresso'
2563
-                                ),
2564
-                            ]
2565
-                        ),
2566
-                    ]
2567
-                ),
2568
-            ]
2569
-        );
2570
-    }
2571
-
2572
-
2573
-    /**
2574
-     * @return void
2575
-     * @throws EE_Error
2576
-     * @throws InvalidArgumentException
2577
-     * @throws InvalidDataTypeException
2578
-     * @throws InvalidInterfaceException
2579
-     * @throws ReflectionException
2580
-     */
2581
-    protected function _update_default_event_settings()
2582
-    {
2583
-        $form = $this->_default_event_settings_form();
2584
-        if ($form->was_submitted()) {
2585
-            $form->receive_form_submission();
2586
-            if ($form->is_valid()) {
2587
-                $registration_config = EE_Registry::instance()->CFG->registration;
2588
-                $valid_data          = $form->valid_data();
2589
-                if (isset($valid_data['default_reg_status'])) {
2590
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2591
-                }
2592
-                if (isset($valid_data['default_max_tickets'])) {
2593
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2594
-                }
2595
-                do_action(
2596
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2597
-                    $valid_data,
2598
-                    EE_Registry::instance()->CFG,
2599
-                    $this
2600
-                );
2601
-                // update because data was valid!
2602
-                EE_Registry::instance()->CFG->update_espresso_config();
2603
-                EE_Error::overwrite_success();
2604
-                EE_Error::add_success(
2605
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2606
-                );
2607
-            }
2608
-        }
2609
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2610
-    }
2611
-
2612
-
2613
-    /*************        Templates        *************
2614
-     *
2615
-     * @throws EE_Error
2616
-     */
2617
-    protected function _template_settings()
2618
-    {
2619
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2620
-        $this->_template_args['preview_img']  = '<img src="'
2621
-                                                . EVENTS_ASSETS_URL
2622
-                                                . '/images/'
2623
-                                                . 'caffeinated_template_features.jpg" alt="'
2624
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2625
-                                                . '" />';
2626
-        $this->_template_args['preview_text'] = '<strong>'
2627
-                                                . esc_html__(
2628
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2629
-                                                    'event_espresso'
2630
-                                                ) . '</strong>';
2631
-        $this->display_admin_caf_preview_page('template_settings_tab');
2632
-    }
2633
-
2634
-
2635
-    /** Event Category Stuff **/
2636
-    /**
2637
-     * set the _category property with the category object for the loaded page.
2638
-     *
2639
-     * @access private
2640
-     * @return void
2641
-     */
2642
-    private function _set_category_object()
2643
-    {
2644
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2645
-            return;
2646
-        } //already have the category object so get out.
2647
-        // set default category object
2648
-        $this->_set_empty_category_object();
2649
-        // only set if we've got an id
2650
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2651
-        if (! $category_ID) {
2652
-            return;
2653
-        }
2654
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2655
-        if (! empty($term)) {
2656
-            $this->_category->category_name       = $term->name;
2657
-            $this->_category->category_identifier = $term->slug;
2658
-            $this->_category->category_desc       = $term->description;
2659
-            $this->_category->id                  = $term->term_id;
2660
-            $this->_category->parent              = $term->parent;
2661
-        }
2662
-    }
2663
-
2664
-
2665
-    /**
2666
-     * Clears out category properties.
2667
-     */
2668
-    private function _set_empty_category_object()
2669
-    {
2670
-        $this->_category                = new stdClass();
2671
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2672
-        $this->_category->id            = $this->_category->parent = 0;
2673
-    }
2674
-
2675
-
2676
-    /**
2677
-     * @throws DomainException
2678
-     * @throws EE_Error
2679
-     * @throws InvalidArgumentException
2680
-     * @throws InvalidDataTypeException
2681
-     * @throws InvalidInterfaceException
2682
-     */
2683
-    protected function _category_list_table()
2684
-    {
2685
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2686
-        $this->_admin_page_title .= ' ';
2687
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2688
-            'add_category',
2689
-            'add_category',
2690
-            [],
2691
-            'add-new-h2'
2692
-        );
2693
-        $this->display_admin_list_table_page_with_sidebar();
2694
-    }
2695
-
2696
-
2697
-    /**
2698
-     * Output category details view.
2699
-     *
2700
-     * @throws EE_Error
2701
-     * @throws EE_Error
2702
-     */
2703
-    protected function _category_details($view)
2704
-    {
2705
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2706
-        $this->_set_add_edit_form_tags($route);
2707
-        $this->_set_category_object();
2708
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2709
-        $delete_action = 'delete_category';
2710
-        // custom redirect
2711
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2712
-            ['action' => 'category_list'],
2713
-            $this->_admin_base_url
2714
-        );
2715
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2716
-        // take care of contents
2717
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2718
-        $this->display_admin_page_with_sidebar();
2719
-    }
2720
-
2721
-
2722
-    /**
2723
-     * Output category details content.
2724
-     *
2725
-     * @throws DomainException
2726
-     */
2727
-    protected function _category_details_content(): string
2728
-    {
2729
-        $editor_args['category_desc'] = [
2730
-            'type'          => 'wp_editor',
2731
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2732
-            'class'         => 'my_editor_custom',
2733
-            'wpeditor_args' => ['media_buttons' => false],
2734
-        ];
2735
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2736
-        $all_terms                    = get_terms(
2737
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2738
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2739
-        );
2740
-        // setup category select for term parents.
2741
-        $category_select_values[] = [
2742
-            'text' => esc_html__('No Parent', 'event_espresso'),
2743
-            'id'   => 0,
2744
-        ];
2745
-        foreach ($all_terms as $term) {
2746
-            $category_select_values[] = [
2747
-                'text' => $term->name,
2748
-                'id'   => $term->term_id,
2749
-            ];
2750
-        }
2751
-        $category_select = EEH_Form_Fields::select_input(
2752
-            'category_parent',
2753
-            $category_select_values,
2754
-            $this->_category->parent
2755
-        );
2756
-        $template_args   = [
2757
-            'category'                 => $this->_category,
2758
-            'category_select'          => $category_select,
2759
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2760
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2761
-            'disable'                  => '',
2762
-            'disabled_message'         => false,
2763
-        ];
2764
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2765
-        return EEH_Template::display_template($template, $template_args, true);
2766
-    }
2767
-
2768
-
2769
-    /**
2770
-     * Handles deleting categories.
2771
-     *
2772
-     * @throws EE_Error
2773
-     */
2774
-    protected function _delete_categories()
2775
-    {
2776
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2777
-        foreach ($category_IDs as $category_ID) {
2778
-            $this->_delete_category($category_ID);
2779
-        }
2780
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2781
-        $query_args = [
2782
-            'action' => 'category_list',
2783
-        ];
2784
-        $this->_redirect_after_action(0, '', '', $query_args);
2785
-    }
2786
-
2787
-
2788
-    /**
2789
-     * Handles deleting specific category.
2790
-     *
2791
-     * @param int $cat_id
2792
-     */
2793
-    protected function _delete_category(int $cat_id)
2794
-    {
2795
-        $cat_id = absint($cat_id);
2796
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2797
-    }
2798
-
2799
-
2800
-    /**
2801
-     * Handles triggering the update or insertion of a new category.
2802
-     *
2803
-     * @param bool $new_category true means we're triggering the insert of a new category.
2804
-     * @throws EE_Error
2805
-     * @throws EE_Error
2806
-     */
2807
-    protected function _insert_or_update_category(bool $new_category)
2808
-    {
2809
-        $cat_id  = $this->_insert_category($new_category);
2810
-        $success = 0; // we already have a success message so lets not send another.
2811
-        if ($cat_id) {
2812
-            $query_args = [
2813
-                'action'     => 'edit_category',
2814
-                'EVT_CAT_ID' => $cat_id,
2815
-            ];
2816
-        } else {
2817
-            $query_args = ['action' => 'add_category'];
2818
-        }
2819
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2820
-    }
2821
-
2822
-
2823
-    /**
2824
-     * Inserts or updates category
2825
-     *
2826
-     * @param bool $new_category (true indicates we're updating a category).
2827
-     * @return bool|mixed|string
2828
-     */
2829
-    private function _insert_category(bool $new_category)
2830
-    {
2831
-        $category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2832
-        $category_name       = $this->request->getRequestParam('category_name', '');
2833
-        $category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2834
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2835
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2836
-
2837
-        if (empty($category_name)) {
2838
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2839
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2840
-            return 0;
2841
-        }
2842
-        $term_args = [
2843
-            'name'        => $category_name,
2844
-            'description' => $category_desc,
2845
-            'parent'      => $category_parent,
2846
-        ];
2847
-        // was the category_identifier input disabled?
2848
-        if ($category_identifier) {
2849
-            $term_args['slug'] = $category_identifier;
2850
-        }
2851
-        $insert_ids = $new_category
2852
-            ? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2853
-            : wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2854
-
2855
-        if ($insert_ids instanceof WP_Error) {
2856
-            EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2857
-            return 0;
2858
-        }
2859
-        $category_ID = $insert_ids['term_id'] ?? 0;
2860
-        if (! $category_ID) {
2861
-            EE_Error::add_error(
2862
-                esc_html__(
2863
-                    'An error occurred and the category has not been saved to the database.',
2864
-                    'event_espresso'
2865
-                ),
2866
-                __FILE__,
2867
-                __FUNCTION__,
2868
-                __LINE__
2869
-            );
2870
-            return 0;
2871
-        }
2872
-        EE_Error::add_success(
2873
-            sprintf(
2874
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2875
-                $category_name
2876
-            )
2877
-        );
2878
-        return $category_ID;
2879
-    }
2880
-
2881
-
2882
-    /**
2883
-     * Gets categories or count of categories matching the arguments in the request.
2884
-     *
2885
-     * @param int  $per_page
2886
-     * @param int  $current_page
2887
-     * @param bool $count
2888
-     * @return EE_Term_Taxonomy[]|int
2889
-     * @throws EE_Error
2890
-     * @throws ReflectionException
2891
-     */
2892
-    public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2893
-    {
2894
-        // testing term stuff
2895
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2896
-        $order       = $this->request->getRequestParam('order', 'DESC');
2897
-        $limit       = ($current_page - 1) * $per_page;
2898
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2899
-        $search_term = $this->request->getRequestParam('s');
2900
-        if ($search_term) {
2901
-            $search_term = '%' . $search_term . '%';
2902
-            $where['OR'] = [
2903
-                'Term.name'   => ['LIKE', $search_term],
2904
-                'description' => ['LIKE', $search_term],
2905
-            ];
2906
-        }
2907
-        $query_params = [
2908
-            $where,
2909
-            'order_by'   => [$orderby => $order],
2910
-            'limit'      => $limit . ',' . $per_page,
2911
-            'force_join' => ['Term'],
2912
-        ];
2913
-        return $count
2914
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2915
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2916
-    }
2917
-
2918
-    /* end category stuff */
2919
-
2920
-
2921
-    /**************/
2922
-
2923
-
2924
-    /**
2925
-     * Callback for the `ee_save_timezone_setting` ajax action.
2926
-     *
2927
-     * @throws EE_Error
2928
-     * @throws InvalidArgumentException
2929
-     * @throws InvalidDataTypeException
2930
-     * @throws InvalidInterfaceException
2931
-     */
2932
-    public function saveTimezoneString()
2933
-    {
2934
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2935
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2936
-            EE_Error::add_error(
2937
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2938
-                __FILE__,
2939
-                __FUNCTION__,
2940
-                __LINE__
2941
-            );
2942
-            $this->_template_args['error'] = true;
2943
-            $this->_return_json();
2944
-        }
2945
-
2946
-        update_option('timezone_string', $timezone_string);
2947
-        EE_Error::add_success(
2948
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2949
-        );
2950
-        $this->_template_args['success'] = true;
2951
-        $this->_return_json(true, ['action' => 'create_new']);
2952
-    }
2953
-
2954
-
2955
-    /**
2956 2615
      * @throws EE_Error
2957
-     * @deprecated 4.10.25.p
2958 2616
      */
2959
-    public function save_timezonestring_setting()
2960
-    {
2961
-        $this->saveTimezoneString();
2962
-    }
2617
+	protected function _template_settings()
2618
+	{
2619
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2620
+		$this->_template_args['preview_img']  = '<img src="'
2621
+												. EVENTS_ASSETS_URL
2622
+												. '/images/'
2623
+												. 'caffeinated_template_features.jpg" alt="'
2624
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2625
+												. '" />';
2626
+		$this->_template_args['preview_text'] = '<strong>'
2627
+												. esc_html__(
2628
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2629
+													'event_espresso'
2630
+												) . '</strong>';
2631
+		$this->display_admin_caf_preview_page('template_settings_tab');
2632
+	}
2633
+
2634
+
2635
+	/** Event Category Stuff **/
2636
+	/**
2637
+	 * set the _category property with the category object for the loaded page.
2638
+	 *
2639
+	 * @access private
2640
+	 * @return void
2641
+	 */
2642
+	private function _set_category_object()
2643
+	{
2644
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2645
+			return;
2646
+		} //already have the category object so get out.
2647
+		// set default category object
2648
+		$this->_set_empty_category_object();
2649
+		// only set if we've got an id
2650
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2651
+		if (! $category_ID) {
2652
+			return;
2653
+		}
2654
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2655
+		if (! empty($term)) {
2656
+			$this->_category->category_name       = $term->name;
2657
+			$this->_category->category_identifier = $term->slug;
2658
+			$this->_category->category_desc       = $term->description;
2659
+			$this->_category->id                  = $term->term_id;
2660
+			$this->_category->parent              = $term->parent;
2661
+		}
2662
+	}
2663
+
2664
+
2665
+	/**
2666
+	 * Clears out category properties.
2667
+	 */
2668
+	private function _set_empty_category_object()
2669
+	{
2670
+		$this->_category                = new stdClass();
2671
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2672
+		$this->_category->id            = $this->_category->parent = 0;
2673
+	}
2674
+
2675
+
2676
+	/**
2677
+	 * @throws DomainException
2678
+	 * @throws EE_Error
2679
+	 * @throws InvalidArgumentException
2680
+	 * @throws InvalidDataTypeException
2681
+	 * @throws InvalidInterfaceException
2682
+	 */
2683
+	protected function _category_list_table()
2684
+	{
2685
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2686
+		$this->_admin_page_title .= ' ';
2687
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2688
+			'add_category',
2689
+			'add_category',
2690
+			[],
2691
+			'add-new-h2'
2692
+		);
2693
+		$this->display_admin_list_table_page_with_sidebar();
2694
+	}
2695
+
2696
+
2697
+	/**
2698
+	 * Output category details view.
2699
+	 *
2700
+	 * @throws EE_Error
2701
+	 * @throws EE_Error
2702
+	 */
2703
+	protected function _category_details($view)
2704
+	{
2705
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2706
+		$this->_set_add_edit_form_tags($route);
2707
+		$this->_set_category_object();
2708
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2709
+		$delete_action = 'delete_category';
2710
+		// custom redirect
2711
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2712
+			['action' => 'category_list'],
2713
+			$this->_admin_base_url
2714
+		);
2715
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2716
+		// take care of contents
2717
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2718
+		$this->display_admin_page_with_sidebar();
2719
+	}
2720
+
2721
+
2722
+	/**
2723
+	 * Output category details content.
2724
+	 *
2725
+	 * @throws DomainException
2726
+	 */
2727
+	protected function _category_details_content(): string
2728
+	{
2729
+		$editor_args['category_desc'] = [
2730
+			'type'          => 'wp_editor',
2731
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2732
+			'class'         => 'my_editor_custom',
2733
+			'wpeditor_args' => ['media_buttons' => false],
2734
+		];
2735
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2736
+		$all_terms                    = get_terms(
2737
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2738
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2739
+		);
2740
+		// setup category select for term parents.
2741
+		$category_select_values[] = [
2742
+			'text' => esc_html__('No Parent', 'event_espresso'),
2743
+			'id'   => 0,
2744
+		];
2745
+		foreach ($all_terms as $term) {
2746
+			$category_select_values[] = [
2747
+				'text' => $term->name,
2748
+				'id'   => $term->term_id,
2749
+			];
2750
+		}
2751
+		$category_select = EEH_Form_Fields::select_input(
2752
+			'category_parent',
2753
+			$category_select_values,
2754
+			$this->_category->parent
2755
+		);
2756
+		$template_args   = [
2757
+			'category'                 => $this->_category,
2758
+			'category_select'          => $category_select,
2759
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2760
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2761
+			'disable'                  => '',
2762
+			'disabled_message'         => false,
2763
+		];
2764
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2765
+		return EEH_Template::display_template($template, $template_args, true);
2766
+	}
2767
+
2768
+
2769
+	/**
2770
+	 * Handles deleting categories.
2771
+	 *
2772
+	 * @throws EE_Error
2773
+	 */
2774
+	protected function _delete_categories()
2775
+	{
2776
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2777
+		foreach ($category_IDs as $category_ID) {
2778
+			$this->_delete_category($category_ID);
2779
+		}
2780
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2781
+		$query_args = [
2782
+			'action' => 'category_list',
2783
+		];
2784
+		$this->_redirect_after_action(0, '', '', $query_args);
2785
+	}
2786
+
2787
+
2788
+	/**
2789
+	 * Handles deleting specific category.
2790
+	 *
2791
+	 * @param int $cat_id
2792
+	 */
2793
+	protected function _delete_category(int $cat_id)
2794
+	{
2795
+		$cat_id = absint($cat_id);
2796
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2797
+	}
2798
+
2799
+
2800
+	/**
2801
+	 * Handles triggering the update or insertion of a new category.
2802
+	 *
2803
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2804
+	 * @throws EE_Error
2805
+	 * @throws EE_Error
2806
+	 */
2807
+	protected function _insert_or_update_category(bool $new_category)
2808
+	{
2809
+		$cat_id  = $this->_insert_category($new_category);
2810
+		$success = 0; // we already have a success message so lets not send another.
2811
+		if ($cat_id) {
2812
+			$query_args = [
2813
+				'action'     => 'edit_category',
2814
+				'EVT_CAT_ID' => $cat_id,
2815
+			];
2816
+		} else {
2817
+			$query_args = ['action' => 'add_category'];
2818
+		}
2819
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2820
+	}
2821
+
2822
+
2823
+	/**
2824
+	 * Inserts or updates category
2825
+	 *
2826
+	 * @param bool $new_category (true indicates we're updating a category).
2827
+	 * @return bool|mixed|string
2828
+	 */
2829
+	private function _insert_category(bool $new_category)
2830
+	{
2831
+		$category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2832
+		$category_name       = $this->request->getRequestParam('category_name', '');
2833
+		$category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2834
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2835
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2836
+
2837
+		if (empty($category_name)) {
2838
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2839
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2840
+			return 0;
2841
+		}
2842
+		$term_args = [
2843
+			'name'        => $category_name,
2844
+			'description' => $category_desc,
2845
+			'parent'      => $category_parent,
2846
+		];
2847
+		// was the category_identifier input disabled?
2848
+		if ($category_identifier) {
2849
+			$term_args['slug'] = $category_identifier;
2850
+		}
2851
+		$insert_ids = $new_category
2852
+			? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2853
+			: wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2854
+
2855
+		if ($insert_ids instanceof WP_Error) {
2856
+			EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2857
+			return 0;
2858
+		}
2859
+		$category_ID = $insert_ids['term_id'] ?? 0;
2860
+		if (! $category_ID) {
2861
+			EE_Error::add_error(
2862
+				esc_html__(
2863
+					'An error occurred and the category has not been saved to the database.',
2864
+					'event_espresso'
2865
+				),
2866
+				__FILE__,
2867
+				__FUNCTION__,
2868
+				__LINE__
2869
+			);
2870
+			return 0;
2871
+		}
2872
+		EE_Error::add_success(
2873
+			sprintf(
2874
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2875
+				$category_name
2876
+			)
2877
+		);
2878
+		return $category_ID;
2879
+	}
2880
+
2881
+
2882
+	/**
2883
+	 * Gets categories or count of categories matching the arguments in the request.
2884
+	 *
2885
+	 * @param int  $per_page
2886
+	 * @param int  $current_page
2887
+	 * @param bool $count
2888
+	 * @return EE_Term_Taxonomy[]|int
2889
+	 * @throws EE_Error
2890
+	 * @throws ReflectionException
2891
+	 */
2892
+	public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2893
+	{
2894
+		// testing term stuff
2895
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2896
+		$order       = $this->request->getRequestParam('order', 'DESC');
2897
+		$limit       = ($current_page - 1) * $per_page;
2898
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2899
+		$search_term = $this->request->getRequestParam('s');
2900
+		if ($search_term) {
2901
+			$search_term = '%' . $search_term . '%';
2902
+			$where['OR'] = [
2903
+				'Term.name'   => ['LIKE', $search_term],
2904
+				'description' => ['LIKE', $search_term],
2905
+			];
2906
+		}
2907
+		$query_params = [
2908
+			$where,
2909
+			'order_by'   => [$orderby => $order],
2910
+			'limit'      => $limit . ',' . $per_page,
2911
+			'force_join' => ['Term'],
2912
+		];
2913
+		return $count
2914
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2915
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2916
+	}
2917
+
2918
+	/* end category stuff */
2919
+
2920
+
2921
+	/**************/
2922
+
2923
+
2924
+	/**
2925
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2926
+	 *
2927
+	 * @throws EE_Error
2928
+	 * @throws InvalidArgumentException
2929
+	 * @throws InvalidDataTypeException
2930
+	 * @throws InvalidInterfaceException
2931
+	 */
2932
+	public function saveTimezoneString()
2933
+	{
2934
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2935
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2936
+			EE_Error::add_error(
2937
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2938
+				__FILE__,
2939
+				__FUNCTION__,
2940
+				__LINE__
2941
+			);
2942
+			$this->_template_args['error'] = true;
2943
+			$this->_return_json();
2944
+		}
2945
+
2946
+		update_option('timezone_string', $timezone_string);
2947
+		EE_Error::add_success(
2948
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2949
+		);
2950
+		$this->_template_args['success'] = true;
2951
+		$this->_return_json(true, ['action' => 'create_new']);
2952
+	}
2953
+
2954
+
2955
+	/**
2956
+	 * @throws EE_Error
2957
+	 * @deprecated 4.10.25.p
2958
+	 */
2959
+	public function save_timezonestring_setting()
2960
+	{
2961
+		$this->saveTimezoneString();
2962
+	}
2963 2963
 }
Please login to merge, or discard this patch.