Completed
Branch FET/extra-logging-when-trashin... (7fb54e)
by
unknown
02:46 queued 20s
created
caffeinated/admin/new/pricing/espresso_events_Pricing_Hooks.class.php 1 patch
Indentation   +2147 added lines, -2147 removed lines patch added patch discarded remove patch
@@ -14,2207 +14,2207 @@
 block discarded – undo
14 14
  */
15 15
 class espresso_events_Pricing_Hooks extends EE_Admin_Hooks
16 16
 {
17
-    /**
18
-     * This property is just used to hold the status of whether an event is currently being
19
-     * created (true) or edited (false)
20
-     *
21
-     * @access protected
22
-     * @var bool
23
-     */
24
-    protected $_is_creating_event;
17
+	/**
18
+	 * This property is just used to hold the status of whether an event is currently being
19
+	 * created (true) or edited (false)
20
+	 *
21
+	 * @access protected
22
+	 * @var bool
23
+	 */
24
+	protected $_is_creating_event;
25 25
 
26
-    /**
27
-     * Used to contain the format strings for date and time that will be used for php date and
28
-     * time.
29
-     * Is set in the _set_hooks_properties() method.
30
-     *
31
-     * @var array
32
-     */
33
-    protected $_date_format_strings;
26
+	/**
27
+	 * Used to contain the format strings for date and time that will be used for php date and
28
+	 * time.
29
+	 * Is set in the _set_hooks_properties() method.
30
+	 *
31
+	 * @var array
32
+	 */
33
+	protected $_date_format_strings;
34 34
 
35
-    /**
36
-     * @var string $_date_time_format
37
-     */
38
-    protected $_date_time_format;
35
+	/**
36
+	 * @var string $_date_time_format
37
+	 */
38
+	protected $_date_time_format;
39 39
 
40 40
 
41
-    /**
42
-     * @throws InvalidArgumentException
43
-     * @throws InvalidInterfaceException
44
-     * @throws InvalidDataTypeException
45
-     */
46
-    protected function _set_hooks_properties()
47
-    {
48
-        $this->_name = 'pricing';
49
-        // capability check
50
-        if (
51
-            ! EE_Registry::instance()->CAP->current_user_can(
52
-                'ee_read_default_prices',
53
-                'advanced_ticket_datetime_metabox'
54
-            )
55
-        ) {
56
-            return;
57
-        }
58
-        $this->_setup_metaboxes();
59
-        $this->_set_date_time_formats();
60
-        $this->_validate_format_strings();
61
-        $this->_set_scripts_styles();
62
-        // commented out temporarily until logic is implemented in callback
63
-        // add_action(
64
-        //     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
65
-        //     array($this, 'autosave_handling')
66
-        // );
67
-        add_filter(
68
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
-            array($this, 'caf_updates')
70
-        );
71
-    }
41
+	/**
42
+	 * @throws InvalidArgumentException
43
+	 * @throws InvalidInterfaceException
44
+	 * @throws InvalidDataTypeException
45
+	 */
46
+	protected function _set_hooks_properties()
47
+	{
48
+		$this->_name = 'pricing';
49
+		// capability check
50
+		if (
51
+			! EE_Registry::instance()->CAP->current_user_can(
52
+				'ee_read_default_prices',
53
+				'advanced_ticket_datetime_metabox'
54
+			)
55
+		) {
56
+			return;
57
+		}
58
+		$this->_setup_metaboxes();
59
+		$this->_set_date_time_formats();
60
+		$this->_validate_format_strings();
61
+		$this->_set_scripts_styles();
62
+		// commented out temporarily until logic is implemented in callback
63
+		// add_action(
64
+		//     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
65
+		//     array($this, 'autosave_handling')
66
+		// );
67
+		add_filter(
68
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
+			array($this, 'caf_updates')
70
+		);
71
+	}
72 72
 
73 73
 
74
-    /**
75
-     * @return void
76
-     */
77
-    protected function _setup_metaboxes()
78
-    {
79
-        // if we were going to add our own metaboxes we'd use the below.
80
-        $this->_metaboxes = array(
81
-            0 => array(
82
-                'page_route' => array('edit', 'create_new'),
83
-                'func'       => 'pricing_metabox',
84
-                'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
85
-                'priority'   => 'high',
86
-                'context'    => 'normal',
87
-            ),
88
-        );
89
-        $this->_remove_metaboxes = array(
90
-            0 => array(
91
-                'page_route' => array('edit', 'create_new'),
92
-                'id'         => 'espresso_event_editor_tickets',
93
-                'context'    => 'normal',
94
-            ),
95
-        );
96
-    }
74
+	/**
75
+	 * @return void
76
+	 */
77
+	protected function _setup_metaboxes()
78
+	{
79
+		// if we were going to add our own metaboxes we'd use the below.
80
+		$this->_metaboxes = array(
81
+			0 => array(
82
+				'page_route' => array('edit', 'create_new'),
83
+				'func'       => 'pricing_metabox',
84
+				'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
85
+				'priority'   => 'high',
86
+				'context'    => 'normal',
87
+			),
88
+		);
89
+		$this->_remove_metaboxes = array(
90
+			0 => array(
91
+				'page_route' => array('edit', 'create_new'),
92
+				'id'         => 'espresso_event_editor_tickets',
93
+				'context'    => 'normal',
94
+			),
95
+		);
96
+	}
97 97
 
98 98
 
99
-    /**
100
-     * @return void
101
-     */
102
-    protected function _set_date_time_formats()
103
-    {
104
-        /**
105
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
106
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
107
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
108
-         *
109
-         * @since 4.6.7
110
-         * @var array  Expected an array returned with 'date' and 'time' keys.
111
-         */
112
-        $this->_date_format_strings = apply_filters(
113
-            'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
114
-            array(
115
-                'date' => 'Y-m-d',
116
-                'time' => 'h:i a',
117
-            )
118
-        );
119
-        // validate
120
-        $this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
121
-            ? $this->_date_format_strings['date']
122
-            : null;
123
-        $this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
124
-            ? $this->_date_format_strings['time']
125
-            : null;
126
-        $this->_date_time_format = $this->_date_format_strings['date']
127
-                                   . ' '
128
-                                   . $this->_date_format_strings['time'];
129
-    }
99
+	/**
100
+	 * @return void
101
+	 */
102
+	protected function _set_date_time_formats()
103
+	{
104
+		/**
105
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
106
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
107
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
108
+		 *
109
+		 * @since 4.6.7
110
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
111
+		 */
112
+		$this->_date_format_strings = apply_filters(
113
+			'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
114
+			array(
115
+				'date' => 'Y-m-d',
116
+				'time' => 'h:i a',
117
+			)
118
+		);
119
+		// validate
120
+		$this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
121
+			? $this->_date_format_strings['date']
122
+			: null;
123
+		$this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
124
+			? $this->_date_format_strings['time']
125
+			: null;
126
+		$this->_date_time_format = $this->_date_format_strings['date']
127
+								   . ' '
128
+								   . $this->_date_format_strings['time'];
129
+	}
130 130
 
131 131
 
132
-    /**
133
-     * @return void
134
-     */
135
-    protected function _validate_format_strings()
136
-    {
137
-        // validate format strings
138
-        $format_validation = EEH_DTT_Helper::validate_format_string(
139
-            $this->_date_time_format
140
-        );
141
-        if (is_array($format_validation)) {
142
-            $msg = '<p>';
143
-            $msg .= sprintf(
144
-                esc_html__(
145
-                    'The format "%s" was likely added via a filter and is invalid for the following reasons:',
146
-                    'event_espresso'
147
-                ),
148
-                $this->_date_time_format
149
-            );
150
-            $msg .= '</p><ul>';
151
-            foreach ($format_validation as $error) {
152
-                $msg .= '<li>' . $error . '</li>';
153
-            }
154
-            $msg .= '</ul><p>';
155
-            $msg .= sprintf(
156
-                esc_html__(
157
-                    '%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
158
-                    'event_espresso'
159
-                ),
160
-                '<span style="color:#D54E21;">',
161
-                '</span>'
162
-            );
163
-            $msg .= '</p>';
164
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
165
-            $this->_date_format_strings = array(
166
-                'date' => 'Y-m-d',
167
-                'time' => 'h:i a',
168
-            );
169
-        }
170
-    }
132
+	/**
133
+	 * @return void
134
+	 */
135
+	protected function _validate_format_strings()
136
+	{
137
+		// validate format strings
138
+		$format_validation = EEH_DTT_Helper::validate_format_string(
139
+			$this->_date_time_format
140
+		);
141
+		if (is_array($format_validation)) {
142
+			$msg = '<p>';
143
+			$msg .= sprintf(
144
+				esc_html__(
145
+					'The format "%s" was likely added via a filter and is invalid for the following reasons:',
146
+					'event_espresso'
147
+				),
148
+				$this->_date_time_format
149
+			);
150
+			$msg .= '</p><ul>';
151
+			foreach ($format_validation as $error) {
152
+				$msg .= '<li>' . $error . '</li>';
153
+			}
154
+			$msg .= '</ul><p>';
155
+			$msg .= sprintf(
156
+				esc_html__(
157
+					'%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
158
+					'event_espresso'
159
+				),
160
+				'<span style="color:#D54E21;">',
161
+				'</span>'
162
+			);
163
+			$msg .= '</p>';
164
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
165
+			$this->_date_format_strings = array(
166
+				'date' => 'Y-m-d',
167
+				'time' => 'h:i a',
168
+			);
169
+		}
170
+	}
171 171
 
172 172
 
173
-    /**
174
-     * @return void
175
-     */
176
-    protected function _set_scripts_styles()
177
-    {
178
-        $this->_scripts_styles = array(
179
-            'registers'   => array(
180
-                'ee-tickets-datetimes-css' => array(
181
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
182
-                    'type' => 'css',
183
-                ),
184
-                'ee-dtt-ticket-metabox'    => array(
185
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
186
-                    'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
187
-                ),
188
-            ),
189
-            'deregisters' => array(
190
-                'event-editor-css'       => array('type' => 'css'),
191
-                'event-datetime-metabox' => array('type' => 'js'),
192
-            ),
193
-            'enqueues'    => array(
194
-                'ee-tickets-datetimes-css' => array('edit', 'create_new'),
195
-                'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
196
-            ),
197
-            'localize'    => array(
198
-                'ee-dtt-ticket-metabox' => array(
199
-                    'DTT_TRASH_BLOCK'       => array(
200
-                        'main_warning'            => esc_html__(
201
-                            'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
202
-                            'event_espresso'
203
-                        ),
204
-                        'after_warning'           => esc_html__(
205
-                            'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
206
-                            'event_espresso'
207
-                        ),
208
-                        'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
209
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
210
-                        'close_button'            => '<button class="button-secondary ee-modal-cancel">'
211
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
212
-                        'single_warning_from_tkt' => esc_html__(
213
-                            'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
214
-                            'event_espresso'
215
-                        ),
216
-                        'single_warning_from_dtt' => esc_html__(
217
-                            'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
218
-                            'event_espresso'
219
-                        ),
220
-                        'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
221
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
222
-                    ),
223
-                    'DTT_ERROR_MSG'         => array(
224
-                        'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
225
-                        'dismiss_button' => '<div class="save-cancel-button-container">'
226
-                                            . '<button class="button-secondary ee-modal-cancel">'
227
-                                            . esc_html__('Dismiss', 'event_espresso')
228
-                                            . '</button></div>',
229
-                    ),
230
-                    'DTT_OVERSELL_WARNING'  => array(
231
-                        'datetime_ticket' => esc_html__(
232
-                            'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
233
-                            'event_espresso'
234
-                        ),
235
-                        'ticket_datetime' => esc_html__(
236
-                            'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
237
-                            'event_espresso'
238
-                        ),
239
-                    ),
240
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
241
-                        $this->_date_format_strings['date'],
242
-                        $this->_date_format_strings['time']
243
-                    ),
244
-                    'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
245
-                ),
246
-            ),
247
-        );
248
-    }
173
+	/**
174
+	 * @return void
175
+	 */
176
+	protected function _set_scripts_styles()
177
+	{
178
+		$this->_scripts_styles = array(
179
+			'registers'   => array(
180
+				'ee-tickets-datetimes-css' => array(
181
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
182
+					'type' => 'css',
183
+				),
184
+				'ee-dtt-ticket-metabox'    => array(
185
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
186
+					'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
187
+				),
188
+			),
189
+			'deregisters' => array(
190
+				'event-editor-css'       => array('type' => 'css'),
191
+				'event-datetime-metabox' => array('type' => 'js'),
192
+			),
193
+			'enqueues'    => array(
194
+				'ee-tickets-datetimes-css' => array('edit', 'create_new'),
195
+				'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
196
+			),
197
+			'localize'    => array(
198
+				'ee-dtt-ticket-metabox' => array(
199
+					'DTT_TRASH_BLOCK'       => array(
200
+						'main_warning'            => esc_html__(
201
+							'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
202
+							'event_espresso'
203
+						),
204
+						'after_warning'           => esc_html__(
205
+							'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
206
+							'event_espresso'
207
+						),
208
+						'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
209
+													 . esc_html__('Cancel', 'event_espresso') . '</button>',
210
+						'close_button'            => '<button class="button-secondary ee-modal-cancel">'
211
+													 . esc_html__('Close', 'event_espresso') . '</button>',
212
+						'single_warning_from_tkt' => esc_html__(
213
+							'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
214
+							'event_espresso'
215
+						),
216
+						'single_warning_from_dtt' => esc_html__(
217
+							'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
218
+							'event_espresso'
219
+						),
220
+						'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
221
+													 . esc_html__('Dismiss', 'event_espresso') . '</button>',
222
+					),
223
+					'DTT_ERROR_MSG'         => array(
224
+						'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
225
+						'dismiss_button' => '<div class="save-cancel-button-container">'
226
+											. '<button class="button-secondary ee-modal-cancel">'
227
+											. esc_html__('Dismiss', 'event_espresso')
228
+											. '</button></div>',
229
+					),
230
+					'DTT_OVERSELL_WARNING'  => array(
231
+						'datetime_ticket' => esc_html__(
232
+							'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
233
+							'event_espresso'
234
+						),
235
+						'ticket_datetime' => esc_html__(
236
+							'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
237
+							'event_espresso'
238
+						),
239
+					),
240
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
241
+						$this->_date_format_strings['date'],
242
+						$this->_date_format_strings['time']
243
+					),
244
+					'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
245
+				),
246
+			),
247
+		);
248
+	}
249 249
 
250 250
 
251
-    /**
252
-     * @param array $update_callbacks
253
-     * @return array
254
-     */
255
-    public function caf_updates(array $update_callbacks)
256
-    {
257
-        foreach ($update_callbacks as $key => $callback) {
258
-            if ($callback[1] === '_default_tickets_update') {
259
-                unset($update_callbacks[ $key ]);
260
-            }
261
-        }
262
-        $update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
263
-        return $update_callbacks;
264
-    }
251
+	/**
252
+	 * @param array $update_callbacks
253
+	 * @return array
254
+	 */
255
+	public function caf_updates(array $update_callbacks)
256
+	{
257
+		foreach ($update_callbacks as $key => $callback) {
258
+			if ($callback[1] === '_default_tickets_update') {
259
+				unset($update_callbacks[ $key ]);
260
+			}
261
+		}
262
+		$update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
263
+		return $update_callbacks;
264
+	}
265 265
 
266 266
 
267
-    /**
268
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
269
-     *
270
-     * @param  EE_Event $event The Event object we're attaching data to
271
-     * @param  array    $data  The request data from the form
272
-     * @throws ReflectionException
273
-     * @throws Exception
274
-     * @throws InvalidInterfaceException
275
-     * @throws InvalidDataTypeException
276
-     * @throws EE_Error
277
-     * @throws InvalidArgumentException
278
-     */
279
-    public function datetime_and_tickets_caf_update($event, $data)
280
-    {
281
-        // first we need to start with datetimes cause they are the "root" items attached to events.
282
-        $saved_datetimes = $this->_update_datetimes($event, $data);
283
-        // next tackle the tickets (and prices?)
284
-        $this->_update_tickets($event, $saved_datetimes, $data);
285
-    }
267
+	/**
268
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
269
+	 *
270
+	 * @param  EE_Event $event The Event object we're attaching data to
271
+	 * @param  array    $data  The request data from the form
272
+	 * @throws ReflectionException
273
+	 * @throws Exception
274
+	 * @throws InvalidInterfaceException
275
+	 * @throws InvalidDataTypeException
276
+	 * @throws EE_Error
277
+	 * @throws InvalidArgumentException
278
+	 */
279
+	public function datetime_and_tickets_caf_update($event, $data)
280
+	{
281
+		// first we need to start with datetimes cause they are the "root" items attached to events.
282
+		$saved_datetimes = $this->_update_datetimes($event, $data);
283
+		// next tackle the tickets (and prices?)
284
+		$this->_update_tickets($event, $saved_datetimes, $data);
285
+	}
286 286
 
287 287
 
288
-    /**
289
-     * update event_datetimes
290
-     *
291
-     * @param  EE_Event $event Event being updated
292
-     * @param  array    $data  the request data from the form
293
-     * @return EE_Datetime[]
294
-     * @throws Exception
295
-     * @throws ReflectionException
296
-     * @throws InvalidInterfaceException
297
-     * @throws InvalidDataTypeException
298
-     * @throws InvalidArgumentException
299
-     * @throws EE_Error
300
-     */
301
-    protected function _update_datetimes($event, $data)
302
-    {
303
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
304
-        $saved_dtt_ids = array();
305
-        $saved_dtt_objs = array();
306
-        if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
307
-            throw new InvalidArgumentException(
308
-                esc_html__(
309
-                    'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
310
-                    'event_espresso'
311
-                )
312
-            );
313
-        }
314
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
315
-            // trim all values to ensure any excess whitespace is removed.
316
-            $datetime_data = array_map(
317
-                function ($datetime_data) {
318
-                    return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
319
-                },
320
-                $datetime_data
321
-            );
322
-            $datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
323
-                                            && ! empty($datetime_data['DTT_EVT_end'])
324
-                ? $datetime_data['DTT_EVT_end']
325
-                : $datetime_data['DTT_EVT_start'];
326
-            $datetime_values = array(
327
-                'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
328
-                    ? $datetime_data['DTT_ID']
329
-                    : null,
330
-                'DTT_name'        => ! empty($datetime_data['DTT_name'])
331
-                    ? $datetime_data['DTT_name']
332
-                    : '',
333
-                'DTT_description' => ! empty($datetime_data['DTT_description'])
334
-                    ? $datetime_data['DTT_description']
335
-                    : '',
336
-                'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
337
-                'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
338
-                'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
339
-                    ? EE_INF
340
-                    : $datetime_data['DTT_reg_limit'],
341
-                'DTT_order'       => ! isset($datetime_data['DTT_order'])
342
-                    ? $row
343
-                    : $datetime_data['DTT_order'],
344
-            );
345
-            // if we have an id then let's get existing object first and then set the new values.
346
-            // Otherwise we instantiate a new object for save.
347
-            if (! empty($datetime_data['DTT_ID'])) {
348
-                $datetime = EE_Registry::instance()
349
-                                       ->load_model('Datetime', array($timezone))
350
-                                       ->get_one_by_ID($datetime_data['DTT_ID']);
351
-                // set date and time format according to what is set in this class.
352
-                $datetime->set_date_format($this->_date_format_strings['date']);
353
-                $datetime->set_time_format($this->_date_format_strings['time']);
354
-                foreach ($datetime_values as $field => $value) {
355
-                    $datetime->set($field, $value);
356
-                }
357
-                // make sure the $dtt_id here is saved just in case
358
-                // after the add_relation_to() the autosave replaces it.
359
-                // We need to do this so we dont' TRASH the parent DTT.
360
-                // (save the ID for both key and value to avoid duplications)
361
-                $saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
362
-            } else {
363
-                $datetime = EE_Registry::instance()->load_class(
364
-                    'Datetime',
365
-                    array(
366
-                        $datetime_values,
367
-                        $timezone,
368
-                        array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
369
-                    ),
370
-                    false,
371
-                    false
372
-                );
373
-                foreach ($datetime_values as $field => $value) {
374
-                    $datetime->set($field, $value);
375
-                }
376
-            }
377
-            $datetime->save();
378
-            do_action(
379
-                'AHEE__espresso_events_Pricing_Hooks___update_datetimes_after_save',
380
-                $datetime,
381
-                $row,
382
-                $datetime_data,
383
-                $data
384
-            );
385
-            $datetime = $event->_add_relation_to($datetime, 'Datetime');
386
-            // before going any further make sure our dates are setup correctly
387
-            // so that the end date is always equal or greater than the start date.
388
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
389
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
390
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
391
-                $datetime->save();
392
-            }
393
-            // now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
394
-            // because it is possible there was a new one created for the autosave.
395
-            // (save the ID for both key and value to avoid duplications)
396
-            $DTT_ID = $datetime->ID();
397
-            $saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
398
-            $saved_dtt_objs[ $row ] = $datetime;
399
-            // @todo if ANY of these updates fail then we want the appropriate global error message.
400
-        }
401
-        $event->save();
402
-        // now we need to REMOVE any datetimes that got deleted.
403
-        // Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
404
-        // So its safe to permanently delete at this point.
405
-        $old_datetimes = explode(',', $data['datetime_IDs']);
406
-        $old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
407
-        if (is_array($old_datetimes)) {
408
-            $datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
409
-            foreach ($datetimes_to_delete as $id) {
410
-                $id = absint($id);
411
-                if (empty($id)) {
412
-                    continue;
413
-                }
414
-                /** @var EE_Datetime $dtt_to_remove */
415
-                $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
416
-                // remove tkt relationships.
417
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
418
-                foreach ($related_tickets as $tkt) {
419
-                    $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
420
-                }
421
-                $event->_remove_relation_to($id, 'Datetime');
422
-                $dtt_to_remove->refresh_cache_of_related_objects();
423
-                $dtt_to_remove->delete_or_restore();
424
-            }
425
-        }
426
-        return $saved_dtt_objs;
427
-    }
288
+	/**
289
+	 * update event_datetimes
290
+	 *
291
+	 * @param  EE_Event $event Event being updated
292
+	 * @param  array    $data  the request data from the form
293
+	 * @return EE_Datetime[]
294
+	 * @throws Exception
295
+	 * @throws ReflectionException
296
+	 * @throws InvalidInterfaceException
297
+	 * @throws InvalidDataTypeException
298
+	 * @throws InvalidArgumentException
299
+	 * @throws EE_Error
300
+	 */
301
+	protected function _update_datetimes($event, $data)
302
+	{
303
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
304
+		$saved_dtt_ids = array();
305
+		$saved_dtt_objs = array();
306
+		if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
307
+			throw new InvalidArgumentException(
308
+				esc_html__(
309
+					'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
310
+					'event_espresso'
311
+				)
312
+			);
313
+		}
314
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
315
+			// trim all values to ensure any excess whitespace is removed.
316
+			$datetime_data = array_map(
317
+				function ($datetime_data) {
318
+					return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
319
+				},
320
+				$datetime_data
321
+			);
322
+			$datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
323
+											&& ! empty($datetime_data['DTT_EVT_end'])
324
+				? $datetime_data['DTT_EVT_end']
325
+				: $datetime_data['DTT_EVT_start'];
326
+			$datetime_values = array(
327
+				'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
328
+					? $datetime_data['DTT_ID']
329
+					: null,
330
+				'DTT_name'        => ! empty($datetime_data['DTT_name'])
331
+					? $datetime_data['DTT_name']
332
+					: '',
333
+				'DTT_description' => ! empty($datetime_data['DTT_description'])
334
+					? $datetime_data['DTT_description']
335
+					: '',
336
+				'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
337
+				'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
338
+				'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
339
+					? EE_INF
340
+					: $datetime_data['DTT_reg_limit'],
341
+				'DTT_order'       => ! isset($datetime_data['DTT_order'])
342
+					? $row
343
+					: $datetime_data['DTT_order'],
344
+			);
345
+			// if we have an id then let's get existing object first and then set the new values.
346
+			// Otherwise we instantiate a new object for save.
347
+			if (! empty($datetime_data['DTT_ID'])) {
348
+				$datetime = EE_Registry::instance()
349
+									   ->load_model('Datetime', array($timezone))
350
+									   ->get_one_by_ID($datetime_data['DTT_ID']);
351
+				// set date and time format according to what is set in this class.
352
+				$datetime->set_date_format($this->_date_format_strings['date']);
353
+				$datetime->set_time_format($this->_date_format_strings['time']);
354
+				foreach ($datetime_values as $field => $value) {
355
+					$datetime->set($field, $value);
356
+				}
357
+				// make sure the $dtt_id here is saved just in case
358
+				// after the add_relation_to() the autosave replaces it.
359
+				// We need to do this so we dont' TRASH the parent DTT.
360
+				// (save the ID for both key and value to avoid duplications)
361
+				$saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
362
+			} else {
363
+				$datetime = EE_Registry::instance()->load_class(
364
+					'Datetime',
365
+					array(
366
+						$datetime_values,
367
+						$timezone,
368
+						array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
369
+					),
370
+					false,
371
+					false
372
+				);
373
+				foreach ($datetime_values as $field => $value) {
374
+					$datetime->set($field, $value);
375
+				}
376
+			}
377
+			$datetime->save();
378
+			do_action(
379
+				'AHEE__espresso_events_Pricing_Hooks___update_datetimes_after_save',
380
+				$datetime,
381
+				$row,
382
+				$datetime_data,
383
+				$data
384
+			);
385
+			$datetime = $event->_add_relation_to($datetime, 'Datetime');
386
+			// before going any further make sure our dates are setup correctly
387
+			// so that the end date is always equal or greater than the start date.
388
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
389
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
390
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
391
+				$datetime->save();
392
+			}
393
+			// now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
394
+			// because it is possible there was a new one created for the autosave.
395
+			// (save the ID for both key and value to avoid duplications)
396
+			$DTT_ID = $datetime->ID();
397
+			$saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
398
+			$saved_dtt_objs[ $row ] = $datetime;
399
+			// @todo if ANY of these updates fail then we want the appropriate global error message.
400
+		}
401
+		$event->save();
402
+		// now we need to REMOVE any datetimes that got deleted.
403
+		// Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
404
+		// So its safe to permanently delete at this point.
405
+		$old_datetimes = explode(',', $data['datetime_IDs']);
406
+		$old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
407
+		if (is_array($old_datetimes)) {
408
+			$datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
409
+			foreach ($datetimes_to_delete as $id) {
410
+				$id = absint($id);
411
+				if (empty($id)) {
412
+					continue;
413
+				}
414
+				/** @var EE_Datetime $dtt_to_remove */
415
+				$dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
416
+				// remove tkt relationships.
417
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
418
+				foreach ($related_tickets as $tkt) {
419
+					$dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
420
+				}
421
+				$event->_remove_relation_to($id, 'Datetime');
422
+				$dtt_to_remove->refresh_cache_of_related_objects();
423
+				$dtt_to_remove->delete_or_restore();
424
+			}
425
+		}
426
+		return $saved_dtt_objs;
427
+	}
428 428
 
429 429
 
430
-    /**
431
-     * update tickets
432
-     *
433
-     * @param  EE_Event      $event           Event object being updated
434
-     * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
435
-     * @param  array         $data            incoming request data
436
-     * @return EE_Ticket[]
437
-     * @throws Exception
438
-     * @throws ReflectionException
439
-     * @throws InvalidInterfaceException
440
-     * @throws InvalidDataTypeException
441
-     * @throws InvalidArgumentException
442
-     * @throws EE_Error
443
-     */
444
-    protected function _update_tickets($event, $saved_datetimes, $data)
445
-    {
446
-        $new_tkt = null;
447
-        // stripslashes because WP filtered the $_POST ($data) array to add slashes
448
-        $data = stripslashes_deep($data);
449
-        $timezone = $data['timezone_string'] ?? null;
450
-        $saved_tickets = array();
451
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
452
-        if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
453
-            throw new InvalidArgumentException(
454
-                esc_html__(
455
-                    'The "edit_tickets" array is invalid therefore the event can not be updated.',
456
-                    'event_espresso'
457
-                )
458
-            );
459
-        }
460
-        foreach ($data['edit_tickets'] as $row => $tkt) {
461
-            $update_prices = $create_new_TKT = false;
462
-            // figure out what datetimes were added to the ticket
463
-            // and what datetimes were removed from the ticket in the session.
464
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
465
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
466
-            $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
467
-            $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
468
-            // trim inputs to ensure any excess whitespace is removed.
469
-            $tkt = array_map(
470
-                function ($ticket_data) {
471
-                    return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
472
-                },
473
-                $tkt
474
-            );
475
-            // note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
476
-            // because we're doing calculations prior to using the models.
477
-            // note incoming ['TKT_price'] value is already in standard notation (via js).
478
-            $ticket_price = isset($tkt['TKT_price'])
479
-                ? round((float) $tkt['TKT_price'], 3)
480
-                : 0;
481
-            // note incoming base price needs converted from localized value.
482
-            $base_price = isset($tkt['TKT_base_price'])
483
-                ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
484
-                : 0;
485
-            // if ticket price == 0 and $base_price != 0 then ticket price == base_price
486
-            $ticket_price = $ticket_price === 0 && $base_price !== 0
487
-                ? $base_price
488
-                : $ticket_price;
489
-            $base_price_id = $tkt['TKT_base_price_ID'] ?? 0;
490
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
491
-                ? $data['edit_prices'][ $row ]
492
-                : array();
493
-            $now = null;
494
-            if (empty($tkt['TKT_start_date'])) {
495
-                // lets' use now in the set timezone.
496
-                $now = new DateTime('now', new DateTimeZone($event->get_timezone()));
497
-                $tkt['TKT_start_date'] = $now->format($this->_date_time_format);
498
-            }
499
-            if (empty($tkt['TKT_end_date'])) {
500
-                /**
501
-                 * set the TKT_end_date to the first datetime attached to the ticket.
502
-                 */
503
-                $first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
504
-                $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
505
-            }
506
-            $TKT_values = array(
507
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
508
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
509
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
510
-                'TKT_description' => ! empty($tkt['TKT_description'])
511
-                                     && $tkt['TKT_description'] !== esc_html__(
512
-                                         'You can modify this description',
513
-                                         'event_espresso'
514
-                                     )
515
-                    ? $tkt['TKT_description']
516
-                    : '',
517
-                'TKT_start_date'  => $tkt['TKT_start_date'],
518
-                'TKT_end_date'    => $tkt['TKT_end_date'],
519
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
520
-                    ? EE_INF
521
-                    : $tkt['TKT_qty'],
522
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
523
-                    ? EE_INF
524
-                    : $tkt['TKT_uses'],
525
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
526
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
527
-                'TKT_row'         => $row,
528
-                'TKT_order'       => $tkt['TKT_order'] ?? 0,
529
-                'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
530
-                'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
531
-                'TKT_price'       => $ticket_price,
532
-            );
533
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
534
-            // which means in turn that the prices will become new prices as well.
535
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
536
-                $TKT_values['TKT_ID'] = 0;
537
-                $TKT_values['TKT_is_default'] = 0;
538
-                $update_prices = true;
539
-            }
540
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
541
-            // we actually do our saves ahead of doing any add_relations to
542
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
543
-            // but DID have it's items modified.
544
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
545
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
546
-            if (absint($TKT_values['TKT_ID'])) {
547
-                $ticket = EE_Registry::instance()
548
-                                     ->load_model('Ticket', array($timezone))
549
-                                     ->get_one_by_ID($tkt['TKT_ID']);
550
-                if ($ticket instanceof EE_Ticket) {
551
-                    $ticket = $this->_update_ticket_datetimes(
552
-                        $ticket,
553
-                        $saved_datetimes,
554
-                        $datetimes_added,
555
-                        $datetimes_removed
556
-                    );
557
-                    // are there any registrations using this ticket ?
558
-                    $tickets_sold = $ticket->count_related(
559
-                        'Registration',
560
-                        array(
561
-                            array(
562
-                                'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
563
-                            ),
564
-                        )
565
-                    );
566
-                    // set ticket formats
567
-                    $ticket->set_date_format($this->_date_format_strings['date']);
568
-                    $ticket->set_time_format($this->_date_format_strings['time']);
569
-                    // let's just check the total price for the existing ticket
570
-                    // and determine if it matches the new total price.
571
-                    // if they are different then we create a new ticket (if tickets sold)
572
-                    // if they aren't different then we go ahead and modify existing ticket.
573
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
574
-                    // set new values
575
-                    foreach ($TKT_values as $field => $value) {
576
-                        if ($field === 'TKT_qty') {
577
-                            $ticket->set_qty($value);
578
-                        } else {
579
-                            $ticket->set($field, $value);
580
-                        }
581
-                    }
582
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
583
-                    // Otherwise we have to create a new ticket.
584
-                    if ($create_new_TKT) {
585
-                        $new_tkt = $this->_duplicate_ticket(
586
-                            $ticket,
587
-                            $price_rows,
588
-                            $ticket_price,
589
-                            $base_price,
590
-                            $base_price_id
591
-                        );
592
-                    }
593
-                }
594
-            } else {
595
-                // no TKT_id so a new TKT
596
-                $ticket = EE_Ticket::new_instance(
597
-                    $TKT_values,
598
-                    $timezone,
599
-                    array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
600
-                );
601
-                if ($ticket instanceof EE_Ticket) {
602
-                    // make sure ticket has an ID of setting relations won't work
603
-                    $ticket->save();
604
-                    $ticket = $this->_update_ticket_datetimes(
605
-                        $ticket,
606
-                        $saved_datetimes,
607
-                        $datetimes_added,
608
-                        $datetimes_removed
609
-                    );
610
-                    $update_prices = true;
611
-                }
612
-            }
613
-            // make sure any current values have been saved.
614
-            // $ticket->save();
615
-            // before going any further make sure our dates are setup correctly
616
-            // so that the end date is always equal or greater than the start date.
617
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
618
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
619
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
620
-            }
621
-            // let's make sure the base price is handled
622
-            $ticket = ! $create_new_TKT
623
-                ? $this->_add_prices_to_ticket(
624
-                    array(),
625
-                    $ticket,
626
-                    $update_prices,
627
-                    $base_price,
628
-                    $base_price_id
629
-                )
630
-                : $ticket;
631
-            // add/update price_modifiers
632
-            $ticket = ! $create_new_TKT
633
-                ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
634
-                : $ticket;
635
-            // need to make sue that the TKT_price is accurate after saving the prices.
636
-            $ticket->ensure_TKT_Price_correct();
637
-            // handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
638
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
639
-                $update_prices = true;
640
-                $new_default = clone $ticket;
641
-                $new_default->set('TKT_ID', 0);
642
-                $new_default->set('TKT_is_default', 1);
643
-                $new_default->set('TKT_row', 1);
644
-                $new_default->set('TKT_price', $ticket_price);
645
-                // remove any dtt relations cause we DON'T want dtt relations attached
646
-                // (note this is just removing the cached relations in the object)
647
-                $new_default->_remove_relations('Datetime');
648
-                // @todo we need to add the current attached prices as new prices to the new default ticket.
649
-                $new_default = $this->_add_prices_to_ticket(
650
-                    $price_rows,
651
-                    $new_default,
652
-                    $update_prices
653
-                );
654
-                // don't forget the base price!
655
-                $new_default = $this->_add_prices_to_ticket(
656
-                    array(),
657
-                    $new_default,
658
-                    $update_prices,
659
-                    $base_price,
660
-                    $base_price_id
661
-                );
662
-                $new_default->save();
663
-                do_action(
664
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
665
-                    $new_default,
666
-                    $row,
667
-                    $ticket,
668
-                    $data
669
-                );
670
-            }
671
-            // DO ALL dtt relationships for both current tickets and any archived tickets
672
-            // for the given dtt that are related to the current ticket.
673
-            // TODO... not sure exactly how we're going to do this considering we don't know
674
-            // what current ticket the archived tickets are related to
675
-            // (and TKT_parent is used for autosaves so that's not a field we can reliably use).
676
-            // let's assign any tickets that have been setup to the saved_tickets tracker
677
-            // save existing TKT
678
-            $ticket->save();
679
-            if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
680
-                // save new TKT
681
-                $new_tkt->save();
682
-                // add new ticket to array
683
-                $saved_tickets[ $new_tkt->ID() ] = $new_tkt;
684
-                do_action(
685
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
686
-                    $new_tkt,
687
-                    $row,
688
-                    $tkt,
689
-                    $data
690
-                );
691
-            } else {
692
-                // add tkt to saved tkts
693
-                $saved_tickets[ $ticket->ID() ] = $ticket;
694
-                do_action(
695
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
696
-                    $ticket,
697
-                    $row,
698
-                    $tkt,
699
-                    $data
700
-                );
701
-            }
702
-        }
703
-        // now we need to handle tickets actually "deleted permanently".
704
-        // There are cases where we'd want this to happen
705
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
706
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
707
-        // No sense in keeping all the related data in the db!
708
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
709
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
710
-        foreach ($tickets_removed as $id) {
711
-            $id = absint($id);
712
-            // get the ticket for this id
713
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
714
-            // if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
715
-            if ($tkt_to_remove->get('TKT_is_default')) {
716
-                continue;
717
-            }
718
-            // if this tkt has any registrations attached so then we just ARCHIVE
719
-            // because we don't actually permanently delete these tickets.
720
-            if ($tkt_to_remove->count_related('Registration') > 0) {
721
-                $tkt_to_remove->delete();
722
-                continue;
723
-            }
724
-            // need to get all the related datetimes on this ticket and remove from every single one of them
725
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
726
-            $datetimes = $tkt_to_remove->get_many_related('Datetime');
727
-            foreach ($datetimes as $datetime) {
728
-                $tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
729
-            }
730
-            // need to do the same for prices (except these prices can also be deleted because again,
731
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
732
-            $tkt_to_remove->delete_related_permanently('Price');
733
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
734
-            // finally let's delete this ticket
735
-            // (which should not be blocked at this point b/c we've removed all our relationships)
736
-            $tkt_to_remove->delete_permanently();
737
-        }
738
-        return $saved_tickets;
739
-    }
430
+	/**
431
+	 * update tickets
432
+	 *
433
+	 * @param  EE_Event      $event           Event object being updated
434
+	 * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
435
+	 * @param  array         $data            incoming request data
436
+	 * @return EE_Ticket[]
437
+	 * @throws Exception
438
+	 * @throws ReflectionException
439
+	 * @throws InvalidInterfaceException
440
+	 * @throws InvalidDataTypeException
441
+	 * @throws InvalidArgumentException
442
+	 * @throws EE_Error
443
+	 */
444
+	protected function _update_tickets($event, $saved_datetimes, $data)
445
+	{
446
+		$new_tkt = null;
447
+		// stripslashes because WP filtered the $_POST ($data) array to add slashes
448
+		$data = stripslashes_deep($data);
449
+		$timezone = $data['timezone_string'] ?? null;
450
+		$saved_tickets = array();
451
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
452
+		if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
453
+			throw new InvalidArgumentException(
454
+				esc_html__(
455
+					'The "edit_tickets" array is invalid therefore the event can not be updated.',
456
+					'event_espresso'
457
+				)
458
+			);
459
+		}
460
+		foreach ($data['edit_tickets'] as $row => $tkt) {
461
+			$update_prices = $create_new_TKT = false;
462
+			// figure out what datetimes were added to the ticket
463
+			// and what datetimes were removed from the ticket in the session.
464
+			$starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
465
+			$tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
466
+			$datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
467
+			$datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
468
+			// trim inputs to ensure any excess whitespace is removed.
469
+			$tkt = array_map(
470
+				function ($ticket_data) {
471
+					return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
472
+				},
473
+				$tkt
474
+			);
475
+			// note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
476
+			// because we're doing calculations prior to using the models.
477
+			// note incoming ['TKT_price'] value is already in standard notation (via js).
478
+			$ticket_price = isset($tkt['TKT_price'])
479
+				? round((float) $tkt['TKT_price'], 3)
480
+				: 0;
481
+			// note incoming base price needs converted from localized value.
482
+			$base_price = isset($tkt['TKT_base_price'])
483
+				? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
484
+				: 0;
485
+			// if ticket price == 0 and $base_price != 0 then ticket price == base_price
486
+			$ticket_price = $ticket_price === 0 && $base_price !== 0
487
+				? $base_price
488
+				: $ticket_price;
489
+			$base_price_id = $tkt['TKT_base_price_ID'] ?? 0;
490
+			$price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
491
+				? $data['edit_prices'][ $row ]
492
+				: array();
493
+			$now = null;
494
+			if (empty($tkt['TKT_start_date'])) {
495
+				// lets' use now in the set timezone.
496
+				$now = new DateTime('now', new DateTimeZone($event->get_timezone()));
497
+				$tkt['TKT_start_date'] = $now->format($this->_date_time_format);
498
+			}
499
+			if (empty($tkt['TKT_end_date'])) {
500
+				/**
501
+				 * set the TKT_end_date to the first datetime attached to the ticket.
502
+				 */
503
+				$first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
504
+				$tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
505
+			}
506
+			$TKT_values = array(
507
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
508
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
509
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
510
+				'TKT_description' => ! empty($tkt['TKT_description'])
511
+									 && $tkt['TKT_description'] !== esc_html__(
512
+										 'You can modify this description',
513
+										 'event_espresso'
514
+									 )
515
+					? $tkt['TKT_description']
516
+					: '',
517
+				'TKT_start_date'  => $tkt['TKT_start_date'],
518
+				'TKT_end_date'    => $tkt['TKT_end_date'],
519
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
520
+					? EE_INF
521
+					: $tkt['TKT_qty'],
522
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
523
+					? EE_INF
524
+					: $tkt['TKT_uses'],
525
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
526
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
527
+				'TKT_row'         => $row,
528
+				'TKT_order'       => $tkt['TKT_order'] ?? 0,
529
+				'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
530
+				'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
531
+				'TKT_price'       => $ticket_price,
532
+			);
533
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
534
+			// which means in turn that the prices will become new prices as well.
535
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
536
+				$TKT_values['TKT_ID'] = 0;
537
+				$TKT_values['TKT_is_default'] = 0;
538
+				$update_prices = true;
539
+			}
540
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
541
+			// we actually do our saves ahead of doing any add_relations to
542
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
543
+			// but DID have it's items modified.
544
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
545
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
546
+			if (absint($TKT_values['TKT_ID'])) {
547
+				$ticket = EE_Registry::instance()
548
+									 ->load_model('Ticket', array($timezone))
549
+									 ->get_one_by_ID($tkt['TKT_ID']);
550
+				if ($ticket instanceof EE_Ticket) {
551
+					$ticket = $this->_update_ticket_datetimes(
552
+						$ticket,
553
+						$saved_datetimes,
554
+						$datetimes_added,
555
+						$datetimes_removed
556
+					);
557
+					// are there any registrations using this ticket ?
558
+					$tickets_sold = $ticket->count_related(
559
+						'Registration',
560
+						array(
561
+							array(
562
+								'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
563
+							),
564
+						)
565
+					);
566
+					// set ticket formats
567
+					$ticket->set_date_format($this->_date_format_strings['date']);
568
+					$ticket->set_time_format($this->_date_format_strings['time']);
569
+					// let's just check the total price for the existing ticket
570
+					// and determine if it matches the new total price.
571
+					// if they are different then we create a new ticket (if tickets sold)
572
+					// if they aren't different then we go ahead and modify existing ticket.
573
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
574
+					// set new values
575
+					foreach ($TKT_values as $field => $value) {
576
+						if ($field === 'TKT_qty') {
577
+							$ticket->set_qty($value);
578
+						} else {
579
+							$ticket->set($field, $value);
580
+						}
581
+					}
582
+					// if $create_new_TKT is false then we can safely update the existing ticket.
583
+					// Otherwise we have to create a new ticket.
584
+					if ($create_new_TKT) {
585
+						$new_tkt = $this->_duplicate_ticket(
586
+							$ticket,
587
+							$price_rows,
588
+							$ticket_price,
589
+							$base_price,
590
+							$base_price_id
591
+						);
592
+					}
593
+				}
594
+			} else {
595
+				// no TKT_id so a new TKT
596
+				$ticket = EE_Ticket::new_instance(
597
+					$TKT_values,
598
+					$timezone,
599
+					array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
600
+				);
601
+				if ($ticket instanceof EE_Ticket) {
602
+					// make sure ticket has an ID of setting relations won't work
603
+					$ticket->save();
604
+					$ticket = $this->_update_ticket_datetimes(
605
+						$ticket,
606
+						$saved_datetimes,
607
+						$datetimes_added,
608
+						$datetimes_removed
609
+					);
610
+					$update_prices = true;
611
+				}
612
+			}
613
+			// make sure any current values have been saved.
614
+			// $ticket->save();
615
+			// before going any further make sure our dates are setup correctly
616
+			// so that the end date is always equal or greater than the start date.
617
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
618
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
619
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
620
+			}
621
+			// let's make sure the base price is handled
622
+			$ticket = ! $create_new_TKT
623
+				? $this->_add_prices_to_ticket(
624
+					array(),
625
+					$ticket,
626
+					$update_prices,
627
+					$base_price,
628
+					$base_price_id
629
+				)
630
+				: $ticket;
631
+			// add/update price_modifiers
632
+			$ticket = ! $create_new_TKT
633
+				? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
634
+				: $ticket;
635
+			// need to make sue that the TKT_price is accurate after saving the prices.
636
+			$ticket->ensure_TKT_Price_correct();
637
+			// handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
638
+			if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
639
+				$update_prices = true;
640
+				$new_default = clone $ticket;
641
+				$new_default->set('TKT_ID', 0);
642
+				$new_default->set('TKT_is_default', 1);
643
+				$new_default->set('TKT_row', 1);
644
+				$new_default->set('TKT_price', $ticket_price);
645
+				// remove any dtt relations cause we DON'T want dtt relations attached
646
+				// (note this is just removing the cached relations in the object)
647
+				$new_default->_remove_relations('Datetime');
648
+				// @todo we need to add the current attached prices as new prices to the new default ticket.
649
+				$new_default = $this->_add_prices_to_ticket(
650
+					$price_rows,
651
+					$new_default,
652
+					$update_prices
653
+				);
654
+				// don't forget the base price!
655
+				$new_default = $this->_add_prices_to_ticket(
656
+					array(),
657
+					$new_default,
658
+					$update_prices,
659
+					$base_price,
660
+					$base_price_id
661
+				);
662
+				$new_default->save();
663
+				do_action(
664
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
665
+					$new_default,
666
+					$row,
667
+					$ticket,
668
+					$data
669
+				);
670
+			}
671
+			// DO ALL dtt relationships for both current tickets and any archived tickets
672
+			// for the given dtt that are related to the current ticket.
673
+			// TODO... not sure exactly how we're going to do this considering we don't know
674
+			// what current ticket the archived tickets are related to
675
+			// (and TKT_parent is used for autosaves so that's not a field we can reliably use).
676
+			// let's assign any tickets that have been setup to the saved_tickets tracker
677
+			// save existing TKT
678
+			$ticket->save();
679
+			if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
680
+				// save new TKT
681
+				$new_tkt->save();
682
+				// add new ticket to array
683
+				$saved_tickets[ $new_tkt->ID() ] = $new_tkt;
684
+				do_action(
685
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
686
+					$new_tkt,
687
+					$row,
688
+					$tkt,
689
+					$data
690
+				);
691
+			} else {
692
+				// add tkt to saved tkts
693
+				$saved_tickets[ $ticket->ID() ] = $ticket;
694
+				do_action(
695
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
696
+					$ticket,
697
+					$row,
698
+					$tkt,
699
+					$data
700
+				);
701
+			}
702
+		}
703
+		// now we need to handle tickets actually "deleted permanently".
704
+		// There are cases where we'd want this to happen
705
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
706
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
707
+		// No sense in keeping all the related data in the db!
708
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
709
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
710
+		foreach ($tickets_removed as $id) {
711
+			$id = absint($id);
712
+			// get the ticket for this id
713
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
714
+			// if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
715
+			if ($tkt_to_remove->get('TKT_is_default')) {
716
+				continue;
717
+			}
718
+			// if this tkt has any registrations attached so then we just ARCHIVE
719
+			// because we don't actually permanently delete these tickets.
720
+			if ($tkt_to_remove->count_related('Registration') > 0) {
721
+				$tkt_to_remove->delete();
722
+				continue;
723
+			}
724
+			// need to get all the related datetimes on this ticket and remove from every single one of them
725
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
726
+			$datetimes = $tkt_to_remove->get_many_related('Datetime');
727
+			foreach ($datetimes as $datetime) {
728
+				$tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
729
+			}
730
+			// need to do the same for prices (except these prices can also be deleted because again,
731
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
732
+			$tkt_to_remove->delete_related_permanently('Price');
733
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
734
+			// finally let's delete this ticket
735
+			// (which should not be blocked at this point b/c we've removed all our relationships)
736
+			$tkt_to_remove->delete_permanently();
737
+		}
738
+		return $saved_tickets;
739
+	}
740 740
 
741 741
 
742
-    /**
743
-     * @access  protected
744
-     * @param EE_Ticket      $ticket
745
-     * @param \EE_Datetime[] $saved_datetimes
746
-     * @param \EE_Datetime[] $added_datetimes
747
-     * @param \EE_Datetime[] $removed_datetimes
748
-     * @return EE_Ticket
749
-     * @throws EE_Error
750
-     */
751
-    protected function _update_ticket_datetimes(
752
-        EE_Ticket $ticket,
753
-        $saved_datetimes = array(),
754
-        $added_datetimes = array(),
755
-        $removed_datetimes = array()
756
-    ) {
757
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
758
-        // and removing the ticket from datetimes it got removed from.
759
-        // first let's add datetimes
760
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
761
-            foreach ($added_datetimes as $row_id) {
762
-                $row_id = (int) $row_id;
763
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
764
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
765
-                    // Is this an existing ticket (has an ID) and does it have any sold?
766
-                    // If so, then we need to add that to the DTT sold because this DTT is getting added.
767
-                    if ($ticket->ID() && $ticket->sold() > 0) {
768
-                        $saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
769
-                    }
770
-                }
771
-            }
772
-        }
773
-        // then remove datetimes
774
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
775
-            foreach ($removed_datetimes as $row_id) {
776
-                $row_id = (int) $row_id;
777
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
778
-                // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
779
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
780
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
781
-                    // Is this an existing ticket (has an ID) and does it have any sold?
782
-                    // If so, then we need to remove it's sold from the DTT_sold.
783
-                    if ($ticket->ID() && $ticket->sold() > 0) {
784
-                        $saved_datetimes[ $row_id ]->decreaseSold($ticket->sold());
785
-                    }
786
-                }
787
-            }
788
-        }
789
-        // cap ticket qty by datetime reg limits
790
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
791
-        return $ticket;
792
-    }
742
+	/**
743
+	 * @access  protected
744
+	 * @param EE_Ticket      $ticket
745
+	 * @param \EE_Datetime[] $saved_datetimes
746
+	 * @param \EE_Datetime[] $added_datetimes
747
+	 * @param \EE_Datetime[] $removed_datetimes
748
+	 * @return EE_Ticket
749
+	 * @throws EE_Error
750
+	 */
751
+	protected function _update_ticket_datetimes(
752
+		EE_Ticket $ticket,
753
+		$saved_datetimes = array(),
754
+		$added_datetimes = array(),
755
+		$removed_datetimes = array()
756
+	) {
757
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
758
+		// and removing the ticket from datetimes it got removed from.
759
+		// first let's add datetimes
760
+		if (! empty($added_datetimes) && is_array($added_datetimes)) {
761
+			foreach ($added_datetimes as $row_id) {
762
+				$row_id = (int) $row_id;
763
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
764
+					$ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
765
+					// Is this an existing ticket (has an ID) and does it have any sold?
766
+					// If so, then we need to add that to the DTT sold because this DTT is getting added.
767
+					if ($ticket->ID() && $ticket->sold() > 0) {
768
+						$saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
769
+					}
770
+				}
771
+			}
772
+		}
773
+		// then remove datetimes
774
+		if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
775
+			foreach ($removed_datetimes as $row_id) {
776
+				$row_id = (int) $row_id;
777
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
778
+				// So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
779
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
780
+					$ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
781
+					// Is this an existing ticket (has an ID) and does it have any sold?
782
+					// If so, then we need to remove it's sold from the DTT_sold.
783
+					if ($ticket->ID() && $ticket->sold() > 0) {
784
+						$saved_datetimes[ $row_id ]->decreaseSold($ticket->sold());
785
+					}
786
+				}
787
+			}
788
+		}
789
+		// cap ticket qty by datetime reg limits
790
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
791
+		return $ticket;
792
+	}
793 793
 
794 794
 
795
-    /**
796
-     * @access  protected
797
-     * @param EE_Ticket $ticket
798
-     * @param array     $price_rows
799
-     * @param int       $ticket_price
800
-     * @param int       $base_price
801
-     * @param int       $base_price_id
802
-     * @return EE_Ticket
803
-     * @throws ReflectionException
804
-     * @throws InvalidArgumentException
805
-     * @throws InvalidInterfaceException
806
-     * @throws InvalidDataTypeException
807
-     * @throws EE_Error
808
-     */
809
-    protected function _duplicate_ticket(
810
-        EE_Ticket $ticket,
811
-        $price_rows = array(),
812
-        $ticket_price = 0,
813
-        $base_price = 0,
814
-        $base_price_id = 0
815
-    ) {
816
-        // create new ticket that's a copy of the existing
817
-        // except a new id of course (and not archived)
818
-        // AND has the new TKT_price associated with it.
819
-        $new_ticket = clone $ticket;
820
-        $new_ticket->set('TKT_ID', 0);
821
-        $new_ticket->set_deleted(0);
822
-        $new_ticket->set_price($ticket_price);
823
-        $new_ticket->set_sold(0);
824
-        // let's get a new ID for this ticket
825
-        $new_ticket->save();
826
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
827
-        $datetimes_on_existing = $ticket->datetimes();
828
-        $new_ticket = $this->_update_ticket_datetimes(
829
-            $new_ticket,
830
-            $datetimes_on_existing,
831
-            array_keys($datetimes_on_existing)
832
-        );
833
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
834
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
835
-        // available.
836
-        if ($ticket->sold() > 0) {
837
-            $new_qty = $ticket->qty() - $ticket->sold();
838
-            $new_ticket->set_qty($new_qty);
839
-        }
840
-        // now we update the prices just for this ticket
841
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
842
-        // and we update the base price
843
-        $new_ticket = $this->_add_prices_to_ticket(
844
-            array(),
845
-            $new_ticket,
846
-            true,
847
-            $base_price,
848
-            $base_price_id
849
-        );
850
-        return $new_ticket;
851
-    }
795
+	/**
796
+	 * @access  protected
797
+	 * @param EE_Ticket $ticket
798
+	 * @param array     $price_rows
799
+	 * @param int       $ticket_price
800
+	 * @param int       $base_price
801
+	 * @param int       $base_price_id
802
+	 * @return EE_Ticket
803
+	 * @throws ReflectionException
804
+	 * @throws InvalidArgumentException
805
+	 * @throws InvalidInterfaceException
806
+	 * @throws InvalidDataTypeException
807
+	 * @throws EE_Error
808
+	 */
809
+	protected function _duplicate_ticket(
810
+		EE_Ticket $ticket,
811
+		$price_rows = array(),
812
+		$ticket_price = 0,
813
+		$base_price = 0,
814
+		$base_price_id = 0
815
+	) {
816
+		// create new ticket that's a copy of the existing
817
+		// except a new id of course (and not archived)
818
+		// AND has the new TKT_price associated with it.
819
+		$new_ticket = clone $ticket;
820
+		$new_ticket->set('TKT_ID', 0);
821
+		$new_ticket->set_deleted(0);
822
+		$new_ticket->set_price($ticket_price);
823
+		$new_ticket->set_sold(0);
824
+		// let's get a new ID for this ticket
825
+		$new_ticket->save();
826
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
827
+		$datetimes_on_existing = $ticket->datetimes();
828
+		$new_ticket = $this->_update_ticket_datetimes(
829
+			$new_ticket,
830
+			$datetimes_on_existing,
831
+			array_keys($datetimes_on_existing)
832
+		);
833
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
834
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
835
+		// available.
836
+		if ($ticket->sold() > 0) {
837
+			$new_qty = $ticket->qty() - $ticket->sold();
838
+			$new_ticket->set_qty($new_qty);
839
+		}
840
+		// now we update the prices just for this ticket
841
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
842
+		// and we update the base price
843
+		$new_ticket = $this->_add_prices_to_ticket(
844
+			array(),
845
+			$new_ticket,
846
+			true,
847
+			$base_price,
848
+			$base_price_id
849
+		);
850
+		return $new_ticket;
851
+	}
852 852
 
853 853
 
854
-    /**
855
-     * This attaches a list of given prices to a ticket.
856
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
857
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
858
-     * price info and prices are automatically "archived" via the ticket.
859
-     *
860
-     * @access  private
861
-     * @param array     $prices        Array of prices from the form.
862
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
863
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
864
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
865
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
866
-     * @return EE_Ticket
867
-     * @throws ReflectionException
868
-     * @throws InvalidArgumentException
869
-     * @throws InvalidInterfaceException
870
-     * @throws InvalidDataTypeException
871
-     * @throws EE_Error
872
-     */
873
-    protected function _add_prices_to_ticket(
874
-        array $prices,
875
-        EE_Ticket $ticket,
876
-        $new_prices = false,
877
-        $base_price = false,
878
-        $base_price_id = false
879
-    ) {
880
-        // let's just get any current prices that may exist on the given ticket
881
-        // so we can remove any prices that got trashed in this session.
882
-        $current_prices_on_ticket = $base_price !== false
883
-            ? $ticket->base_price(true)
884
-            : $ticket->price_modifiers();
885
-        $updated_prices = array();
886
-        // if $base_price ! FALSE then updating a base price.
887
-        if ($base_price !== false) {
888
-            $prices[1] = array(
889
-                'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
890
-                'PRT_ID'     => 1,
891
-                'PRC_amount' => $base_price,
892
-                'PRC_name'   => $ticket->get('TKT_name'),
893
-                'PRC_desc'   => $ticket->get('TKT_description'),
894
-            );
895
-        }
896
-        // possibly need to save tkt
897
-        if (! $ticket->ID()) {
898
-            $ticket->save();
899
-        }
900
-        foreach ($prices as $row => $prc) {
901
-            $prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
902
-            if (empty($prt_id)) {
903
-                continue;
904
-            } //prices MUST have a price type id.
905
-            $PRC_values = array(
906
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
907
-                'PRT_ID'         => $prt_id,
908
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
909
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
910
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
911
-                'PRC_is_default' => false,
912
-                // make sure we set PRC_is_default to false for all ticket saves from event_editor
913
-                'PRC_order'      => $row,
914
-            );
915
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
916
-                $PRC_values['PRC_ID'] = 0;
917
-                $price = EE_Registry::instance()->load_class(
918
-                    'Price',
919
-                    array($PRC_values),
920
-                    false,
921
-                    false
922
-                );
923
-            } else {
924
-                $price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
925
-                // update this price with new values
926
-                foreach ($PRC_values as $field => $value) {
927
-                    $price->set($field, $value);
928
-                }
929
-            }
930
-            $price->save();
931
-            $updated_prices[ $price->ID() ] = $price;
932
-            $ticket->_add_relation_to($price, 'Price');
933
-        }
934
-        // now let's remove any prices that got removed from the ticket
935
-        if (! empty($current_prices_on_ticket)) {
936
-            $current = array_keys($current_prices_on_ticket);
937
-            $updated = array_keys($updated_prices);
938
-            $prices_to_remove = array_diff($current, $updated);
939
-            if (! empty($prices_to_remove)) {
940
-                foreach ($prices_to_remove as $prc_id) {
941
-                    $p = $current_prices_on_ticket[ $prc_id ];
942
-                    $ticket->_remove_relation_to($p, 'Price');
943
-                    // delete permanently the price
944
-                    $p->delete_permanently();
945
-                }
946
-            }
947
-        }
948
-        return $ticket;
949
-    }
854
+	/**
855
+	 * This attaches a list of given prices to a ticket.
856
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
857
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
858
+	 * price info and prices are automatically "archived" via the ticket.
859
+	 *
860
+	 * @access  private
861
+	 * @param array     $prices        Array of prices from the form.
862
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
863
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
864
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
865
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
866
+	 * @return EE_Ticket
867
+	 * @throws ReflectionException
868
+	 * @throws InvalidArgumentException
869
+	 * @throws InvalidInterfaceException
870
+	 * @throws InvalidDataTypeException
871
+	 * @throws EE_Error
872
+	 */
873
+	protected function _add_prices_to_ticket(
874
+		array $prices,
875
+		EE_Ticket $ticket,
876
+		$new_prices = false,
877
+		$base_price = false,
878
+		$base_price_id = false
879
+	) {
880
+		// let's just get any current prices that may exist on the given ticket
881
+		// so we can remove any prices that got trashed in this session.
882
+		$current_prices_on_ticket = $base_price !== false
883
+			? $ticket->base_price(true)
884
+			: $ticket->price_modifiers();
885
+		$updated_prices = array();
886
+		// if $base_price ! FALSE then updating a base price.
887
+		if ($base_price !== false) {
888
+			$prices[1] = array(
889
+				'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
890
+				'PRT_ID'     => 1,
891
+				'PRC_amount' => $base_price,
892
+				'PRC_name'   => $ticket->get('TKT_name'),
893
+				'PRC_desc'   => $ticket->get('TKT_description'),
894
+			);
895
+		}
896
+		// possibly need to save tkt
897
+		if (! $ticket->ID()) {
898
+			$ticket->save();
899
+		}
900
+		foreach ($prices as $row => $prc) {
901
+			$prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
902
+			if (empty($prt_id)) {
903
+				continue;
904
+			} //prices MUST have a price type id.
905
+			$PRC_values = array(
906
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
907
+				'PRT_ID'         => $prt_id,
908
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
909
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
910
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
911
+				'PRC_is_default' => false,
912
+				// make sure we set PRC_is_default to false for all ticket saves from event_editor
913
+				'PRC_order'      => $row,
914
+			);
915
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
916
+				$PRC_values['PRC_ID'] = 0;
917
+				$price = EE_Registry::instance()->load_class(
918
+					'Price',
919
+					array($PRC_values),
920
+					false,
921
+					false
922
+				);
923
+			} else {
924
+				$price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
925
+				// update this price with new values
926
+				foreach ($PRC_values as $field => $value) {
927
+					$price->set($field, $value);
928
+				}
929
+			}
930
+			$price->save();
931
+			$updated_prices[ $price->ID() ] = $price;
932
+			$ticket->_add_relation_to($price, 'Price');
933
+		}
934
+		// now let's remove any prices that got removed from the ticket
935
+		if (! empty($current_prices_on_ticket)) {
936
+			$current = array_keys($current_prices_on_ticket);
937
+			$updated = array_keys($updated_prices);
938
+			$prices_to_remove = array_diff($current, $updated);
939
+			if (! empty($prices_to_remove)) {
940
+				foreach ($prices_to_remove as $prc_id) {
941
+					$p = $current_prices_on_ticket[ $prc_id ];
942
+					$ticket->_remove_relation_to($p, 'Price');
943
+					// delete permanently the price
944
+					$p->delete_permanently();
945
+				}
946
+			}
947
+		}
948
+		return $ticket;
949
+	}
950 950
 
951 951
 
952
-    /**
953
-     * @param Events_Admin_Page $event_admin_obj
954
-     * @return Events_Admin_Page
955
-     */
956
-    public function autosave_handling(Events_Admin_Page $event_admin_obj)
957
-    {
958
-        return $event_admin_obj;
959
-        // doing nothing for the moment.
960
-        // todo when I get to this remember that I need to set the template args on the $event_admin_obj
961
-        // (use the set_template_args() method)
962
-        /**
963
-         * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
964
-         * 1. TKT_is_default_selector (visible)
965
-         * 2. TKT_is_default (hidden)
966
-         * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
967
-         * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
968
-         * this ticket to be saved as a default.
969
-         * The tricky part is, on an initial display on create or edit (or after manually updating),
970
-         * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
971
-         * if this is a create.  However, after an autosave, users will want some sort of indicator that
972
-         * the TKT HAS been saved as a default..
973
-         * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
974
-         * On Autosave:
975
-         * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
976
-         * then set the TKT_is_default to false.
977
-         * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
978
-         *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
979
-         * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
980
-         */
981
-    }
952
+	/**
953
+	 * @param Events_Admin_Page $event_admin_obj
954
+	 * @return Events_Admin_Page
955
+	 */
956
+	public function autosave_handling(Events_Admin_Page $event_admin_obj)
957
+	{
958
+		return $event_admin_obj;
959
+		// doing nothing for the moment.
960
+		// todo when I get to this remember that I need to set the template args on the $event_admin_obj
961
+		// (use the set_template_args() method)
962
+		/**
963
+		 * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
964
+		 * 1. TKT_is_default_selector (visible)
965
+		 * 2. TKT_is_default (hidden)
966
+		 * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
967
+		 * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
968
+		 * this ticket to be saved as a default.
969
+		 * The tricky part is, on an initial display on create or edit (or after manually updating),
970
+		 * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
971
+		 * if this is a create.  However, after an autosave, users will want some sort of indicator that
972
+		 * the TKT HAS been saved as a default..
973
+		 * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
974
+		 * On Autosave:
975
+		 * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
976
+		 * then set the TKT_is_default to false.
977
+		 * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
978
+		 *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
979
+		 * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
980
+		 */
981
+	}
982 982
 
983 983
 
984
-    /**
985
-     * @throws ReflectionException
986
-     * @throws InvalidArgumentException
987
-     * @throws InvalidInterfaceException
988
-     * @throws InvalidDataTypeException
989
-     * @throws DomainException
990
-     * @throws EE_Error
991
-     */
992
-    public function pricing_metabox()
993
-    {
994
-        $existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
995
-        $event = $this->_adminpage_obj->get_cpt_model_obj();
996
-        // set is_creating_event property.
997
-        $EVT_ID = $event->ID();
998
-        $this->_is_creating_event = empty($this->_req_data['post']);
999
-        // default main template args
1000
-        $main_template_args = array(
1001
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link(
1002
-                'event_editor_event_datetimes_help_tab',
1003
-                $this->_adminpage_obj->page_slug,
1004
-                $this->_adminpage_obj->get_req_action(),
1005
-                false,
1006
-                false
1007
-            ),
1008
-            // todo need to add a filter to the template for the help text
1009
-            // in the Events_Admin_Page core file so we can add further help
1010
-            'existing_datetime_ids'    => '',
1011
-            'total_dtt_rows'           => 1,
1012
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1013
-                'add_new_dtt_info',
1014
-                $this->_adminpage_obj->page_slug,
1015
-                $this->_adminpage_obj->get_req_action(),
1016
-                false,
1017
-                false
1018
-            ),
1019
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1020
-            'datetime_rows'            => '',
1021
-            'show_tickets_container'   => '',
1022
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1023
-            'ticket_rows'              => '',
1024
-            'existing_ticket_ids'      => '',
1025
-            'total_ticket_rows'        => 1,
1026
-            'ticket_js_structure'      => '',
1027
-            'ee_collapsible_status'    => ' ee-collapsible-open'
1028
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1029
-        );
1030
-        $timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1031
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1032
-        /**
1033
-         * 1. Start with retrieving Datetimes
1034
-         * 2. For each datetime get related tickets
1035
-         * 3. For each ticket get related prices
1036
-         */
1037
-        /** @var EEM_Datetime $datetime_model */
1038
-        $datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1039
-        $datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1040
-        $main_template_args['total_dtt_rows'] = count($datetimes);
1041
-        /**
1042
-         * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1043
-         * for why we are counting $datetime_row and then setting that on the Datetime object
1044
-         */
1045
-        $datetime_row = 1;
1046
-        foreach ($datetimes as $datetime) {
1047
-            $DTT_ID = $datetime->get('DTT_ID');
1048
-            $datetime->set('DTT_order', $datetime_row);
1049
-            $existing_datetime_ids[] = $DTT_ID;
1050
-            // tickets attached
1051
-            $related_tickets = $datetime->ID() > 0
1052
-                ? $datetime->get_many_related(
1053
-                    'Ticket',
1054
-                    array(
1055
-                        array(
1056
-                            'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1057
-                        ),
1058
-                        'default_where_conditions' => 'none',
1059
-                        'order_by'                 => array('TKT_order' => 'ASC'),
1060
-                    )
1061
-                )
1062
-                : array();
1063
-            // if there are no related tickets this is likely a new event OR autodraft
1064
-            // event so we need to generate the default tickets because datetimes
1065
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1066
-            // datetime on the event.
1067
-            if (empty($related_tickets) && count($datetimes) < 2) {
1068
-                /** @var EEM_Ticket $ticket_model */
1069
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
1070
-                $related_tickets = $ticket_model->get_all_default_tickets();
1071
-                // this should be ordered by TKT_ID, so let's grab the first default ticket
1072
-                // (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1073
-                $default_prices = EEM_Price::instance()->get_all_default_prices();
1074
-                $main_default_ticket = reset($related_tickets);
1075
-                if ($main_default_ticket instanceof EE_Ticket) {
1076
-                    foreach ($default_prices as $default_price) {
1077
-                        if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1078
-                            continue;
1079
-                        }
1080
-                        $main_default_ticket->cache('Price', $default_price);
1081
-                    }
1082
-                }
1083
-            }
1084
-            // we can't actually setup rows in this loop yet cause we don't know all
1085
-            // the unique tickets for this event yet (tickets are linked through all datetimes).
1086
-            // So we're going to temporarily cache some of that information.
1087
-            // loop through and setup the ticket rows and make sure the order is set.
1088
-            foreach ($related_tickets as $ticket) {
1089
-                $TKT_ID = $ticket->get('TKT_ID');
1090
-                $ticket_row = $ticket->get('TKT_row');
1091
-                // we only want unique tickets in our final display!!
1092
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1093
-                    $existing_ticket_ids[] = $TKT_ID;
1094
-                    $all_tickets[] = $ticket;
1095
-                }
1096
-                // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1097
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1098
-                // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1099
-                if (
1100
-                    ! isset($ticket_datetimes[ $TKT_ID ])
1101
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1102
-                ) {
1103
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1104
-                }
1105
-            }
1106
-            $datetime_row++;
1107
-        }
1108
-        $main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1109
-        $main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1110
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1111
-        // sort $all_tickets by order
1112
-        usort(
1113
-            $all_tickets,
1114
-            function (EE_Ticket $a, EE_Ticket $b) {
1115
-                $a_order = (int) $a->get('TKT_order');
1116
-                $b_order = (int) $b->get('TKT_order');
1117
-                if ($a_order === $b_order) {
1118
-                    return 0;
1119
-                }
1120
-                return ($a_order < $b_order) ? -1 : 1;
1121
-            }
1122
-        );
1123
-        // k NOW we have all the data we need for setting up the dtt rows
1124
-        // and ticket rows so we start our dtt loop again.
1125
-        $datetime_row = 1;
1126
-        foreach ($datetimes as $datetime) {
1127
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1128
-                $datetime_row,
1129
-                $datetime,
1130
-                $datetime_tickets,
1131
-                $all_tickets,
1132
-                false,
1133
-                $datetimes
1134
-            );
1135
-            $datetime_row++;
1136
-        }
1137
-        // then loop through all tickets for the ticket rows.
1138
-        $ticket_row = 1;
1139
-        foreach ($all_tickets as $ticket) {
1140
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1141
-                $ticket_row,
1142
-                $ticket,
1143
-                $ticket_datetimes,
1144
-                $datetimes,
1145
-                false,
1146
-                $all_tickets
1147
-            );
1148
-            $ticket_row++;
1149
-        }
1150
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1151
-        EEH_Template::display_template(
1152
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1153
-            $main_template_args
1154
-        );
1155
-    }
984
+	/**
985
+	 * @throws ReflectionException
986
+	 * @throws InvalidArgumentException
987
+	 * @throws InvalidInterfaceException
988
+	 * @throws InvalidDataTypeException
989
+	 * @throws DomainException
990
+	 * @throws EE_Error
991
+	 */
992
+	public function pricing_metabox()
993
+	{
994
+		$existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
995
+		$event = $this->_adminpage_obj->get_cpt_model_obj();
996
+		// set is_creating_event property.
997
+		$EVT_ID = $event->ID();
998
+		$this->_is_creating_event = empty($this->_req_data['post']);
999
+		// default main template args
1000
+		$main_template_args = array(
1001
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link(
1002
+				'event_editor_event_datetimes_help_tab',
1003
+				$this->_adminpage_obj->page_slug,
1004
+				$this->_adminpage_obj->get_req_action(),
1005
+				false,
1006
+				false
1007
+			),
1008
+			// todo need to add a filter to the template for the help text
1009
+			// in the Events_Admin_Page core file so we can add further help
1010
+			'existing_datetime_ids'    => '',
1011
+			'total_dtt_rows'           => 1,
1012
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1013
+				'add_new_dtt_info',
1014
+				$this->_adminpage_obj->page_slug,
1015
+				$this->_adminpage_obj->get_req_action(),
1016
+				false,
1017
+				false
1018
+			),
1019
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1020
+			'datetime_rows'            => '',
1021
+			'show_tickets_container'   => '',
1022
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1023
+			'ticket_rows'              => '',
1024
+			'existing_ticket_ids'      => '',
1025
+			'total_ticket_rows'        => 1,
1026
+			'ticket_js_structure'      => '',
1027
+			'ee_collapsible_status'    => ' ee-collapsible-open'
1028
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1029
+		);
1030
+		$timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1031
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1032
+		/**
1033
+		 * 1. Start with retrieving Datetimes
1034
+		 * 2. For each datetime get related tickets
1035
+		 * 3. For each ticket get related prices
1036
+		 */
1037
+		/** @var EEM_Datetime $datetime_model */
1038
+		$datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1039
+		$datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1040
+		$main_template_args['total_dtt_rows'] = count($datetimes);
1041
+		/**
1042
+		 * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1043
+		 * for why we are counting $datetime_row and then setting that on the Datetime object
1044
+		 */
1045
+		$datetime_row = 1;
1046
+		foreach ($datetimes as $datetime) {
1047
+			$DTT_ID = $datetime->get('DTT_ID');
1048
+			$datetime->set('DTT_order', $datetime_row);
1049
+			$existing_datetime_ids[] = $DTT_ID;
1050
+			// tickets attached
1051
+			$related_tickets = $datetime->ID() > 0
1052
+				? $datetime->get_many_related(
1053
+					'Ticket',
1054
+					array(
1055
+						array(
1056
+							'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1057
+						),
1058
+						'default_where_conditions' => 'none',
1059
+						'order_by'                 => array('TKT_order' => 'ASC'),
1060
+					)
1061
+				)
1062
+				: array();
1063
+			// if there are no related tickets this is likely a new event OR autodraft
1064
+			// event so we need to generate the default tickets because datetimes
1065
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1066
+			// datetime on the event.
1067
+			if (empty($related_tickets) && count($datetimes) < 2) {
1068
+				/** @var EEM_Ticket $ticket_model */
1069
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
1070
+				$related_tickets = $ticket_model->get_all_default_tickets();
1071
+				// this should be ordered by TKT_ID, so let's grab the first default ticket
1072
+				// (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1073
+				$default_prices = EEM_Price::instance()->get_all_default_prices();
1074
+				$main_default_ticket = reset($related_tickets);
1075
+				if ($main_default_ticket instanceof EE_Ticket) {
1076
+					foreach ($default_prices as $default_price) {
1077
+						if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1078
+							continue;
1079
+						}
1080
+						$main_default_ticket->cache('Price', $default_price);
1081
+					}
1082
+				}
1083
+			}
1084
+			// we can't actually setup rows in this loop yet cause we don't know all
1085
+			// the unique tickets for this event yet (tickets are linked through all datetimes).
1086
+			// So we're going to temporarily cache some of that information.
1087
+			// loop through and setup the ticket rows and make sure the order is set.
1088
+			foreach ($related_tickets as $ticket) {
1089
+				$TKT_ID = $ticket->get('TKT_ID');
1090
+				$ticket_row = $ticket->get('TKT_row');
1091
+				// we only want unique tickets in our final display!!
1092
+				if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1093
+					$existing_ticket_ids[] = $TKT_ID;
1094
+					$all_tickets[] = $ticket;
1095
+				}
1096
+				// temporary cache of this ticket info for this datetime for later processing of datetime rows.
1097
+				$datetime_tickets[ $DTT_ID ][] = $ticket_row;
1098
+				// temporary cache of this datetime info for this ticket for later processing of ticket rows.
1099
+				if (
1100
+					! isset($ticket_datetimes[ $TKT_ID ])
1101
+					|| ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1102
+				) {
1103
+					$ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1104
+				}
1105
+			}
1106
+			$datetime_row++;
1107
+		}
1108
+		$main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1109
+		$main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1110
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1111
+		// sort $all_tickets by order
1112
+		usort(
1113
+			$all_tickets,
1114
+			function (EE_Ticket $a, EE_Ticket $b) {
1115
+				$a_order = (int) $a->get('TKT_order');
1116
+				$b_order = (int) $b->get('TKT_order');
1117
+				if ($a_order === $b_order) {
1118
+					return 0;
1119
+				}
1120
+				return ($a_order < $b_order) ? -1 : 1;
1121
+			}
1122
+		);
1123
+		// k NOW we have all the data we need for setting up the dtt rows
1124
+		// and ticket rows so we start our dtt loop again.
1125
+		$datetime_row = 1;
1126
+		foreach ($datetimes as $datetime) {
1127
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1128
+				$datetime_row,
1129
+				$datetime,
1130
+				$datetime_tickets,
1131
+				$all_tickets,
1132
+				false,
1133
+				$datetimes
1134
+			);
1135
+			$datetime_row++;
1136
+		}
1137
+		// then loop through all tickets for the ticket rows.
1138
+		$ticket_row = 1;
1139
+		foreach ($all_tickets as $ticket) {
1140
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1141
+				$ticket_row,
1142
+				$ticket,
1143
+				$ticket_datetimes,
1144
+				$datetimes,
1145
+				false,
1146
+				$all_tickets
1147
+			);
1148
+			$ticket_row++;
1149
+		}
1150
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1151
+		EEH_Template::display_template(
1152
+			PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1153
+			$main_template_args
1154
+		);
1155
+	}
1156 1156
 
1157 1157
 
1158
-    /**
1159
-     * @param int         $datetime_row
1160
-     * @param EE_Datetime $datetime
1161
-     * @param array       $datetime_tickets
1162
-     * @param array       $all_tickets
1163
-     * @param bool        $default
1164
-     * @param array       $all_datetimes
1165
-     * @return mixed
1166
-     * @throws DomainException
1167
-     * @throws EE_Error
1168
-     */
1169
-    protected function _get_datetime_row(
1170
-        $datetime_row,
1171
-        EE_Datetime $datetime,
1172
-        $datetime_tickets = array(),
1173
-        $all_tickets = array(),
1174
-        $default = false,
1175
-        $all_datetimes = array()
1176
-    ) {
1177
-        $dtt_display_template_args = array(
1178
-            'dtt_edit_row'             => $this->_get_dtt_edit_row(
1179
-                $datetime_row,
1180
-                $datetime,
1181
-                $default,
1182
-                $all_datetimes
1183
-            ),
1184
-            'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1185
-                $datetime_row,
1186
-                $datetime,
1187
-                $datetime_tickets,
1188
-                $all_tickets,
1189
-                $default
1190
-            ),
1191
-            'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1192
-        );
1193
-        return EEH_Template::display_template(
1194
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1195
-            $dtt_display_template_args,
1196
-            true
1197
-        );
1198
-    }
1158
+	/**
1159
+	 * @param int         $datetime_row
1160
+	 * @param EE_Datetime $datetime
1161
+	 * @param array       $datetime_tickets
1162
+	 * @param array       $all_tickets
1163
+	 * @param bool        $default
1164
+	 * @param array       $all_datetimes
1165
+	 * @return mixed
1166
+	 * @throws DomainException
1167
+	 * @throws EE_Error
1168
+	 */
1169
+	protected function _get_datetime_row(
1170
+		$datetime_row,
1171
+		EE_Datetime $datetime,
1172
+		$datetime_tickets = array(),
1173
+		$all_tickets = array(),
1174
+		$default = false,
1175
+		$all_datetimes = array()
1176
+	) {
1177
+		$dtt_display_template_args = array(
1178
+			'dtt_edit_row'             => $this->_get_dtt_edit_row(
1179
+				$datetime_row,
1180
+				$datetime,
1181
+				$default,
1182
+				$all_datetimes
1183
+			),
1184
+			'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1185
+				$datetime_row,
1186
+				$datetime,
1187
+				$datetime_tickets,
1188
+				$all_tickets,
1189
+				$default
1190
+			),
1191
+			'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1192
+		);
1193
+		return EEH_Template::display_template(
1194
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1195
+			$dtt_display_template_args,
1196
+			true
1197
+		);
1198
+	}
1199 1199
 
1200 1200
 
1201
-    /**
1202
-     * This method is used to generate a dtt fields  edit row.
1203
-     * The same row is used to generate a row with valid DTT objects
1204
-     * and the default row that is used as the skeleton by the js.
1205
-     *
1206
-     * @param int           $datetime_row  The row number for the row being generated.
1207
-     * @param EE_Datetime   $datetime
1208
-     * @param bool          $default       Whether a default row is being generated or not.
1209
-     * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1210
-     * @return string
1211
-     * @throws DomainException
1212
-     * @throws EE_Error
1213
-     */
1214
-    protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1215
-    {
1216
-        // if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1217
-        $default = ! $datetime instanceof EE_Datetime ? true : $default;
1218
-        $template_args = array(
1219
-            'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1220
-            'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1221
-            'edit_dtt_expanded'    => '',
1222
-            'DTT_ID'               => $default ? '' : $datetime->ID(),
1223
-            'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1224
-            'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1225
-            'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1226
-            'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1227
-            'DTT_reg_limit'        => $default
1228
-                ? ''
1229
-                : $datetime->get_pretty(
1230
-                    'DTT_reg_limit',
1231
-                    'input'
1232
-                ),
1233
-            'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1234
-            'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1235
-            'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1236
-            'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1237
-                ? ''
1238
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1239
-            'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1240
-                ? 'ee-lock-icon'
1241
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1242
-            'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1243
-                ? ''
1244
-                : EE_Admin_Page::add_query_args_and_nonce(
1245
-                    array(
1246
-                        'event_id' => $datetime->event()->ID(),
1247
-                        'datetime_id' => $datetime->ID(),
1248
-                        'use_filters' => true
1249
-                    ),
1250
-                    REG_ADMIN_URL
1251
-                ),
1252
-        );
1253
-        $template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1254
-            ? 'display:none'
1255
-            : '';
1256
-        // allow filtering of template args at this point.
1257
-        $template_args = apply_filters(
1258
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1259
-            $template_args,
1260
-            $datetime_row,
1261
-            $datetime,
1262
-            $default,
1263
-            $all_datetimes,
1264
-            $this->_is_creating_event
1265
-        );
1266
-        return EEH_Template::display_template(
1267
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1268
-            $template_args,
1269
-            true
1270
-        );
1271
-    }
1201
+	/**
1202
+	 * This method is used to generate a dtt fields  edit row.
1203
+	 * The same row is used to generate a row with valid DTT objects
1204
+	 * and the default row that is used as the skeleton by the js.
1205
+	 *
1206
+	 * @param int           $datetime_row  The row number for the row being generated.
1207
+	 * @param EE_Datetime   $datetime
1208
+	 * @param bool          $default       Whether a default row is being generated or not.
1209
+	 * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1210
+	 * @return string
1211
+	 * @throws DomainException
1212
+	 * @throws EE_Error
1213
+	 */
1214
+	protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1215
+	{
1216
+		// if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1217
+		$default = ! $datetime instanceof EE_Datetime ? true : $default;
1218
+		$template_args = array(
1219
+			'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1220
+			'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1221
+			'edit_dtt_expanded'    => '',
1222
+			'DTT_ID'               => $default ? '' : $datetime->ID(),
1223
+			'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1224
+			'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1225
+			'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1226
+			'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1227
+			'DTT_reg_limit'        => $default
1228
+				? ''
1229
+				: $datetime->get_pretty(
1230
+					'DTT_reg_limit',
1231
+					'input'
1232
+				),
1233
+			'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1234
+			'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1235
+			'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1236
+			'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1237
+				? ''
1238
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1239
+			'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1240
+				? 'ee-lock-icon'
1241
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1242
+			'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1243
+				? ''
1244
+				: EE_Admin_Page::add_query_args_and_nonce(
1245
+					array(
1246
+						'event_id' => $datetime->event()->ID(),
1247
+						'datetime_id' => $datetime->ID(),
1248
+						'use_filters' => true
1249
+					),
1250
+					REG_ADMIN_URL
1251
+				),
1252
+		);
1253
+		$template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1254
+			? 'display:none'
1255
+			: '';
1256
+		// allow filtering of template args at this point.
1257
+		$template_args = apply_filters(
1258
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1259
+			$template_args,
1260
+			$datetime_row,
1261
+			$datetime,
1262
+			$default,
1263
+			$all_datetimes,
1264
+			$this->_is_creating_event
1265
+		);
1266
+		return EEH_Template::display_template(
1267
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1268
+			$template_args,
1269
+			true
1270
+		);
1271
+	}
1272 1272
 
1273 1273
 
1274
-    /**
1275
-     * @param int         $datetime_row
1276
-     * @param EE_Datetime $datetime
1277
-     * @param array       $datetime_tickets
1278
-     * @param array       $all_tickets
1279
-     * @param bool       $default
1280
-     * @return mixed
1281
-     * @throws DomainException
1282
-     * @throws EE_Error
1283
-     */
1284
-    protected function _get_dtt_attached_tickets_row(
1285
-        $datetime_row,
1286
-        $datetime,
1287
-        $datetime_tickets = array(),
1288
-        $all_tickets = array(),
1289
-        $default = false
1290
-    ) {
1291
-        $template_args = array(
1292
-            'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1293
-            'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1294
-            'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1295
-            'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1296
-            'show_tickets_row'                  => 'display:none;',
1297
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1298
-                'add_new_ticket_via_datetime',
1299
-                $this->_adminpage_obj->page_slug,
1300
-                $this->_adminpage_obj->get_req_action(),
1301
-                false,
1302
-                false
1303
-            ),
1304
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1305
-            'DTT_ID'                            => $default ? '' : $datetime->ID(),
1306
-        );
1307
-        // need to setup the list items (but only if this isn't a default skeleton setup)
1308
-        if (! $default) {
1309
-            $ticket_row = 1;
1310
-            foreach ($all_tickets as $ticket) {
1311
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1312
-                    $datetime_row,
1313
-                    $ticket_row,
1314
-                    $datetime,
1315
-                    $ticket,
1316
-                    $datetime_tickets,
1317
-                    $default
1318
-                );
1319
-                $ticket_row++;
1320
-            }
1321
-        }
1322
-        // filter template args at this point
1323
-        $template_args = apply_filters(
1324
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1325
-            $template_args,
1326
-            $datetime_row,
1327
-            $datetime,
1328
-            $datetime_tickets,
1329
-            $all_tickets,
1330
-            $default,
1331
-            $this->_is_creating_event
1332
-        );
1333
-        return EEH_Template::display_template(
1334
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1335
-            $template_args,
1336
-            true
1337
-        );
1338
-    }
1274
+	/**
1275
+	 * @param int         $datetime_row
1276
+	 * @param EE_Datetime $datetime
1277
+	 * @param array       $datetime_tickets
1278
+	 * @param array       $all_tickets
1279
+	 * @param bool       $default
1280
+	 * @return mixed
1281
+	 * @throws DomainException
1282
+	 * @throws EE_Error
1283
+	 */
1284
+	protected function _get_dtt_attached_tickets_row(
1285
+		$datetime_row,
1286
+		$datetime,
1287
+		$datetime_tickets = array(),
1288
+		$all_tickets = array(),
1289
+		$default = false
1290
+	) {
1291
+		$template_args = array(
1292
+			'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1293
+			'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1294
+			'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1295
+			'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1296
+			'show_tickets_row'                  => 'display:none;',
1297
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1298
+				'add_new_ticket_via_datetime',
1299
+				$this->_adminpage_obj->page_slug,
1300
+				$this->_adminpage_obj->get_req_action(),
1301
+				false,
1302
+				false
1303
+			),
1304
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1305
+			'DTT_ID'                            => $default ? '' : $datetime->ID(),
1306
+		);
1307
+		// need to setup the list items (but only if this isn't a default skeleton setup)
1308
+		if (! $default) {
1309
+			$ticket_row = 1;
1310
+			foreach ($all_tickets as $ticket) {
1311
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1312
+					$datetime_row,
1313
+					$ticket_row,
1314
+					$datetime,
1315
+					$ticket,
1316
+					$datetime_tickets,
1317
+					$default
1318
+				);
1319
+				$ticket_row++;
1320
+			}
1321
+		}
1322
+		// filter template args at this point
1323
+		$template_args = apply_filters(
1324
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1325
+			$template_args,
1326
+			$datetime_row,
1327
+			$datetime,
1328
+			$datetime_tickets,
1329
+			$all_tickets,
1330
+			$default,
1331
+			$this->_is_creating_event
1332
+		);
1333
+		return EEH_Template::display_template(
1334
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1335
+			$template_args,
1336
+			true
1337
+		);
1338
+	}
1339 1339
 
1340 1340
 
1341
-    /**
1342
-     * @param int         $datetime_row
1343
-     * @param int         $ticket_row
1344
-     * @param EE_Datetime $datetime
1345
-     * @param EE_Ticket   $ticket
1346
-     * @param array       $datetime_tickets
1347
-     * @param bool        $default
1348
-     * @return mixed
1349
-     * @throws DomainException
1350
-     * @throws EE_Error
1351
-     */
1352
-    protected function _get_datetime_tickets_list_item(
1353
-        $datetime_row,
1354
-        $ticket_row,
1355
-        $datetime,
1356
-        $ticket,
1357
-        $datetime_tickets = array(),
1358
-        $default = false
1359
-    ) {
1360
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1361
-            ? $datetime_tickets[ $datetime->ID() ]
1362
-            : array();
1363
-        $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1364
-        $no_ticket = $default && empty($ticket);
1365
-        $template_args = array(
1366
-            'dtt_row'                 => $default
1367
-                ? 'DTTNUM'
1368
-                : $datetime_row,
1369
-            'tkt_row'                 => $no_ticket
1370
-                ? 'TICKETNUM'
1371
-                : $ticket_row,
1372
-            'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1373
-                ? ' checked'
1374
-                : '',
1375
-            'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1376
-                ? ' ticket-selected'
1377
-                : '',
1378
-            'TKT_name'                => $no_ticket
1379
-                ? 'TKTNAME'
1380
-                : $ticket->get('TKT_name'),
1381
-            'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1382
-                ? ' tkt-status-' . EE_Ticket::onsale
1383
-                : ' tkt-status-' . $ticket->ticket_status(),
1384
-        );
1385
-        // filter template args
1386
-        $template_args = apply_filters(
1387
-            'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1388
-            $template_args,
1389
-            $datetime_row,
1390
-            $ticket_row,
1391
-            $datetime,
1392
-            $ticket,
1393
-            $datetime_tickets,
1394
-            $default,
1395
-            $this->_is_creating_event
1396
-        );
1397
-        return EEH_Template::display_template(
1398
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1399
-            $template_args,
1400
-            true
1401
-        );
1402
-    }
1341
+	/**
1342
+	 * @param int         $datetime_row
1343
+	 * @param int         $ticket_row
1344
+	 * @param EE_Datetime $datetime
1345
+	 * @param EE_Ticket   $ticket
1346
+	 * @param array       $datetime_tickets
1347
+	 * @param bool        $default
1348
+	 * @return mixed
1349
+	 * @throws DomainException
1350
+	 * @throws EE_Error
1351
+	 */
1352
+	protected function _get_datetime_tickets_list_item(
1353
+		$datetime_row,
1354
+		$ticket_row,
1355
+		$datetime,
1356
+		$ticket,
1357
+		$datetime_tickets = array(),
1358
+		$default = false
1359
+	) {
1360
+		$dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1361
+			? $datetime_tickets[ $datetime->ID() ]
1362
+			: array();
1363
+		$display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1364
+		$no_ticket = $default && empty($ticket);
1365
+		$template_args = array(
1366
+			'dtt_row'                 => $default
1367
+				? 'DTTNUM'
1368
+				: $datetime_row,
1369
+			'tkt_row'                 => $no_ticket
1370
+				? 'TICKETNUM'
1371
+				: $ticket_row,
1372
+			'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1373
+				? ' checked'
1374
+				: '',
1375
+			'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1376
+				? ' ticket-selected'
1377
+				: '',
1378
+			'TKT_name'                => $no_ticket
1379
+				? 'TKTNAME'
1380
+				: $ticket->get('TKT_name'),
1381
+			'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1382
+				? ' tkt-status-' . EE_Ticket::onsale
1383
+				: ' tkt-status-' . $ticket->ticket_status(),
1384
+		);
1385
+		// filter template args
1386
+		$template_args = apply_filters(
1387
+			'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1388
+			$template_args,
1389
+			$datetime_row,
1390
+			$ticket_row,
1391
+			$datetime,
1392
+			$ticket,
1393
+			$datetime_tickets,
1394
+			$default,
1395
+			$this->_is_creating_event
1396
+		);
1397
+		return EEH_Template::display_template(
1398
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1399
+			$template_args,
1400
+			true
1401
+		);
1402
+	}
1403 1403
 
1404 1404
 
1405
-    /**
1406
-     * This generates the ticket row for tickets.
1407
-     * This same method is used to generate both the actual rows and the js skeleton row
1408
-     * (when default === true)
1409
-     *
1410
-     * @param int           $ticket_row       Represents the row number being generated.
1411
-     * @param               $ticket
1412
-     * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1413
-     *                                        or empty for default
1414
-     * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1415
-     * @param bool          $default          Whether default row being generated or not.
1416
-     * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1417
-     *                                        (or empty in the case of defaults)
1418
-     * @return mixed
1419
-     * @throws InvalidArgumentException
1420
-     * @throws InvalidInterfaceException
1421
-     * @throws InvalidDataTypeException
1422
-     * @throws DomainException
1423
-     * @throws EE_Error
1424
-     * @throws ReflectionException
1425
-     */
1426
-    protected function _get_ticket_row(
1427
-        $ticket_row,
1428
-        $ticket,
1429
-        $ticket_datetimes,
1430
-        $all_datetimes,
1431
-        $default = false,
1432
-        $all_tickets = array()
1433
-    ) {
1434
-        // if $ticket is not an instance of EE_Ticket then force default to true.
1435
-        $default = ! $ticket instanceof EE_Ticket ? true : $default;
1436
-        $prices = ! empty($ticket) && ! $default
1437
-            ? $ticket->get_many_related(
1438
-                'Price',
1439
-                array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1440
-            )
1441
-            : array();
1442
-        // if there is only one price (which would be the base price)
1443
-        // or NO prices and this ticket is a default ticket,
1444
-        // let's just make sure there are no cached default prices on the object.
1445
-        // This is done by not including any query_params.
1446
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1447
-            $prices = $ticket->prices();
1448
-        }
1449
-        // check if we're dealing with a default ticket in which case
1450
-        // we don't want any starting_ticket_datetime_row values set
1451
-        // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1452
-        // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1453
-        $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1454
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1455
-            ? $ticket_datetimes[ $ticket->ID() ]
1456
-            : array();
1457
-        $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1458
-        $base_price = $default ? null : $ticket->base_price();
1459
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1460
-        // breaking out complicated condition for ticket_status
1461
-        if ($default) {
1462
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1463
-        } else {
1464
-            $ticket_status_class = $ticket->is_default()
1465
-                ? ' tkt-status-' . EE_Ticket::onsale
1466
-                : ' tkt-status-' . $ticket->ticket_status();
1467
-        }
1468
-        // breaking out complicated condition for TKT_taxable
1469
-        if ($default) {
1470
-            $TKT_taxable = '';
1471
-        } else {
1472
-            $TKT_taxable = $ticket->taxable()
1473
-                ? 'checked'
1474
-                : '';
1475
-        }
1476
-        if ($default) {
1477
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1478
-        } elseif ($ticket->is_default()) {
1479
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1480
-        } else {
1481
-            $TKT_status = $ticket->ticket_status(true);
1482
-        }
1483
-        if ($default) {
1484
-            $TKT_min = '';
1485
-        } else {
1486
-            $TKT_min = $ticket->min();
1487
-            if ($TKT_min === -1 || $TKT_min === 0) {
1488
-                $TKT_min = '';
1489
-            }
1490
-        }
1491
-        $template_args = array(
1492
-            'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1493
-            'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1494
-            // on initial page load this will always be the correct order.
1495
-            'tkt_status_class'              => $ticket_status_class,
1496
-            'display_edit_tkt_row'          => 'display:none;',
1497
-            'edit_tkt_expanded'             => '',
1498
-            'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1499
-            'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1500
-            'TKT_start_date'                => $default
1501
-                ? ''
1502
-                : $ticket->get_date('TKT_start_date', $this->_date_time_format),
1503
-            'TKT_end_date'                  => $default
1504
-                ? ''
1505
-                : $ticket->get_date('TKT_end_date', $this->_date_time_format),
1506
-            'TKT_status'                    => $TKT_status,
1507
-            'TKT_price'                     => $default
1508
-                ? ''
1509
-                : EEH_Template::format_currency(
1510
-                    $ticket->get_ticket_total_with_taxes(),
1511
-                    false,
1512
-                    false
1513
-                ),
1514
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1515
-            'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1516
-            'TKT_qty'                       => $default
1517
-                ? ''
1518
-                : $ticket->get_pretty('TKT_qty', 'symbol'),
1519
-            'TKT_qty_for_input'             => $default
1520
-                ? ''
1521
-                : $ticket->get_pretty('TKT_qty', 'input'),
1522
-            'TKT_uses'                      => $default
1523
-                ? ''
1524
-                : $ticket->get_pretty('TKT_uses', 'input'),
1525
-            'TKT_min'                       => $TKT_min,
1526
-            'TKT_max'                       => $default
1527
-                ? ''
1528
-                : $ticket->get_pretty('TKT_max', 'input'),
1529
-            'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1530
-            'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1531
-            'TKT_registrations'             => $default
1532
-                ? 0
1533
-                : $ticket->count_registrations(
1534
-                    array(
1535
-                        array(
1536
-                            'STS_ID' => array(
1537
-                                '!=',
1538
-                                EEM_Registration::status_id_incomplete,
1539
-                            ),
1540
-                        ),
1541
-                    )
1542
-                ),
1543
-            'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1544
-            'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1545
-            'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1546
-            'TKT_required'                  => $default ? 0 : $ticket->required(),
1547
-            'TKT_is_default_selector'       => '',
1548
-            'ticket_price_rows'             => '',
1549
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1550
-                ? ''
1551
-                : $base_price->get_pretty('PRC_amount', 'localized_float'),
1552
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1553
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1554
-                ? ''
1555
-                : 'display:none;',
1556
-            'show_price_mod_button'         => count($prices) > 1
1557
-                                               || ($default && $count_price_mods > 0)
1558
-                                               || (! $default && $ticket->deleted())
1559
-                ? 'display:none;'
1560
-                : '',
1561
-            'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1562
-            'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1563
-            'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1564
-            'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1565
-            'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1566
-            'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1567
-            'TKT_taxable'                   => $TKT_taxable,
1568
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1569
-                ? ''
1570
-                : 'display:none;',
1571
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1572
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1573
-                $ticket_subtotal,
1574
-                false,
1575
-                false
1576
-            ),
1577
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1578
-            'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1579
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1580
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1581
-                ? ' ticket-archived'
1582
-                : '',
1583
-            'trash_icon'                    => $ticket instanceof EE_Ticket
1584
-                                               && $ticket->deleted()
1585
-                                               && ! $ticket->is_permanently_deleteable()
1586
-                ? 'ee-lock-icon '
1587
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1588
-            'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1589
-                ? ''
1590
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1591
-        );
1592
-        $template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1593
-            ? 'display:none'
1594
-            : '';
1595
-        // handle rows that should NOT be empty
1596
-        if (empty($template_args['TKT_start_date'])) {
1597
-            // if empty then the start date will be now.
1598
-            $template_args['TKT_start_date'] = date(
1599
-                $this->_date_time_format,
1600
-                current_time('timestamp')
1601
-            );
1602
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1603
-        }
1604
-        if (empty($template_args['TKT_end_date'])) {
1605
-            // get the earliest datetime (if present);
1606
-            $earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1607
-                ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1608
-                    'Datetime',
1609
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1610
-                )
1611
-                : null;
1612
-            if (! empty($earliest_dtt)) {
1613
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1614
-                    'DTT_EVT_start',
1615
-                    $this->_date_time_format
1616
-                );
1617
-            } else {
1618
-                // default so let's just use what's been set for the default date-time which is 30 days from now.
1619
-                $template_args['TKT_end_date'] = date(
1620
-                    $this->_date_time_format,
1621
-                    mktime(
1622
-                        24,
1623
-                        0,
1624
-                        0,
1625
-                        date('m'),
1626
-                        date('d') + 29,
1627
-                        date('Y')
1628
-                    )
1629
-                );
1630
-            }
1631
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1632
-        }
1633
-        // generate ticket_datetime items
1634
-        if (! $default) {
1635
-            $datetime_row = 1;
1636
-            foreach ($all_datetimes as $datetime) {
1637
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1638
-                    $datetime_row,
1639
-                    $ticket_row,
1640
-                    $datetime,
1641
-                    $ticket,
1642
-                    $ticket_datetimes,
1643
-                    $default
1644
-                );
1645
-                $datetime_row++;
1646
-            }
1647
-        }
1648
-        $price_row = 1;
1649
-        foreach ($prices as $price) {
1650
-            if (! $price instanceof EE_Price) {
1651
-                continue;
1652
-            }
1653
-            if ($price->is_base_price()) {
1654
-                $price_row++;
1655
-                continue;
1656
-            }
1657
-            $show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1658
-            $show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1659
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1660
-                $ticket_row,
1661
-                $price_row,
1662
-                $price,
1663
-                $default,
1664
-                $ticket,
1665
-                $show_trash,
1666
-                $show_create
1667
-            );
1668
-            $price_row++;
1669
-        }
1670
-        // filter $template_args
1671
-        $template_args = apply_filters(
1672
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1673
-            $template_args,
1674
-            $ticket_row,
1675
-            $ticket,
1676
-            $ticket_datetimes,
1677
-            $all_datetimes,
1678
-            $default,
1679
-            $all_tickets,
1680
-            $this->_is_creating_event
1681
-        );
1682
-        return EEH_Template::display_template(
1683
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1684
-            $template_args,
1685
-            true
1686
-        );
1687
-    }
1405
+	/**
1406
+	 * This generates the ticket row for tickets.
1407
+	 * This same method is used to generate both the actual rows and the js skeleton row
1408
+	 * (when default === true)
1409
+	 *
1410
+	 * @param int           $ticket_row       Represents the row number being generated.
1411
+	 * @param               $ticket
1412
+	 * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1413
+	 *                                        or empty for default
1414
+	 * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1415
+	 * @param bool          $default          Whether default row being generated or not.
1416
+	 * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1417
+	 *                                        (or empty in the case of defaults)
1418
+	 * @return mixed
1419
+	 * @throws InvalidArgumentException
1420
+	 * @throws InvalidInterfaceException
1421
+	 * @throws InvalidDataTypeException
1422
+	 * @throws DomainException
1423
+	 * @throws EE_Error
1424
+	 * @throws ReflectionException
1425
+	 */
1426
+	protected function _get_ticket_row(
1427
+		$ticket_row,
1428
+		$ticket,
1429
+		$ticket_datetimes,
1430
+		$all_datetimes,
1431
+		$default = false,
1432
+		$all_tickets = array()
1433
+	) {
1434
+		// if $ticket is not an instance of EE_Ticket then force default to true.
1435
+		$default = ! $ticket instanceof EE_Ticket ? true : $default;
1436
+		$prices = ! empty($ticket) && ! $default
1437
+			? $ticket->get_many_related(
1438
+				'Price',
1439
+				array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1440
+			)
1441
+			: array();
1442
+		// if there is only one price (which would be the base price)
1443
+		// or NO prices and this ticket is a default ticket,
1444
+		// let's just make sure there are no cached default prices on the object.
1445
+		// This is done by not including any query_params.
1446
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1447
+			$prices = $ticket->prices();
1448
+		}
1449
+		// check if we're dealing with a default ticket in which case
1450
+		// we don't want any starting_ticket_datetime_row values set
1451
+		// (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1452
+		// This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1453
+		$default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1454
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1455
+			? $ticket_datetimes[ $ticket->ID() ]
1456
+			: array();
1457
+		$ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1458
+		$base_price = $default ? null : $ticket->base_price();
1459
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1460
+		// breaking out complicated condition for ticket_status
1461
+		if ($default) {
1462
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1463
+		} else {
1464
+			$ticket_status_class = $ticket->is_default()
1465
+				? ' tkt-status-' . EE_Ticket::onsale
1466
+				: ' tkt-status-' . $ticket->ticket_status();
1467
+		}
1468
+		// breaking out complicated condition for TKT_taxable
1469
+		if ($default) {
1470
+			$TKT_taxable = '';
1471
+		} else {
1472
+			$TKT_taxable = $ticket->taxable()
1473
+				? 'checked'
1474
+				: '';
1475
+		}
1476
+		if ($default) {
1477
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1478
+		} elseif ($ticket->is_default()) {
1479
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1480
+		} else {
1481
+			$TKT_status = $ticket->ticket_status(true);
1482
+		}
1483
+		if ($default) {
1484
+			$TKT_min = '';
1485
+		} else {
1486
+			$TKT_min = $ticket->min();
1487
+			if ($TKT_min === -1 || $TKT_min === 0) {
1488
+				$TKT_min = '';
1489
+			}
1490
+		}
1491
+		$template_args = array(
1492
+			'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1493
+			'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1494
+			// on initial page load this will always be the correct order.
1495
+			'tkt_status_class'              => $ticket_status_class,
1496
+			'display_edit_tkt_row'          => 'display:none;',
1497
+			'edit_tkt_expanded'             => '',
1498
+			'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1499
+			'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1500
+			'TKT_start_date'                => $default
1501
+				? ''
1502
+				: $ticket->get_date('TKT_start_date', $this->_date_time_format),
1503
+			'TKT_end_date'                  => $default
1504
+				? ''
1505
+				: $ticket->get_date('TKT_end_date', $this->_date_time_format),
1506
+			'TKT_status'                    => $TKT_status,
1507
+			'TKT_price'                     => $default
1508
+				? ''
1509
+				: EEH_Template::format_currency(
1510
+					$ticket->get_ticket_total_with_taxes(),
1511
+					false,
1512
+					false
1513
+				),
1514
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1515
+			'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1516
+			'TKT_qty'                       => $default
1517
+				? ''
1518
+				: $ticket->get_pretty('TKT_qty', 'symbol'),
1519
+			'TKT_qty_for_input'             => $default
1520
+				? ''
1521
+				: $ticket->get_pretty('TKT_qty', 'input'),
1522
+			'TKT_uses'                      => $default
1523
+				? ''
1524
+				: $ticket->get_pretty('TKT_uses', 'input'),
1525
+			'TKT_min'                       => $TKT_min,
1526
+			'TKT_max'                       => $default
1527
+				? ''
1528
+				: $ticket->get_pretty('TKT_max', 'input'),
1529
+			'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1530
+			'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1531
+			'TKT_registrations'             => $default
1532
+				? 0
1533
+				: $ticket->count_registrations(
1534
+					array(
1535
+						array(
1536
+							'STS_ID' => array(
1537
+								'!=',
1538
+								EEM_Registration::status_id_incomplete,
1539
+							),
1540
+						),
1541
+					)
1542
+				),
1543
+			'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1544
+			'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1545
+			'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1546
+			'TKT_required'                  => $default ? 0 : $ticket->required(),
1547
+			'TKT_is_default_selector'       => '',
1548
+			'ticket_price_rows'             => '',
1549
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1550
+				? ''
1551
+				: $base_price->get_pretty('PRC_amount', 'localized_float'),
1552
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1553
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1554
+				? ''
1555
+				: 'display:none;',
1556
+			'show_price_mod_button'         => count($prices) > 1
1557
+											   || ($default && $count_price_mods > 0)
1558
+											   || (! $default && $ticket->deleted())
1559
+				? 'display:none;'
1560
+				: '',
1561
+			'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1562
+			'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1563
+			'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1564
+			'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1565
+			'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1566
+			'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1567
+			'TKT_taxable'                   => $TKT_taxable,
1568
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1569
+				? ''
1570
+				: 'display:none;',
1571
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1572
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1573
+				$ticket_subtotal,
1574
+				false,
1575
+				false
1576
+			),
1577
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1578
+			'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1579
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1580
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1581
+				? ' ticket-archived'
1582
+				: '',
1583
+			'trash_icon'                    => $ticket instanceof EE_Ticket
1584
+											   && $ticket->deleted()
1585
+											   && ! $ticket->is_permanently_deleteable()
1586
+				? 'ee-lock-icon '
1587
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1588
+			'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1589
+				? ''
1590
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1591
+		);
1592
+		$template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1593
+			? 'display:none'
1594
+			: '';
1595
+		// handle rows that should NOT be empty
1596
+		if (empty($template_args['TKT_start_date'])) {
1597
+			// if empty then the start date will be now.
1598
+			$template_args['TKT_start_date'] = date(
1599
+				$this->_date_time_format,
1600
+				current_time('timestamp')
1601
+			);
1602
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1603
+		}
1604
+		if (empty($template_args['TKT_end_date'])) {
1605
+			// get the earliest datetime (if present);
1606
+			$earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1607
+				? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1608
+					'Datetime',
1609
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1610
+				)
1611
+				: null;
1612
+			if (! empty($earliest_dtt)) {
1613
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1614
+					'DTT_EVT_start',
1615
+					$this->_date_time_format
1616
+				);
1617
+			} else {
1618
+				// default so let's just use what's been set for the default date-time which is 30 days from now.
1619
+				$template_args['TKT_end_date'] = date(
1620
+					$this->_date_time_format,
1621
+					mktime(
1622
+						24,
1623
+						0,
1624
+						0,
1625
+						date('m'),
1626
+						date('d') + 29,
1627
+						date('Y')
1628
+					)
1629
+				);
1630
+			}
1631
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1632
+		}
1633
+		// generate ticket_datetime items
1634
+		if (! $default) {
1635
+			$datetime_row = 1;
1636
+			foreach ($all_datetimes as $datetime) {
1637
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1638
+					$datetime_row,
1639
+					$ticket_row,
1640
+					$datetime,
1641
+					$ticket,
1642
+					$ticket_datetimes,
1643
+					$default
1644
+				);
1645
+				$datetime_row++;
1646
+			}
1647
+		}
1648
+		$price_row = 1;
1649
+		foreach ($prices as $price) {
1650
+			if (! $price instanceof EE_Price) {
1651
+				continue;
1652
+			}
1653
+			if ($price->is_base_price()) {
1654
+				$price_row++;
1655
+				continue;
1656
+			}
1657
+			$show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1658
+			$show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1659
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1660
+				$ticket_row,
1661
+				$price_row,
1662
+				$price,
1663
+				$default,
1664
+				$ticket,
1665
+				$show_trash,
1666
+				$show_create
1667
+			);
1668
+			$price_row++;
1669
+		}
1670
+		// filter $template_args
1671
+		$template_args = apply_filters(
1672
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1673
+			$template_args,
1674
+			$ticket_row,
1675
+			$ticket,
1676
+			$ticket_datetimes,
1677
+			$all_datetimes,
1678
+			$default,
1679
+			$all_tickets,
1680
+			$this->_is_creating_event
1681
+		);
1682
+		return EEH_Template::display_template(
1683
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1684
+			$template_args,
1685
+			true
1686
+		);
1687
+	}
1688 1688
 
1689 1689
 
1690
-    /**
1691
-     * @param int            $ticket_row
1692
-     * @param EE_Ticket|null $ticket
1693
-     * @return string
1694
-     * @throws DomainException
1695
-     * @throws EE_Error
1696
-     */
1697
-    protected function _get_tax_rows($ticket_row, $ticket)
1698
-    {
1699
-        $tax_rows = '';
1700
-        /** @var EE_Price[] $taxes */
1701
-        $taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1702
-        foreach ($taxes as $tax) {
1703
-            $tax_added = $this->_get_tax_added($tax, $ticket);
1704
-            $template_args = array(
1705
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1706
-                    ? ''
1707
-                    : 'display:none;',
1708
-                'tax_id'            => $tax->ID(),
1709
-                'tkt_row'           => $ticket_row,
1710
-                'tax_label'         => $tax->get('PRC_name'),
1711
-                'tax_added'         => $tax_added,
1712
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1713
-                'tax_amount'        => $tax->get('PRC_amount'),
1714
-            );
1715
-            $template_args = apply_filters(
1716
-                'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1717
-                $template_args,
1718
-                $ticket_row,
1719
-                $ticket,
1720
-                $this->_is_creating_event
1721
-            );
1722
-            $tax_rows .= EEH_Template::display_template(
1723
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1724
-                $template_args,
1725
-                true
1726
-            );
1727
-        }
1728
-        return $tax_rows;
1729
-    }
1690
+	/**
1691
+	 * @param int            $ticket_row
1692
+	 * @param EE_Ticket|null $ticket
1693
+	 * @return string
1694
+	 * @throws DomainException
1695
+	 * @throws EE_Error
1696
+	 */
1697
+	protected function _get_tax_rows($ticket_row, $ticket)
1698
+	{
1699
+		$tax_rows = '';
1700
+		/** @var EE_Price[] $taxes */
1701
+		$taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1702
+		foreach ($taxes as $tax) {
1703
+			$tax_added = $this->_get_tax_added($tax, $ticket);
1704
+			$template_args = array(
1705
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1706
+					? ''
1707
+					: 'display:none;',
1708
+				'tax_id'            => $tax->ID(),
1709
+				'tkt_row'           => $ticket_row,
1710
+				'tax_label'         => $tax->get('PRC_name'),
1711
+				'tax_added'         => $tax_added,
1712
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1713
+				'tax_amount'        => $tax->get('PRC_amount'),
1714
+			);
1715
+			$template_args = apply_filters(
1716
+				'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1717
+				$template_args,
1718
+				$ticket_row,
1719
+				$ticket,
1720
+				$this->_is_creating_event
1721
+			);
1722
+			$tax_rows .= EEH_Template::display_template(
1723
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1724
+				$template_args,
1725
+				true
1726
+			);
1727
+		}
1728
+		return $tax_rows;
1729
+	}
1730 1730
 
1731 1731
 
1732
-    /**
1733
-     * @param EE_Price       $tax
1734
-     * @param EE_Ticket|null $ticket
1735
-     * @return float|int
1736
-     * @throws EE_Error
1737
-     */
1738
-    protected function _get_tax_added(EE_Price $tax, $ticket)
1739
-    {
1740
-        $subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1741
-        return $subtotal * $tax->get('PRC_amount') / 100;
1742
-    }
1732
+	/**
1733
+	 * @param EE_Price       $tax
1734
+	 * @param EE_Ticket|null $ticket
1735
+	 * @return float|int
1736
+	 * @throws EE_Error
1737
+	 */
1738
+	protected function _get_tax_added(EE_Price $tax, $ticket)
1739
+	{
1740
+		$subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1741
+		return $subtotal * $tax->get('PRC_amount') / 100;
1742
+	}
1743 1743
 
1744 1744
 
1745
-    /**
1746
-     * @param int            $ticket_row
1747
-     * @param int            $price_row
1748
-     * @param EE_Price|null  $price
1749
-     * @param bool           $default
1750
-     * @param EE_Ticket|null $ticket
1751
-     * @param bool           $show_trash
1752
-     * @param bool           $show_create
1753
-     * @return mixed
1754
-     * @throws InvalidArgumentException
1755
-     * @throws InvalidInterfaceException
1756
-     * @throws InvalidDataTypeException
1757
-     * @throws DomainException
1758
-     * @throws EE_Error
1759
-     * @throws ReflectionException
1760
-     */
1761
-    protected function _get_ticket_price_row(
1762
-        $ticket_row,
1763
-        $price_row,
1764
-        $price,
1765
-        $default,
1766
-        $ticket,
1767
-        $show_trash = true,
1768
-        $show_create = true
1769
-    ) {
1770
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1771
-        $template_args = array(
1772
-            'tkt_row'               => $default && empty($ticket)
1773
-                ? 'TICKETNUM'
1774
-                : $ticket_row,
1775
-            'PRC_order'             => $default && empty($price)
1776
-                ? 'PRICENUM'
1777
-                : $price_row,
1778
-            'edit_prices_name'      => $default && empty($price)
1779
-                ? 'PRICENAMEATTR'
1780
-                : 'edit_prices',
1781
-            'price_type_selector'   => $default && empty($price)
1782
-                ? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1783
-                : $this->_get_price_type_selector(
1784
-                    $ticket_row,
1785
-                    $price_row,
1786
-                    $price,
1787
-                    $default,
1788
-                    $send_disabled
1789
-                ),
1790
-            'PRC_ID'                => $default && empty($price)
1791
-                ? 0
1792
-                : $price->ID(),
1793
-            'PRC_is_default'        => $default && empty($price)
1794
-                ? 0
1795
-                : $price->get('PRC_is_default'),
1796
-            'PRC_name'              => $default && empty($price)
1797
-                ? ''
1798
-                : $price->get('PRC_name'),
1799
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1800
-            'show_plus_or_minus'    => $default && empty($price)
1801
-                ? ''
1802
-                : 'display:none;',
1803
-            'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1804
-                ? 'display:none;'
1805
-                : '',
1806
-            'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1807
-                ? 'display:none;'
1808
-                : '',
1809
-            'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1810
-                ? 'display:none'
1811
-                : '',
1812
-            'PRC_amount'            => $default && empty($price)
1813
-                ? 0
1814
-                : $price->get_pretty('PRC_amount', 'localized_float'),
1815
-            'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1816
-                ? 'display:none;'
1817
-                : '',
1818
-            'show_trash_icon'       => $show_trash
1819
-                ? ''
1820
-                : ' style="display:none;"',
1821
-            'show_create_button'    => $show_create
1822
-                ? ''
1823
-                : ' style="display:none;"',
1824
-            'PRC_desc'              => $default && empty($price)
1825
-                ? ''
1826
-                : $price->get('PRC_desc'),
1827
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1828
-        );
1829
-        $template_args = apply_filters(
1830
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1831
-            $template_args,
1832
-            $ticket_row,
1833
-            $price_row,
1834
-            $price,
1835
-            $default,
1836
-            $ticket,
1837
-            $show_trash,
1838
-            $show_create,
1839
-            $this->_is_creating_event
1840
-        );
1841
-        return EEH_Template::display_template(
1842
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1843
-            $template_args,
1844
-            true
1845
-        );
1846
-    }
1745
+	/**
1746
+	 * @param int            $ticket_row
1747
+	 * @param int            $price_row
1748
+	 * @param EE_Price|null  $price
1749
+	 * @param bool           $default
1750
+	 * @param EE_Ticket|null $ticket
1751
+	 * @param bool           $show_trash
1752
+	 * @param bool           $show_create
1753
+	 * @return mixed
1754
+	 * @throws InvalidArgumentException
1755
+	 * @throws InvalidInterfaceException
1756
+	 * @throws InvalidDataTypeException
1757
+	 * @throws DomainException
1758
+	 * @throws EE_Error
1759
+	 * @throws ReflectionException
1760
+	 */
1761
+	protected function _get_ticket_price_row(
1762
+		$ticket_row,
1763
+		$price_row,
1764
+		$price,
1765
+		$default,
1766
+		$ticket,
1767
+		$show_trash = true,
1768
+		$show_create = true
1769
+	) {
1770
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1771
+		$template_args = array(
1772
+			'tkt_row'               => $default && empty($ticket)
1773
+				? 'TICKETNUM'
1774
+				: $ticket_row,
1775
+			'PRC_order'             => $default && empty($price)
1776
+				? 'PRICENUM'
1777
+				: $price_row,
1778
+			'edit_prices_name'      => $default && empty($price)
1779
+				? 'PRICENAMEATTR'
1780
+				: 'edit_prices',
1781
+			'price_type_selector'   => $default && empty($price)
1782
+				? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1783
+				: $this->_get_price_type_selector(
1784
+					$ticket_row,
1785
+					$price_row,
1786
+					$price,
1787
+					$default,
1788
+					$send_disabled
1789
+				),
1790
+			'PRC_ID'                => $default && empty($price)
1791
+				? 0
1792
+				: $price->ID(),
1793
+			'PRC_is_default'        => $default && empty($price)
1794
+				? 0
1795
+				: $price->get('PRC_is_default'),
1796
+			'PRC_name'              => $default && empty($price)
1797
+				? ''
1798
+				: $price->get('PRC_name'),
1799
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1800
+			'show_plus_or_minus'    => $default && empty($price)
1801
+				? ''
1802
+				: 'display:none;',
1803
+			'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1804
+				? 'display:none;'
1805
+				: '',
1806
+			'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1807
+				? 'display:none;'
1808
+				: '',
1809
+			'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1810
+				? 'display:none'
1811
+				: '',
1812
+			'PRC_amount'            => $default && empty($price)
1813
+				? 0
1814
+				: $price->get_pretty('PRC_amount', 'localized_float'),
1815
+			'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1816
+				? 'display:none;'
1817
+				: '',
1818
+			'show_trash_icon'       => $show_trash
1819
+				? ''
1820
+				: ' style="display:none;"',
1821
+			'show_create_button'    => $show_create
1822
+				? ''
1823
+				: ' style="display:none;"',
1824
+			'PRC_desc'              => $default && empty($price)
1825
+				? ''
1826
+				: $price->get('PRC_desc'),
1827
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1828
+		);
1829
+		$template_args = apply_filters(
1830
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1831
+			$template_args,
1832
+			$ticket_row,
1833
+			$price_row,
1834
+			$price,
1835
+			$default,
1836
+			$ticket,
1837
+			$show_trash,
1838
+			$show_create,
1839
+			$this->_is_creating_event
1840
+		);
1841
+		return EEH_Template::display_template(
1842
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1843
+			$template_args,
1844
+			true
1845
+		);
1846
+	}
1847 1847
 
1848 1848
 
1849
-    /**
1850
-     * @param int      $ticket_row
1851
-     * @param int      $price_row
1852
-     * @param EE_Price $price
1853
-     * @param bool     $default
1854
-     * @param bool     $disabled
1855
-     * @return mixed
1856
-     * @throws ReflectionException
1857
-     * @throws InvalidArgumentException
1858
-     * @throws InvalidInterfaceException
1859
-     * @throws InvalidDataTypeException
1860
-     * @throws DomainException
1861
-     * @throws EE_Error
1862
-     */
1863
-    protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1864
-    {
1865
-        if ($price->is_base_price()) {
1866
-            return $this->_get_base_price_template(
1867
-                $ticket_row,
1868
-                $price_row,
1869
-                $price,
1870
-                $default
1871
-            );
1872
-        }
1873
-        return $this->_get_price_modifier_template(
1874
-            $ticket_row,
1875
-            $price_row,
1876
-            $price,
1877
-            $default,
1878
-            $disabled
1879
-        );
1880
-    }
1849
+	/**
1850
+	 * @param int      $ticket_row
1851
+	 * @param int      $price_row
1852
+	 * @param EE_Price $price
1853
+	 * @param bool     $default
1854
+	 * @param bool     $disabled
1855
+	 * @return mixed
1856
+	 * @throws ReflectionException
1857
+	 * @throws InvalidArgumentException
1858
+	 * @throws InvalidInterfaceException
1859
+	 * @throws InvalidDataTypeException
1860
+	 * @throws DomainException
1861
+	 * @throws EE_Error
1862
+	 */
1863
+	protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1864
+	{
1865
+		if ($price->is_base_price()) {
1866
+			return $this->_get_base_price_template(
1867
+				$ticket_row,
1868
+				$price_row,
1869
+				$price,
1870
+				$default
1871
+			);
1872
+		}
1873
+		return $this->_get_price_modifier_template(
1874
+			$ticket_row,
1875
+			$price_row,
1876
+			$price,
1877
+			$default,
1878
+			$disabled
1879
+		);
1880
+	}
1881 1881
 
1882 1882
 
1883
-    /**
1884
-     * @param int      $ticket_row
1885
-     * @param int      $price_row
1886
-     * @param EE_Price $price
1887
-     * @param bool     $default
1888
-     * @return mixed
1889
-     * @throws DomainException
1890
-     * @throws EE_Error
1891
-     */
1892
-    protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1893
-    {
1894
-        $template_args = array(
1895
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1896
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1897
-            'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1898
-            'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1899
-            'price_selected_operator'   => '+',
1900
-            'price_selected_is_percent' => 0,
1901
-        );
1902
-        $template_args = apply_filters(
1903
-            'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1904
-            $template_args,
1905
-            $ticket_row,
1906
-            $price_row,
1907
-            $price,
1908
-            $default,
1909
-            $this->_is_creating_event
1910
-        );
1911
-        return EEH_Template::display_template(
1912
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1913
-            $template_args,
1914
-            true
1915
-        );
1916
-    }
1883
+	/**
1884
+	 * @param int      $ticket_row
1885
+	 * @param int      $price_row
1886
+	 * @param EE_Price $price
1887
+	 * @param bool     $default
1888
+	 * @return mixed
1889
+	 * @throws DomainException
1890
+	 * @throws EE_Error
1891
+	 */
1892
+	protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1893
+	{
1894
+		$template_args = array(
1895
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1896
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1897
+			'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1898
+			'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1899
+			'price_selected_operator'   => '+',
1900
+			'price_selected_is_percent' => 0,
1901
+		);
1902
+		$template_args = apply_filters(
1903
+			'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1904
+			$template_args,
1905
+			$ticket_row,
1906
+			$price_row,
1907
+			$price,
1908
+			$default,
1909
+			$this->_is_creating_event
1910
+		);
1911
+		return EEH_Template::display_template(
1912
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1913
+			$template_args,
1914
+			true
1915
+		);
1916
+	}
1917 1917
 
1918 1918
 
1919
-    /**
1920
-     * @param int      $ticket_row
1921
-     * @param int      $price_row
1922
-     * @param EE_Price $price
1923
-     * @param bool     $default
1924
-     * @param bool     $disabled
1925
-     * @return mixed
1926
-     * @throws ReflectionException
1927
-     * @throws InvalidArgumentException
1928
-     * @throws InvalidInterfaceException
1929
-     * @throws InvalidDataTypeException
1930
-     * @throws DomainException
1931
-     * @throws EE_Error
1932
-     */
1933
-    protected function _get_price_modifier_template(
1934
-        $ticket_row,
1935
-        $price_row,
1936
-        $price,
1937
-        $default,
1938
-        $disabled = false
1939
-    ) {
1940
-        $select_name = $default && ! $price instanceof EE_Price
1941
-            ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1942
-            : 'edit_prices[' . esc_attr($ticket_row) . '][' . esc_attr($price_row) . '][PRT_ID]';
1943
-        /** @var EEM_Price_Type $price_type_model */
1944
-        $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1945
-        $price_types = $price_type_model->get_all(array(
1946
-            array(
1947
-                'OR' => array(
1948
-                    'PBT_ID'  => '2',
1949
-                    'PBT_ID*' => '3',
1950
-                ),
1951
-            ),
1952
-        ));
1953
-        $all_price_types = $default && ! $price instanceof EE_Price
1954
-            ? array(esc_html__('Select Modifier', 'event_espresso'))
1955
-            : array();
1956
-        $selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1957
-        $price_option_spans = '';
1958
-        // setup price types for selector
1959
-        foreach ($price_types as $price_type) {
1960
-            if (! $price_type instanceof EE_Price_Type) {
1961
-                continue;
1962
-            }
1963
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1964
-            // while we're in the loop let's setup the option spans used by js
1965
-            $span_args = array(
1966
-                'PRT_ID'         => $price_type->ID(),
1967
-                'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1968
-                'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1969
-            );
1970
-            $price_option_spans .= EEH_Template::display_template(
1971
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1972
-                $span_args,
1973
-                true
1974
-            );
1975
-        }
1976
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1977
-            : $select_name;
1978
-        $select_input = new EE_Select_Input(
1979
-            $all_price_types,
1980
-            array(
1981
-                'default'               => $selected_price_type_id,
1982
-                'html_name'             => $select_name,
1983
-                'html_class'            => 'edit-price-PRT_ID',
1984
-                'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1985
-            )
1986
-        );
1987
-        $price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1988
-        $price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1989
-        $price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1990
-        $price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1991
-        $template_args = array(
1992
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1993
-            'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1994
-            'price_modifier_selector'   => $select_input->get_html_for_input(),
1995
-            'main_name'                 => $select_name,
1996
-            'selected_price_type_id'    => $selected_price_type_id,
1997
-            'price_option_spans'        => $price_option_spans,
1998
-            'price_selected_operator'   => $price_selected_operator,
1999
-            'price_selected_is_percent' => $price_selected_is_percent,
2000
-            'disabled'                  => $disabled,
2001
-        );
2002
-        $template_args = apply_filters(
2003
-            'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2004
-            $template_args,
2005
-            $ticket_row,
2006
-            $price_row,
2007
-            $price,
2008
-            $default,
2009
-            $disabled,
2010
-            $this->_is_creating_event
2011
-        );
2012
-        return EEH_Template::display_template(
2013
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2014
-            $template_args,
2015
-            true
2016
-        );
2017
-    }
1919
+	/**
1920
+	 * @param int      $ticket_row
1921
+	 * @param int      $price_row
1922
+	 * @param EE_Price $price
1923
+	 * @param bool     $default
1924
+	 * @param bool     $disabled
1925
+	 * @return mixed
1926
+	 * @throws ReflectionException
1927
+	 * @throws InvalidArgumentException
1928
+	 * @throws InvalidInterfaceException
1929
+	 * @throws InvalidDataTypeException
1930
+	 * @throws DomainException
1931
+	 * @throws EE_Error
1932
+	 */
1933
+	protected function _get_price_modifier_template(
1934
+		$ticket_row,
1935
+		$price_row,
1936
+		$price,
1937
+		$default,
1938
+		$disabled = false
1939
+	) {
1940
+		$select_name = $default && ! $price instanceof EE_Price
1941
+			? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1942
+			: 'edit_prices[' . esc_attr($ticket_row) . '][' . esc_attr($price_row) . '][PRT_ID]';
1943
+		/** @var EEM_Price_Type $price_type_model */
1944
+		$price_type_model = EE_Registry::instance()->load_model('Price_Type');
1945
+		$price_types = $price_type_model->get_all(array(
1946
+			array(
1947
+				'OR' => array(
1948
+					'PBT_ID'  => '2',
1949
+					'PBT_ID*' => '3',
1950
+				),
1951
+			),
1952
+		));
1953
+		$all_price_types = $default && ! $price instanceof EE_Price
1954
+			? array(esc_html__('Select Modifier', 'event_espresso'))
1955
+			: array();
1956
+		$selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1957
+		$price_option_spans = '';
1958
+		// setup price types for selector
1959
+		foreach ($price_types as $price_type) {
1960
+			if (! $price_type instanceof EE_Price_Type) {
1961
+				continue;
1962
+			}
1963
+			$all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1964
+			// while we're in the loop let's setup the option spans used by js
1965
+			$span_args = array(
1966
+				'PRT_ID'         => $price_type->ID(),
1967
+				'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1968
+				'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1969
+			);
1970
+			$price_option_spans .= EEH_Template::display_template(
1971
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1972
+				$span_args,
1973
+				true
1974
+			);
1975
+		}
1976
+		$select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1977
+			: $select_name;
1978
+		$select_input = new EE_Select_Input(
1979
+			$all_price_types,
1980
+			array(
1981
+				'default'               => $selected_price_type_id,
1982
+				'html_name'             => $select_name,
1983
+				'html_class'            => 'edit-price-PRT_ID',
1984
+				'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1985
+			)
1986
+		);
1987
+		$price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1988
+		$price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1989
+		$price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1990
+		$price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1991
+		$template_args = array(
1992
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1993
+			'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1994
+			'price_modifier_selector'   => $select_input->get_html_for_input(),
1995
+			'main_name'                 => $select_name,
1996
+			'selected_price_type_id'    => $selected_price_type_id,
1997
+			'price_option_spans'        => $price_option_spans,
1998
+			'price_selected_operator'   => $price_selected_operator,
1999
+			'price_selected_is_percent' => $price_selected_is_percent,
2000
+			'disabled'                  => $disabled,
2001
+		);
2002
+		$template_args = apply_filters(
2003
+			'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2004
+			$template_args,
2005
+			$ticket_row,
2006
+			$price_row,
2007
+			$price,
2008
+			$default,
2009
+			$disabled,
2010
+			$this->_is_creating_event
2011
+		);
2012
+		return EEH_Template::display_template(
2013
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2014
+			$template_args,
2015
+			true
2016
+		);
2017
+	}
2018 2018
 
2019 2019
 
2020
-    /**
2021
-     * @param int              $datetime_row
2022
-     * @param int              $ticket_row
2023
-     * @param EE_Datetime|null $datetime
2024
-     * @param EE_Ticket|null   $ticket
2025
-     * @param array            $ticket_datetimes
2026
-     * @param bool             $default
2027
-     * @return mixed
2028
-     * @throws DomainException
2029
-     * @throws EE_Error
2030
-     */
2031
-    protected function _get_ticket_datetime_list_item(
2032
-        $datetime_row,
2033
-        $ticket_row,
2034
-        $datetime,
2035
-        $ticket,
2036
-        $ticket_datetimes = array(),
2037
-        $default = false
2038
-    ) {
2039
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2040
-            ? $ticket_datetimes[ $ticket->ID() ]
2041
-            : array();
2042
-        $template_args = array(
2043
-            'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2044
-                ? 'DTTNUM'
2045
-                : $datetime_row,
2046
-            'tkt_row'                  => $default
2047
-                ? 'TICKETNUM'
2048
-                : $ticket_row,
2049
-            'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2050
-                ? ' ticket-selected'
2051
-                : '',
2052
-            'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2053
-                ? ' checked'
2054
-                : '',
2055
-            'DTT_name'                 => $default && empty($datetime)
2056
-                ? 'DTTNAME'
2057
-                : $datetime->get_dtt_display_name(true),
2058
-            'tkt_status_class'         => '',
2059
-        );
2060
-        $template_args = apply_filters(
2061
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2062
-            $template_args,
2063
-            $datetime_row,
2064
-            $ticket_row,
2065
-            $datetime,
2066
-            $ticket,
2067
-            $ticket_datetimes,
2068
-            $default,
2069
-            $this->_is_creating_event
2070
-        );
2071
-        return EEH_Template::display_template(
2072
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2073
-            $template_args,
2074
-            true
2075
-        );
2076
-    }
2020
+	/**
2021
+	 * @param int              $datetime_row
2022
+	 * @param int              $ticket_row
2023
+	 * @param EE_Datetime|null $datetime
2024
+	 * @param EE_Ticket|null   $ticket
2025
+	 * @param array            $ticket_datetimes
2026
+	 * @param bool             $default
2027
+	 * @return mixed
2028
+	 * @throws DomainException
2029
+	 * @throws EE_Error
2030
+	 */
2031
+	protected function _get_ticket_datetime_list_item(
2032
+		$datetime_row,
2033
+		$ticket_row,
2034
+		$datetime,
2035
+		$ticket,
2036
+		$ticket_datetimes = array(),
2037
+		$default = false
2038
+	) {
2039
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2040
+			? $ticket_datetimes[ $ticket->ID() ]
2041
+			: array();
2042
+		$template_args = array(
2043
+			'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2044
+				? 'DTTNUM'
2045
+				: $datetime_row,
2046
+			'tkt_row'                  => $default
2047
+				? 'TICKETNUM'
2048
+				: $ticket_row,
2049
+			'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2050
+				? ' ticket-selected'
2051
+				: '',
2052
+			'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2053
+				? ' checked'
2054
+				: '',
2055
+			'DTT_name'                 => $default && empty($datetime)
2056
+				? 'DTTNAME'
2057
+				: $datetime->get_dtt_display_name(true),
2058
+			'tkt_status_class'         => '',
2059
+		);
2060
+		$template_args = apply_filters(
2061
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2062
+			$template_args,
2063
+			$datetime_row,
2064
+			$ticket_row,
2065
+			$datetime,
2066
+			$ticket,
2067
+			$ticket_datetimes,
2068
+			$default,
2069
+			$this->_is_creating_event
2070
+		);
2071
+		return EEH_Template::display_template(
2072
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2073
+			$template_args,
2074
+			true
2075
+		);
2076
+	}
2077 2077
 
2078 2078
 
2079
-    /**
2080
-     * @param array $all_datetimes
2081
-     * @param array $all_tickets
2082
-     * @return mixed
2083
-     * @throws ReflectionException
2084
-     * @throws InvalidArgumentException
2085
-     * @throws InvalidInterfaceException
2086
-     * @throws InvalidDataTypeException
2087
-     * @throws DomainException
2088
-     * @throws EE_Error
2089
-     */
2090
-    protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2091
-    {
2092
-        $template_args = array(
2093
-            'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2094
-                'DTTNUM',
2095
-                null,
2096
-                true,
2097
-                $all_datetimes
2098
-            ),
2099
-            'default_ticket_row'                       => $this->_get_ticket_row(
2100
-                'TICKETNUM',
2101
-                null,
2102
-                array(),
2103
-                array(),
2104
-                true
2105
-            ),
2106
-            'default_price_row'                        => $this->_get_ticket_price_row(
2107
-                'TICKETNUM',
2108
-                'PRICENUM',
2109
-                null,
2110
-                true,
2111
-                null
2112
-            ),
2113
-            'default_price_rows'                       => '',
2114
-            'default_base_price_amount'                => 0,
2115
-            'default_base_price_name'                  => '',
2116
-            'default_base_price_description'           => '',
2117
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2118
-                'TICKETNUM',
2119
-                'PRICENUM',
2120
-                null,
2121
-                true
2122
-            ),
2123
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2124
-                'DTTNUM',
2125
-                null,
2126
-                array(),
2127
-                array(),
2128
-                true
2129
-            ),
2130
-            'existing_available_datetime_tickets_list' => '',
2131
-            'existing_available_ticket_datetimes_list' => '',
2132
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2133
-                'DTTNUM',
2134
-                'TICKETNUM',
2135
-                null,
2136
-                null,
2137
-                array(),
2138
-                true
2139
-            ),
2140
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2141
-                'DTTNUM',
2142
-                'TICKETNUM',
2143
-                null,
2144
-                null,
2145
-                array(),
2146
-                true
2147
-            ),
2148
-        );
2149
-        $ticket_row = 1;
2150
-        foreach ($all_tickets as $ticket) {
2151
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2152
-                'DTTNUM',
2153
-                $ticket_row,
2154
-                null,
2155
-                $ticket,
2156
-                array(),
2157
-                true
2158
-            );
2159
-            $ticket_row++;
2160
-        }
2161
-        $datetime_row = 1;
2162
-        foreach ($all_datetimes as $datetime) {
2163
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2164
-                $datetime_row,
2165
-                'TICKETNUM',
2166
-                $datetime,
2167
-                null,
2168
-                array(),
2169
-                true
2170
-            );
2171
-            $datetime_row++;
2172
-        }
2173
-        /** @var EEM_Price $price_model */
2174
-        $price_model = EE_Registry::instance()->load_model('Price');
2175
-        $default_prices = $price_model->get_all_default_prices();
2176
-        $price_row = 1;
2177
-        foreach ($default_prices as $price) {
2178
-            if (! $price instanceof EE_Price) {
2179
-                continue;
2180
-            }
2181
-            if ($price->is_base_price()) {
2182
-                $template_args['default_base_price_amount'] = $price->get_pretty(
2183
-                    'PRC_amount',
2184
-                    'localized_float'
2185
-                );
2186
-                $template_args['default_base_price_name'] = $price->get('PRC_name');
2187
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
2188
-                $price_row++;
2189
-                continue;
2190
-            }
2191
-            $show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2192
-                             || count($default_prices) === 1);
2193
-            $show_create = ! (count($default_prices) > 1
2194
-                              && count($default_prices)
2195
-                                 !== $price_row);
2196
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2197
-                'TICKETNUM',
2198
-                $price_row,
2199
-                $price,
2200
-                true,
2201
-                null,
2202
-                $show_trash,
2203
-                $show_create
2204
-            );
2205
-            $price_row++;
2206
-        }
2207
-        $template_args = apply_filters(
2208
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2209
-            $template_args,
2210
-            $all_datetimes,
2211
-            $all_tickets,
2212
-            $this->_is_creating_event
2213
-        );
2214
-        return EEH_Template::display_template(
2215
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2216
-            $template_args,
2217
-            true
2218
-        );
2219
-    }
2079
+	/**
2080
+	 * @param array $all_datetimes
2081
+	 * @param array $all_tickets
2082
+	 * @return mixed
2083
+	 * @throws ReflectionException
2084
+	 * @throws InvalidArgumentException
2085
+	 * @throws InvalidInterfaceException
2086
+	 * @throws InvalidDataTypeException
2087
+	 * @throws DomainException
2088
+	 * @throws EE_Error
2089
+	 */
2090
+	protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2091
+	{
2092
+		$template_args = array(
2093
+			'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2094
+				'DTTNUM',
2095
+				null,
2096
+				true,
2097
+				$all_datetimes
2098
+			),
2099
+			'default_ticket_row'                       => $this->_get_ticket_row(
2100
+				'TICKETNUM',
2101
+				null,
2102
+				array(),
2103
+				array(),
2104
+				true
2105
+			),
2106
+			'default_price_row'                        => $this->_get_ticket_price_row(
2107
+				'TICKETNUM',
2108
+				'PRICENUM',
2109
+				null,
2110
+				true,
2111
+				null
2112
+			),
2113
+			'default_price_rows'                       => '',
2114
+			'default_base_price_amount'                => 0,
2115
+			'default_base_price_name'                  => '',
2116
+			'default_base_price_description'           => '',
2117
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2118
+				'TICKETNUM',
2119
+				'PRICENUM',
2120
+				null,
2121
+				true
2122
+			),
2123
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2124
+				'DTTNUM',
2125
+				null,
2126
+				array(),
2127
+				array(),
2128
+				true
2129
+			),
2130
+			'existing_available_datetime_tickets_list' => '',
2131
+			'existing_available_ticket_datetimes_list' => '',
2132
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2133
+				'DTTNUM',
2134
+				'TICKETNUM',
2135
+				null,
2136
+				null,
2137
+				array(),
2138
+				true
2139
+			),
2140
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2141
+				'DTTNUM',
2142
+				'TICKETNUM',
2143
+				null,
2144
+				null,
2145
+				array(),
2146
+				true
2147
+			),
2148
+		);
2149
+		$ticket_row = 1;
2150
+		foreach ($all_tickets as $ticket) {
2151
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2152
+				'DTTNUM',
2153
+				$ticket_row,
2154
+				null,
2155
+				$ticket,
2156
+				array(),
2157
+				true
2158
+			);
2159
+			$ticket_row++;
2160
+		}
2161
+		$datetime_row = 1;
2162
+		foreach ($all_datetimes as $datetime) {
2163
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2164
+				$datetime_row,
2165
+				'TICKETNUM',
2166
+				$datetime,
2167
+				null,
2168
+				array(),
2169
+				true
2170
+			);
2171
+			$datetime_row++;
2172
+		}
2173
+		/** @var EEM_Price $price_model */
2174
+		$price_model = EE_Registry::instance()->load_model('Price');
2175
+		$default_prices = $price_model->get_all_default_prices();
2176
+		$price_row = 1;
2177
+		foreach ($default_prices as $price) {
2178
+			if (! $price instanceof EE_Price) {
2179
+				continue;
2180
+			}
2181
+			if ($price->is_base_price()) {
2182
+				$template_args['default_base_price_amount'] = $price->get_pretty(
2183
+					'PRC_amount',
2184
+					'localized_float'
2185
+				);
2186
+				$template_args['default_base_price_name'] = $price->get('PRC_name');
2187
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
2188
+				$price_row++;
2189
+				continue;
2190
+			}
2191
+			$show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2192
+							 || count($default_prices) === 1);
2193
+			$show_create = ! (count($default_prices) > 1
2194
+							  && count($default_prices)
2195
+								 !== $price_row);
2196
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2197
+				'TICKETNUM',
2198
+				$price_row,
2199
+				$price,
2200
+				true,
2201
+				null,
2202
+				$show_trash,
2203
+				$show_create
2204
+			);
2205
+			$price_row++;
2206
+		}
2207
+		$template_args = apply_filters(
2208
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2209
+			$template_args,
2210
+			$all_datetimes,
2211
+			$all_tickets,
2212
+			$this->_is_creating_event
2213
+		);
2214
+		return EEH_Template::display_template(
2215
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2216
+			$template_args,
2217
+			true
2218
+		);
2219
+	}
2220 2220
 }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2809 added lines, -2809 removed lines patch added patch discarded remove patch
@@ -15,2816 +15,2816 @@
 block discarded – undo
15 15
  */
16 16
 class Events_Admin_Page extends EE_Admin_Page_CPT
17 17
 {
18
-    /**
19
-     * This will hold the event object for event_details screen.
18
+	/**
19
+	 * This will hold the event object for event_details screen.
20
+	 *
21
+	 * @var EE_Event $_event
22
+	 */
23
+	protected $_event;
24
+
25
+
26
+	/**
27
+	 * This will hold the category object for category_details screen.
28
+	 *
29
+	 * @var stdClass $_category
30
+	 */
31
+	protected $_category;
32
+
33
+
34
+	/**
35
+	 * This will hold the event model instance
36
+	 *
37
+	 * @var EEM_Event $_event_model
38
+	 */
39
+	protected $_event_model;
40
+
41
+
42
+	/**
43
+	 * @var EE_Event
44
+	 */
45
+	protected $_cpt_model_obj = false;
46
+
47
+
48
+	/**
49
+	 * @var NodeGroupDao
50
+	 */
51
+	protected $model_obj_node_group_persister;
52
+
53
+
54
+	/**
55
+	 * Initialize page props for this admin page group.
56
+	 */
57
+	protected function _init_page_props()
58
+	{
59
+		$this->page_slug        = EVENTS_PG_SLUG;
60
+		$this->page_label       = EVENTS_LABEL;
61
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
62
+		$this->_admin_base_path = EVENTS_ADMIN;
63
+		$this->_cpt_model_names = [
64
+			'create_new' => 'EEM_Event',
65
+			'edit'       => 'EEM_Event',
66
+		];
67
+		$this->_cpt_edit_routes = [
68
+			'espresso_events' => 'edit',
69
+		];
70
+		add_action(
71
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
72
+			[$this, 'verify_event_edit'],
73
+			10,
74
+			2
75
+		);
76
+	}
77
+
78
+
79
+	/**
80
+	 * Sets the ajax hooks used for this admin page group.
81
+	 */
82
+	protected function _ajax_hooks()
83
+	{
84
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
85
+	}
86
+
87
+
88
+	/**
89
+	 * Sets the page properties for this admin page group.
90
+	 */
91
+	protected function _define_page_props()
92
+	{
93
+		$this->_admin_page_title = EVENTS_LABEL;
94
+		$this->_labels           = [
95
+			'buttons'      => [
96
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
97
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
98
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
99
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
100
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
101
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
102
+			],
103
+			'editor_title' => [
104
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
105
+			],
106
+			'publishbox'   => [
107
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
108
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
109
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
110
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
111
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
112
+			],
113
+		];
114
+	}
115
+
116
+
117
+	/**
118
+	 * Sets the page routes property for this admin page group.
119
+	 */
120
+	protected function _set_page_routes()
121
+	{
122
+		// load formatter helper
123
+		// load field generator helper
124
+		// is there a evt_id in the request?
125
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
126
+		$EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
127
+
128
+		$this->_page_routes = [
129
+			'default'                       => [
130
+				'func'       => [$this, '_events_overview_list_table'],
131
+				'capability' => 'ee_read_events',
132
+			],
133
+			'create_new'                    => [
134
+				'func'       => [$this, '_create_new_cpt_item'],
135
+				'capability' => 'ee_edit_events',
136
+			],
137
+			'edit'                          => [
138
+				'func'       => [$this, '_edit_cpt_item'],
139
+				'capability' => 'ee_edit_event',
140
+				'obj_id'     => $EVT_ID,
141
+			],
142
+			'copy_event'                    => [
143
+				'func'       => [$this, '_copy_events'],
144
+				'capability' => 'ee_edit_event',
145
+				'obj_id'     => $EVT_ID,
146
+				'noheader'   => true,
147
+			],
148
+			'trash_event'                   => [
149
+				'func'       => [$this, '_trash_or_restore_event'],
150
+				'args'       => ['event_status' => 'trash'],
151
+				'capability' => 'ee_delete_event',
152
+				'obj_id'     => $EVT_ID,
153
+				'noheader'   => true,
154
+			],
155
+			'trash_events'                  => [
156
+				'func'       => [$this, '_trash_or_restore_events'],
157
+				'args'       => ['event_status' => 'trash'],
158
+				'capability' => 'ee_delete_events',
159
+				'noheader'   => true,
160
+			],
161
+			'restore_event'                 => [
162
+				'func'       => [$this, '_trash_or_restore_event'],
163
+				'args'       => ['event_status' => 'draft'],
164
+				'capability' => 'ee_delete_event',
165
+				'obj_id'     => $EVT_ID,
166
+				'noheader'   => true,
167
+			],
168
+			'restore_events'                => [
169
+				'func'       => [$this, '_trash_or_restore_events'],
170
+				'args'       => ['event_status' => 'draft'],
171
+				'capability' => 'ee_delete_events',
172
+				'noheader'   => true,
173
+			],
174
+			'delete_event'                  => [
175
+				'func'       => [$this, '_delete_event'],
176
+				'capability' => 'ee_delete_event',
177
+				'obj_id'     => $EVT_ID,
178
+				'noheader'   => true,
179
+			],
180
+			'delete_events'                 => [
181
+				'func'       => [$this, '_delete_events'],
182
+				'capability' => 'ee_delete_events',
183
+				'noheader'   => true,
184
+			],
185
+			'view_report'                   => [
186
+				'func'       => [$this, '_view_report'],
187
+				'capability' => 'ee_edit_events',
188
+			],
189
+			'default_event_settings'        => [
190
+				'func'       => [$this, '_default_event_settings'],
191
+				'capability' => 'manage_options',
192
+			],
193
+			'update_default_event_settings' => [
194
+				'func'       => [$this, '_update_default_event_settings'],
195
+				'capability' => 'manage_options',
196
+				'noheader'   => true,
197
+			],
198
+			'template_settings'             => [
199
+				'func'       => [$this, '_template_settings'],
200
+				'capability' => 'manage_options',
201
+			],
202
+			// event category tab related
203
+			'add_category'                  => [
204
+				'func'       => [$this, '_category_details'],
205
+				'capability' => 'ee_edit_event_category',
206
+				'args'       => ['add'],
207
+			],
208
+			'edit_category'                 => [
209
+				'func'       => [$this, '_category_details'],
210
+				'capability' => 'ee_edit_event_category',
211
+				'args'       => ['edit'],
212
+			],
213
+			'delete_categories'             => [
214
+				'func'       => [$this, '_delete_categories'],
215
+				'capability' => 'ee_delete_event_category',
216
+				'noheader'   => true,
217
+			],
218
+			'delete_category'               => [
219
+				'func'       => [$this, '_delete_categories'],
220
+				'capability' => 'ee_delete_event_category',
221
+				'noheader'   => true,
222
+			],
223
+			'insert_category'               => [
224
+				'func'       => [$this, '_insert_or_update_category'],
225
+				'args'       => ['new_category' => true],
226
+				'capability' => 'ee_edit_event_category',
227
+				'noheader'   => true,
228
+			],
229
+			'update_category'               => [
230
+				'func'       => [$this, '_insert_or_update_category'],
231
+				'args'       => ['new_category' => false],
232
+				'capability' => 'ee_edit_event_category',
233
+				'noheader'   => true,
234
+			],
235
+			'category_list'                 => [
236
+				'func'       => [$this, '_category_list_table'],
237
+				'capability' => 'ee_manage_event_categories',
238
+			],
239
+			'preview_deletion'              => [
240
+				'func'       => [$this, 'previewDeletion'],
241
+				'capability' => 'ee_delete_events',
242
+			],
243
+			'confirm_deletion'              => [
244
+				'func'       => [$this, 'confirmDeletion'],
245
+				'capability' => 'ee_delete_events',
246
+				'noheader'   => true,
247
+			],
248
+		];
249
+	}
250
+
251
+
252
+	/**
253
+	 * Set the _page_config property for this admin page group.
254
+	 */
255
+	protected function _set_page_config()
256
+	{
257
+		$post_id            = $this->request->getRequestParam('post', 0, 'int');
258
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
259
+		$this->_page_config = [
260
+			'default'                => [
261
+				'nav'           => [
262
+					'label' => esc_html__('Overview', 'event_espresso'),
263
+					'order' => 10,
264
+				],
265
+				'list_table'    => 'Events_Admin_List_Table',
266
+				'help_tabs'     => [
267
+					'events_overview_help_tab'                       => [
268
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
269
+						'filename' => 'events_overview',
270
+					],
271
+					'events_overview_table_column_headings_help_tab' => [
272
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
273
+						'filename' => 'events_overview_table_column_headings',
274
+					],
275
+					'events_overview_filters_help_tab'               => [
276
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
277
+						'filename' => 'events_overview_filters',
278
+					],
279
+					'events_overview_view_help_tab'                  => [
280
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
281
+						'filename' => 'events_overview_views',
282
+					],
283
+					'events_overview_other_help_tab'                 => [
284
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
285
+						'filename' => 'events_overview_other',
286
+					],
287
+				],
288
+				'qtips'         => [
289
+					'EE_Event_List_Table_Tips',
290
+				],
291
+				'require_nonce' => false,
292
+			],
293
+			'create_new'             => [
294
+				'nav'           => [
295
+					'label'      => esc_html__('Add Event', 'event_espresso'),
296
+					'order'      => 5,
297
+					'persistent' => false,
298
+				],
299
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
300
+				'help_tabs'     => [
301
+					'event_editor_help_tab'                            => [
302
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
303
+						'filename' => 'event_editor',
304
+					],
305
+					'event_editor_title_richtexteditor_help_tab'       => [
306
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
307
+						'filename' => 'event_editor_title_richtexteditor',
308
+					],
309
+					'event_editor_venue_details_help_tab'              => [
310
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
311
+						'filename' => 'event_editor_venue_details',
312
+					],
313
+					'event_editor_event_datetimes_help_tab'            => [
314
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
315
+						'filename' => 'event_editor_event_datetimes',
316
+					],
317
+					'event_editor_event_tickets_help_tab'              => [
318
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
319
+						'filename' => 'event_editor_event_tickets',
320
+					],
321
+					'event_editor_event_registration_options_help_tab' => [
322
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
323
+						'filename' => 'event_editor_event_registration_options',
324
+					],
325
+					'event_editor_tags_categories_help_tab'            => [
326
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
327
+						'filename' => 'event_editor_tags_categories',
328
+					],
329
+					'event_editor_questions_registrants_help_tab'      => [
330
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
331
+						'filename' => 'event_editor_questions_registrants',
332
+					],
333
+					'event_editor_save_new_event_help_tab'             => [
334
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
335
+						'filename' => 'event_editor_save_new_event',
336
+					],
337
+					'event_editor_other_help_tab'                      => [
338
+						'title'    => esc_html__('Event Other', 'event_espresso'),
339
+						'filename' => 'event_editor_other',
340
+					],
341
+				],
342
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
343
+				'require_nonce' => false,
344
+			],
345
+			'edit'                   => [
346
+				'nav'           => [
347
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
348
+					'order'      => 5,
349
+					'persistent' => false,
350
+					'url'        => $post_id
351
+						? EE_Admin_Page::add_query_args_and_nonce(
352
+							['post' => $post_id, 'action' => 'edit'],
353
+							$this->_current_page_view_url
354
+						)
355
+						: $this->_admin_base_url,
356
+				],
357
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
358
+				'help_tabs'     => [
359
+					'event_editor_help_tab'                            => [
360
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
361
+						'filename' => 'event_editor',
362
+					],
363
+					'event_editor_title_richtexteditor_help_tab'       => [
364
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
365
+						'filename' => 'event_editor_title_richtexteditor',
366
+					],
367
+					'event_editor_venue_details_help_tab'              => [
368
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
369
+						'filename' => 'event_editor_venue_details',
370
+					],
371
+					'event_editor_event_datetimes_help_tab'            => [
372
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
373
+						'filename' => 'event_editor_event_datetimes',
374
+					],
375
+					'event_editor_event_tickets_help_tab'              => [
376
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
377
+						'filename' => 'event_editor_event_tickets',
378
+					],
379
+					'event_editor_event_registration_options_help_tab' => [
380
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
381
+						'filename' => 'event_editor_event_registration_options',
382
+					],
383
+					'event_editor_tags_categories_help_tab'            => [
384
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
385
+						'filename' => 'event_editor_tags_categories',
386
+					],
387
+					'event_editor_questions_registrants_help_tab'      => [
388
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
389
+						'filename' => 'event_editor_questions_registrants',
390
+					],
391
+					'event_editor_save_new_event_help_tab'             => [
392
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
393
+						'filename' => 'event_editor_save_new_event',
394
+					],
395
+					'event_editor_other_help_tab'                      => [
396
+						'title'    => esc_html__('Event Other', 'event_espresso'),
397
+						'filename' => 'event_editor_other',
398
+					],
399
+				],
400
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
401
+				'require_nonce' => false,
402
+			],
403
+			'default_event_settings' => [
404
+				'nav'           => [
405
+					'label' => esc_html__('Default Settings', 'event_espresso'),
406
+					'order' => 40,
407
+				],
408
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
409
+				'labels'        => [
410
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
411
+				],
412
+				'help_tabs'     => [
413
+					'default_settings_help_tab'        => [
414
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
415
+						'filename' => 'events_default_settings',
416
+					],
417
+					'default_settings_status_help_tab' => [
418
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
419
+						'filename' => 'events_default_settings_status',
420
+					],
421
+					'default_maximum_tickets_help_tab' => [
422
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
423
+						'filename' => 'events_default_settings_max_tickets',
424
+					],
425
+				],
426
+				'require_nonce' => false,
427
+			],
428
+			// template settings
429
+			'template_settings'      => [
430
+				'nav'           => [
431
+					'label' => esc_html__('Templates', 'event_espresso'),
432
+					'order' => 30,
433
+				],
434
+				'metaboxes'     => $this->_default_espresso_metaboxes,
435
+				'help_tabs'     => [
436
+					'general_settings_templates_help_tab' => [
437
+						'title'    => esc_html__('Templates', 'event_espresso'),
438
+						'filename' => 'general_settings_templates',
439
+					],
440
+				],
441
+				'require_nonce' => false,
442
+			],
443
+			// event category stuff
444
+			'add_category'           => [
445
+				'nav'           => [
446
+					'label'      => esc_html__('Add Category', 'event_espresso'),
447
+					'order'      => 15,
448
+					'persistent' => false,
449
+				],
450
+				'help_tabs'     => [
451
+					'add_category_help_tab' => [
452
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
453
+						'filename' => 'events_add_category',
454
+					],
455
+				],
456
+				'metaboxes'     => ['_publish_post_box'],
457
+				'require_nonce' => false,
458
+			],
459
+			'edit_category'          => [
460
+				'nav'           => [
461
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
462
+					'order'      => 15,
463
+					'persistent' => false,
464
+					'url'        => $EVT_CAT_ID
465
+						? add_query_arg(
466
+							['EVT_CAT_ID' => $EVT_CAT_ID],
467
+							$this->_current_page_view_url
468
+						)
469
+						: $this->_admin_base_url,
470
+				],
471
+				'help_tabs'     => [
472
+					'edit_category_help_tab' => [
473
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
474
+						'filename' => 'events_edit_category',
475
+					],
476
+				],
477
+				'metaboxes'     => ['_publish_post_box'],
478
+				'require_nonce' => false,
479
+			],
480
+			'category_list'          => [
481
+				'nav'           => [
482
+					'label' => esc_html__('Categories', 'event_espresso'),
483
+					'order' => 20,
484
+				],
485
+				'list_table'    => 'Event_Categories_Admin_List_Table',
486
+				'help_tabs'     => [
487
+					'events_categories_help_tab'                       => [
488
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
489
+						'filename' => 'events_categories',
490
+					],
491
+					'events_categories_table_column_headings_help_tab' => [
492
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
493
+						'filename' => 'events_categories_table_column_headings',
494
+					],
495
+					'events_categories_view_help_tab'                  => [
496
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
497
+						'filename' => 'events_categories_views',
498
+					],
499
+					'events_categories_other_help_tab'                 => [
500
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
501
+						'filename' => 'events_categories_other',
502
+					],
503
+				],
504
+				'metaboxes'     => $this->_default_espresso_metaboxes,
505
+				'require_nonce' => false,
506
+			],
507
+			'preview_deletion'       => [
508
+				'nav'           => [
509
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
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
+	protected function _add_screen_options_default()
532
+	{
533
+		$this->_per_page_screen_option();
534
+	}
535
+
536
+
537
+	/**
538
+	 * Implementing screen options for the category list route.
539
+	 */
540
+	protected function _add_screen_options_category_list()
541
+	{
542
+		$page_title              = $this->_admin_page_title;
543
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
544
+		$this->_per_page_screen_option();
545
+		$this->_admin_page_title = $page_title;
546
+	}
547
+
548
+
549
+	/**
550
+	 * Used to register any global feature pointers for the admin page group.
551
+	 */
552
+	protected function _add_feature_pointers()
553
+	{
554
+	}
555
+
556
+
557
+	/**
558
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
559
+	 */
560
+	public function load_scripts_styles()
561
+	{
562
+		wp_register_style(
563
+			'events-admin-css',
564
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
565
+			[],
566
+			EVENT_ESPRESSO_VERSION
567
+		);
568
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
569
+		wp_enqueue_style('events-admin-css');
570
+		wp_enqueue_style('ee-cat-admin');
571
+		// todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
572
+		// registers for all views
573
+		// scripts
574
+		wp_register_script(
575
+			'event_editor_js',
576
+			EVENTS_ASSETS_URL . 'event_editor.js',
577
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
578
+			EVENT_ESPRESSO_VERSION,
579
+			true
580
+		);
581
+	}
582
+
583
+
584
+	/**
585
+	 * Enqueuing scripts and styles specific to this view
586
+	 */
587
+	public function load_scripts_styles_create_new()
588
+	{
589
+		$this->load_scripts_styles_edit();
590
+	}
591
+
592
+
593
+	/**
594
+	 * Enqueuing scripts and styles specific to this view
595
+	 */
596
+	public function load_scripts_styles_edit()
597
+	{
598
+		// styles
599
+		wp_enqueue_style('espresso-ui-theme');
600
+		wp_register_style(
601
+			'event-editor-css',
602
+			EVENTS_ASSETS_URL . 'event-editor.css',
603
+			['ee-admin-css'],
604
+			EVENT_ESPRESSO_VERSION
605
+		);
606
+		wp_enqueue_style('event-editor-css');
607
+		// scripts
608
+		wp_register_script(
609
+			'event-datetime-metabox',
610
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
611
+			['event_editor_js', 'ee-datepicker'],
612
+			EVENT_ESPRESSO_VERSION
613
+		);
614
+		wp_enqueue_script('event-datetime-metabox');
615
+	}
616
+
617
+
618
+	/**
619
+	 * Populating the _views property for the category list table view.
620
+	 */
621
+	protected function _set_list_table_views_category_list()
622
+	{
623
+		$this->_views = [
624
+			'all' => [
625
+				'slug'        => 'all',
626
+				'label'       => esc_html__('All', 'event_espresso'),
627
+				'count'       => 0,
628
+				'bulk_action' => [
629
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
630
+				],
631
+			],
632
+		];
633
+	}
634
+
635
+
636
+	/**
637
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
638
+	 */
639
+	public function admin_init()
640
+	{
641
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
642
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
643
+			'event_espresso'
644
+		);
645
+	}
646
+
647
+
648
+	/**
649
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
650
+	 * group.
651
+	 */
652
+	public function admin_notices()
653
+	{
654
+	}
655
+
656
+
657
+	/**
658
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
659
+	 * this admin page group.
660
+	 */
661
+	public function admin_footer_scripts()
662
+	{
663
+	}
664
+
665
+
666
+	/**
667
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
668
+	 * warning (via EE_Error::add_error());
669
+	 *
670
+	 * @param EE_Event $event Event object
671
+	 * @param string   $req_type
672
+	 * @return void
673
+	 * @throws EE_Error
674
+	 * @throws ReflectionException
675
+	 */
676
+	public function verify_event_edit($event = null, $req_type = '')
677
+	{
678
+		// don't need to do this when processing
679
+		if (! empty($req_type)) {
680
+			return;
681
+		}
682
+		// no event?
683
+		if (empty($event)) {
684
+			// set event
685
+			$event = $this->_cpt_model_obj;
686
+		}
687
+		// STILL no event?
688
+		if (! $event instanceof EE_Event) {
689
+			return;
690
+		}
691
+		$orig_status = $event->status();
692
+		// first check if event is active.
693
+		if (
694
+			$orig_status === EEM_Event::cancelled
695
+			|| $orig_status === EEM_Event::postponed
696
+			|| $event->is_expired()
697
+			|| $event->is_inactive()
698
+		) {
699
+			return;
700
+		}
701
+		// made it here so it IS active... next check that any of the tickets are sold.
702
+		if ($event->is_sold_out(true)) {
703
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
704
+				EE_Error::add_attention(
705
+					sprintf(
706
+						esc_html__(
707
+							'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.',
708
+							'event_espresso'
709
+						),
710
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
711
+					)
712
+				);
713
+			}
714
+			return;
715
+		} elseif ($orig_status === EEM_Event::sold_out) {
716
+			EE_Error::add_attention(
717
+				sprintf(
718
+					esc_html__(
719
+						'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.',
720
+						'event_espresso'
721
+					),
722
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
723
+				)
724
+			);
725
+		}
726
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
727
+		if (! $event->tickets_on_sale()) {
728
+			return;
729
+		}
730
+		// made it here so show warning
731
+		$this->_edit_event_warning();
732
+	}
733
+
734
+
735
+	/**
736
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
737
+	 * When needed, hook this into a EE_Error::add_error() notice.
738
+	 *
739
+	 * @access protected
740
+	 * @return void
741
+	 */
742
+	protected function _edit_event_warning()
743
+	{
744
+		// we don't want to add warnings during these requests
745
+		if ($this->request->getRequestParam('action') === 'editpost') {
746
+			return;
747
+		}
748
+		EE_Error::add_attention(
749
+			sprintf(
750
+				esc_html__(
751
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
752
+					'event_espresso'
753
+				),
754
+				'<a class="espresso-help-tab-lnk">',
755
+				'</a>'
756
+			)
757
+		);
758
+	}
759
+
760
+
761
+	/**
762
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
763
+	 * Otherwise, do the normal logic
764
+	 *
765
+	 * @return void
766
+	 * @throws EE_Error
767
+	 */
768
+	protected function _create_new_cpt_item()
769
+	{
770
+		$has_timezone_string = get_option('timezone_string');
771
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
772
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
773
+			EE_Error::add_attention(
774
+				sprintf(
775
+					esc_html__(
776
+						'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',
777
+						'event_espresso'
778
+					),
779
+					'<br>',
780
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
781
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
782
+					. '</select>',
783
+					'<button class="button button-secondary timezone-submit">',
784
+					'</button><span class="spinner"></span>'
785
+				),
786
+				__FILE__,
787
+				__FUNCTION__,
788
+				__LINE__
789
+			);
790
+		}
791
+		parent::_create_new_cpt_item();
792
+	}
793
+
794
+
795
+	/**
796
+	 * Sets the _views property for the default route in this admin page group.
797
+	 */
798
+	protected function _set_list_table_views_default()
799
+	{
800
+		$this->_views = [
801
+			'all'   => [
802
+				'slug'        => 'all',
803
+				'label'       => esc_html__('View All Events', 'event_espresso'),
804
+				'count'       => 0,
805
+				'bulk_action' => [
806
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
807
+				],
808
+			],
809
+			'draft' => [
810
+				'slug'        => 'draft',
811
+				'label'       => esc_html__('Draft', 'event_espresso'),
812
+				'count'       => 0,
813
+				'bulk_action' => [
814
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
815
+				],
816
+			],
817
+		];
818
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
819
+			$this->_views['trash'] = [
820
+				'slug'        => 'trash',
821
+				'label'       => esc_html__('Trash', 'event_espresso'),
822
+				'count'       => 0,
823
+				'bulk_action' => [
824
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
825
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
826
+				],
827
+			];
828
+		}
829
+	}
830
+
831
+
832
+	/**
833
+	 * Provides the legend item array for the default list table view.
834
+	 *
835
+	 * @return array
836
+	 * @throws EE_Error
837
+	 * @throws EE_Error
838
+	 */
839
+	protected function _event_legend_items()
840
+	{
841
+		$items    = [
842
+			'view_details'   => [
843
+				'class' => 'dashicons dashicons-search',
844
+				'desc'  => esc_html__('View Event', 'event_espresso'),
845
+			],
846
+			'edit_event'     => [
847
+				'class' => 'ee-icon ee-icon-calendar-edit',
848
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
849
+			],
850
+			'view_attendees' => [
851
+				'class' => 'dashicons dashicons-groups',
852
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
853
+			],
854
+		];
855
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856
+		$statuses = [
857
+			'sold_out_status'  => [
858
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
859
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860
+			],
861
+			'active_status'    => [
862
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
863
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864
+			],
865
+			'upcoming_status'  => [
866
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
867
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868
+			],
869
+			'postponed_status' => [
870
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
871
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872
+			],
873
+			'cancelled_status' => [
874
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
875
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876
+			],
877
+			'expired_status'   => [
878
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
879
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880
+			],
881
+			'inactive_status'  => [
882
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
883
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884
+			],
885
+		];
886
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
887
+		return array_merge($items, $statuses);
888
+	}
889
+
890
+
891
+	/**
892
+	 * @return EEM_Event
893
+	 * @throws EE_Error
894
+	 * @throws ReflectionException
895
+	 */
896
+	private function _event_model()
897
+	{
898
+		if (! $this->_event_model instanceof EEM_Event) {
899
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
900
+		}
901
+		return $this->_event_model;
902
+	}
903
+
904
+
905
+	/**
906
+	 * Adds extra buttons to the WP CPT permalink field row.
907
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
908
+	 *
909
+	 * @param string $return    the current html
910
+	 * @param int    $id        the post id for the page
911
+	 * @param string $new_title What the title is
912
+	 * @param string $new_slug  what the slug is
913
+	 * @return string            The new html string for the permalink area
914
+	 */
915
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
916
+	{
917
+		// make sure this is only when editing
918
+		if (! empty($id)) {
919
+			$post   = get_post($id);
920
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
921
+					   . esc_html__('Shortcode', 'event_espresso')
922
+					   . '</a> ';
923
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
924
+					   . $post->ID
925
+					   . ']">';
926
+		}
927
+		return $return;
928
+	}
929
+
930
+
931
+	/**
932
+	 * _events_overview_list_table
933
+	 * This contains the logic for showing the events_overview list
934
+	 *
935
+	 * @access protected
936
+	 * @return void
937
+	 * @throws EE_Error
938
+	 */
939
+	protected function _events_overview_list_table()
940
+	{
941
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
942
+		$this->_template_args['after_list_table']                           =
943
+			! empty($this->_template_args['after_list_table'])
944
+				? (array) $this->_template_args['after_list_table']
945
+				: [];
946
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
947
+			. EEH_Template::get_button_or_link(
948
+				get_post_type_archive_link('espresso_events'),
949
+				esc_html__("View Event Archive Page", "event_espresso"),
950
+				'button'
951
+			);
952
+		$this->_template_args['after_list_table']['legend']                 = $this->_display_legend(
953
+			$this->_event_legend_items()
954
+		);
955
+		$this->_admin_page_title                                            .= ' ' . $this->get_action_link_or_button(
956
+			'create_new',
957
+			'add',
958
+			[],
959
+			'add-new-h2'
960
+		);
961
+		$this->display_admin_list_table_page_with_no_sidebar();
962
+	}
963
+
964
+
965
+	/**
966
+	 * this allows for extra misc actions in the default WP publish box
967
+	 *
968
+	 * @return void
969
+	 * @throws EE_Error
970
+	 * @throws ReflectionException
971
+	 */
972
+	public function extra_misc_actions_publish_box()
973
+	{
974
+		$this->_generate_publish_box_extra_content();
975
+	}
976
+
977
+
978
+	/**
979
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
980
+	 * saved.
981
+	 * Typically you would use this to save any additional data.
982
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
983
+	 * ALSO very important.  When a post transitions from scheduled to published,
984
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
985
+	 * other meta saves. So MAKE sure that you handle this accordingly.
986
+	 *
987
+	 * @access protected
988
+	 * @abstract
989
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
990
+	 * @param WP_Post $post    The post object of the cpt that was saved.
991
+	 * @return void
992
+	 * @throws EE_Error
993
+	 * @throws ReflectionException
994
+	 */
995
+	protected function _insert_update_cpt_item($post_id, $post)
996
+	{
997
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
998
+			// get out we're not processing an event save.
999
+			return;
1000
+		}
1001
+
1002
+		$event_values = [
1003
+			'EVT_display_desc'                => $this->request->getRequestParam('display_desc', false, 'bool'),
1004
+			'EVT_display_ticket_selector'     => $this->request->getRequestParam(
1005
+				'display_ticket_selector',
1006
+				false,
1007
+				'bool'
1008
+			),
1009
+			'EVT_additional_limit'            => min(
1010
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1011
+				$this->request->getRequestParam('additional_limit', null, 'int')
1012
+			),
1013
+			'EVT_default_registration_status' => $this->request->getRequestParam(
1014
+				'EVT_default_registration_status',
1015
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1016
+			),
1017
+
1018
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1019
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1020
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1021
+			'EVT_external_URL'    => $this->request->getRequestParam('externalURL'),
1022
+			'EVT_phone'           => $this->request->getRequestParam('event_phone'),
1023
+		];
1024
+		// update event
1025
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1026
+		// get event_object for other metaboxes...
1027
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1028
+		// i have to setup where conditions to override the filters in the model
1029
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1030
+		$event = $this->_event_model()->get_one(
1031
+			[
1032
+				[
1033
+					$this->_event_model()->primary_key_name() => $post_id,
1034
+					'OR'                                      => [
1035
+						'status'   => $post->post_status,
1036
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1037
+						// but the returned object here has a status of "publish", so use the original post status as well
1038
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1039
+					],
1040
+				],
1041
+			]
1042
+		);
1043
+		// the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1044
+		$event_update_callbacks = apply_filters(
1045
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1046
+			[
1047
+				[$this, '_default_venue_update'],
1048
+				[$this, '_default_tickets_update'],
1049
+			]
1050
+		);
1051
+		$att_success            = true;
1052
+		foreach ($event_update_callbacks as $e_callback) {
1053
+			$_success = is_callable($e_callback)
1054
+				? call_user_func($e_callback, $event, $this->request->requestParams())
1055
+				: false;
1056
+			// if ANY of these updates fail then we want the appropriate global error message
1057
+			$att_success = ! $att_success ? $att_success : $_success;
1058
+		}
1059
+		// any errors?
1060
+		if ($success && false === $att_success) {
1061
+			EE_Error::add_error(
1062
+				esc_html__(
1063
+					'Event Details saved successfully but something went wrong with saving attachments.',
1064
+					'event_espresso'
1065
+				),
1066
+				__FILE__,
1067
+				__FUNCTION__,
1068
+				__LINE__
1069
+			);
1070
+		} elseif ($success === false) {
1071
+			EE_Error::add_error(
1072
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1073
+				__FILE__,
1074
+				__FUNCTION__,
1075
+				__LINE__
1076
+			);
1077
+		}
1078
+	}
1079
+
1080
+
1081
+	/**
1082
+	 * @param int $post_id
1083
+	 * @param int $revision_id
1084
+	 * @throws EE_Error
1085
+	 * @throws EE_Error
1086
+	 * @throws ReflectionException
1087
+	 * @see parent::restore_item()
1088
+	 */
1089
+	protected function _restore_cpt_item($post_id, $revision_id)
1090
+	{
1091
+		// copy existing event meta to new post
1092
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1093
+		if ($post_evt instanceof EE_Event) {
1094
+			// meta revision restore
1095
+			$post_evt->restore_revision($revision_id);
1096
+			// related objs restore
1097
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1098
+		}
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * Attach the venue to the Event
1104
+	 *
1105
+	 * @param EE_Event $event Event Object to add the venue to
1106
+	 * @param array    $data  The request data from the form
1107
+	 * @return bool           Success or fail.
1108
+	 * @throws EE_Error
1109
+	 * @throws ReflectionException
1110
+	 */
1111
+	protected function _default_venue_update(EE_Event $event, $data)
1112
+	{
1113
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1114
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1115
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1116
+		// very important.  If we don't have a venue name...
1117
+		// then we'll get out because not necessary to create empty venue
1118
+		if (empty($data['venue_title'])) {
1119
+			return false;
1120
+		}
1121
+		$venue_array = [
1122
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1123
+			'VNU_name'            => $data['venue_title'],
1124
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1125
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1126
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1127
+				? $data['venue_short_description']
1128
+				: null,
1129
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1130
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1131
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1132
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1133
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1134
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1135
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1136
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1137
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1138
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1139
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1140
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1141
+			'status'              => 'publish',
1142
+		];
1143
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1144
+		if (! empty($venue_id)) {
1145
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1146
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1147
+			// we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1148
+			$event->_add_relation_to($venue_id, 'Venue');
1149
+			return $rows_affected > 0;
1150
+		}
1151
+		// we insert the venue
1152
+		$venue_id = $venue_model->insert($venue_array);
1153
+		$event->_add_relation_to($venue_id, 'Venue');
1154
+		return ! empty($venue_id);
1155
+		// when we have the ancestor come in it's already been handled by the revision save.
1156
+	}
1157
+
1158
+
1159
+	/**
1160
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1161
+	 *
1162
+	 * @param EE_Event $event The Event object we're attaching data to
1163
+	 * @param array    $data  The request data from the form
1164
+	 * @return array
1165
+	 * @throws EE_Error
1166
+	 * @throws ReflectionException
1167
+	 * @throws Exception
1168
+	 */
1169
+	protected function _default_tickets_update(EE_Event $event, $data)
1170
+	{
1171
+		$datetime       = null;
1172
+		$saved_tickets  = [];
1173
+		$event_timezone = $event->get_timezone();
1174
+		$date_formats   = ['Y-m-d', 'h:i a'];
1175
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1176
+			// trim all values to ensure any excess whitespace is removed.
1177
+			$datetime_data                = array_map('trim', $datetime_data);
1178
+			$datetime_data['DTT_EVT_end'] =
1179
+				isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1180
+					? $datetime_data['DTT_EVT_end']
1181
+					: $datetime_data['DTT_EVT_start'];
1182
+			$datetime_values              = [
1183
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1184
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1185
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1186
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1187
+				'DTT_order'     => $row,
1188
+			];
1189
+			// if we have an id then let's get existing object first and then set the new values.
1190
+			//  Otherwise we instantiate a new object for save.
1191
+			if (! empty($datetime_data['DTT_ID'])) {
1192
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1193
+				if (! $datetime instanceof EE_Datetime) {
1194
+					throw new RuntimeException(
1195
+						sprintf(
1196
+							esc_html__(
1197
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1198
+								'event_espresso'
1199
+							),
1200
+							$datetime_data['DTT_ID']
1201
+						)
1202
+					);
1203
+				}
1204
+				$datetime->set_date_format($date_formats[0]);
1205
+				$datetime->set_time_format($date_formats[1]);
1206
+				foreach ($datetime_values as $field => $value) {
1207
+					$datetime->set($field, $value);
1208
+				}
1209
+			} else {
1210
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1211
+			}
1212
+			if (! $datetime instanceof EE_Datetime) {
1213
+				throw new RuntimeException(
1214
+					sprintf(
1215
+						esc_html__(
1216
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1217
+							'event_espresso'
1218
+						),
1219
+						print_r($datetime_values, true)
1220
+					)
1221
+				);
1222
+			}
1223
+			// before going any further make sure our dates are setup correctly
1224
+			// so that the end date is always equal or greater than the start date.
1225
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1226
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1227
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1228
+			}
1229
+			$datetime->save();
1230
+			$event->_add_relation_to($datetime, 'Datetime');
1231
+		}
1232
+		// no datetimes get deleted so we don't do any of that logic here.
1233
+		// update tickets next
1234
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1235
+
1236
+		// set up some default start and end dates in case those are not present in the incoming data
1237
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1238
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1239
+		// use the start date of the first datetime for the end date
1240
+		$first_datetime   = $event->first_datetime();
1241
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1242
+
1243
+		// now process the incoming data
1244
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1245
+			$update_prices = false;
1246
+			$ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1247
+				? $data['edit_prices'][ $row ][1]['PRC_amount']
1248
+				: 0;
1249
+			// trim inputs to ensure any excess whitespace is removed.
1250
+			$ticket_data   = array_map('trim', $ticket_data);
1251
+			$ticket_values = [
1252
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1253
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1254
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1255
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1256
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1257
+					? $ticket_data['TKT_start_date']
1258
+					: $default_start_date,
1259
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1260
+					? $ticket_data['TKT_end_date']
1261
+					: $default_end_date,
1262
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1263
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1264
+					? $ticket_data['TKT_qty']
1265
+					: EE_INF,
1266
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1267
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1268
+					? $ticket_data['TKT_uses']
1269
+					: EE_INF,
1270
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1271
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1272
+				'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1273
+				'TKT_price'       => $ticket_price,
1274
+				'TKT_row'         => $row,
1275
+			];
1276
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1277
+			// which means in turn that the prices will become new prices as well.
1278
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1279
+				$ticket_values['TKT_ID']         = 0;
1280
+				$ticket_values['TKT_is_default'] = 0;
1281
+				$update_prices                   = true;
1282
+			}
1283
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1284
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1285
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1286
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1287
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1288
+			if (! empty($ticket_data['TKT_ID'])) {
1289
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1290
+				if (! $existing_ticket instanceof EE_Ticket) {
1291
+					throw new RuntimeException(
1292
+						sprintf(
1293
+							esc_html__(
1294
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1295
+								'event_espresso'
1296
+							),
1297
+							$ticket_data['TKT_ID']
1298
+						)
1299
+					);
1300
+				}
1301
+				$ticket_sold = $existing_ticket->count_related(
1302
+					'Registration',
1303
+					[
1304
+						[
1305
+							'STS_ID' => [
1306
+								'NOT IN',
1307
+								[EEM_Registration::status_id_incomplete],
1308
+							],
1309
+						],
1310
+					]
1311
+				) > 0;
1312
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1313
+				// if they are different then we create a new ticket (if $ticket_sold)
1314
+				// if they aren't different then we go ahead and modify existing ticket.
1315
+				$create_new_ticket = $ticket_sold
1316
+									 && $ticket_price !== $existing_ticket->price()
1317
+									 && ! $existing_ticket->deleted();
1318
+				$existing_ticket->set_date_format($date_formats[0]);
1319
+				$existing_ticket->set_time_format($date_formats[1]);
1320
+				// set new values
1321
+				foreach ($ticket_values as $field => $value) {
1322
+					if ($field == 'TKT_qty') {
1323
+						$existing_ticket->set_qty($value);
1324
+					} elseif ($field == 'TKT_price') {
1325
+						$existing_ticket->set('TKT_price', $ticket_price);
1326
+					} else {
1327
+						$existing_ticket->set($field, $value);
1328
+					}
1329
+				}
1330
+				$ticket = $existing_ticket;
1331
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1332
+				//  Otherwise we have to create a new ticket.
1333
+				if ($create_new_ticket) {
1334
+					// archive the old ticket first
1335
+					$existing_ticket->set('TKT_deleted', 1);
1336
+					$existing_ticket->save();
1337
+					// make sure this ticket is still recorded in our $saved_tickets
1338
+					// so we don't run it through the regular trash routine.
1339
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1340
+					// create new ticket that's a copy of the existing except,
1341
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1342
+					$new_ticket = clone $existing_ticket;
1343
+					$new_ticket->set('TKT_ID', 0);
1344
+					$new_ticket->set('TKT_deleted', 0);
1345
+					$new_ticket->set('TKT_sold', 0);
1346
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1347
+					$update_prices = true;
1348
+					$ticket        = $new_ticket;
1349
+				}
1350
+			} else {
1351
+				// no TKT_id so a new ticket
1352
+				$ticket_values['TKT_price'] = $ticket_price;
1353
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1354
+				$update_prices              = true;
1355
+			}
1356
+			if (! $ticket instanceof EE_Ticket) {
1357
+				throw new RuntimeException(
1358
+					sprintf(
1359
+						esc_html__(
1360
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1361
+							'event_espresso'
1362
+						),
1363
+						print_r($ticket_values, true)
1364
+					)
1365
+				);
1366
+			}
1367
+			// cap ticket qty by datetime reg limits
1368
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1369
+			// update ticket.
1370
+			$ticket->save();
1371
+			// before going any further make sure our dates are setup correctly
1372
+			// so that the end date is always equal or greater than the start date.
1373
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1374
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1375
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1376
+				$ticket->save();
1377
+			}
1378
+			// initially let's add the ticket to the datetime
1379
+			$datetime->_add_relation_to($ticket, 'Ticket');
1380
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1381
+			// add prices to ticket
1382
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1383
+				? $data['edit_prices'][ $row ]
1384
+				: [];
1385
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1386
+		}
1387
+		// however now we need to handle permanently deleting tickets via the ui.
1388
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1389
+		// However, it does allow for deleting tickets that have no tickets sold,
1390
+		// in which case we want to get rid of permanently because there is no need to save in db.
1391
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? [] : $old_tickets;
1392
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1393
+		foreach ($tickets_removed as $id) {
1394
+			$id = absint($id);
1395
+			// get the ticket for this id
1396
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1397
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1398
+				continue;
1399
+			}
1400
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1401
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1402
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1403
+			foreach ($related_datetimes as $related_datetime) {
1404
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1405
+			}
1406
+			// need to do the same for prices (except these prices can also be deleted because again,
1407
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1408
+			$ticket_to_remove->delete_related_permanently('Price');
1409
+			// finally let's delete this ticket
1410
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1411
+			$ticket_to_remove->delete_permanently();
1412
+		}
1413
+		return [$datetime, $saved_tickets];
1414
+	}
1415
+
1416
+
1417
+	/**
1418
+	 * This attaches a list of given prices to a ticket.
1419
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1420
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1421
+	 * price info and prices are automatically "archived" via the ticket.
1422
+	 *
1423
+	 * @access  private
1424
+	 * @param array     $prices_data Array of prices from the form.
1425
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1426
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1427
+	 * @return  void
1428
+	 * @throws EE_Error
1429
+	 * @throws ReflectionException
1430
+	 */
1431
+	private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1432
+	{
1433
+		$timezone = $ticket->get_timezone();
1434
+		foreach ($prices_data as $row => $price_data) {
1435
+			$price_values = [
1436
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1437
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1438
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1439
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1440
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1441
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1442
+				'PRC_order'      => $row,
1443
+			];
1444
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1445
+				$price_values['PRC_ID'] = 0;
1446
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1447
+			} else {
1448
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1449
+				// update this price with new values
1450
+				foreach ($price_values as $field => $new_price) {
1451
+					$price->set($field, $new_price);
1452
+				}
1453
+			}
1454
+			if (! $price instanceof EE_Price) {
1455
+				throw new RuntimeException(
1456
+					sprintf(
1457
+						esc_html__(
1458
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1459
+							'event_espresso'
1460
+						),
1461
+						print_r($price_values, true)
1462
+					)
1463
+				);
1464
+			}
1465
+			$price->save();
1466
+			$ticket->_add_relation_to($price, 'Price');
1467
+		}
1468
+	}
1469
+
1470
+
1471
+	/**
1472
+	 * Add in our autosave ajax handlers
1473
+	 *
1474
+	 */
1475
+	protected function _ee_autosave_create_new()
1476
+	{
1477
+	}
1478
+
1479
+
1480
+	/**
1481
+	 * More autosave handlers.
1482
+	 */
1483
+	protected function _ee_autosave_edit()
1484
+	{
1485
+		// TEMPORARILY EXITING CAUSE THIS IS A TODO
1486
+	}
1487
+
1488
+
1489
+	/**
1490
+	 * @throws EE_Error
1491
+	 * @throws ReflectionException
1492
+	 */
1493
+	private function _generate_publish_box_extra_content()
1494
+	{
1495
+		// load formatter helper
1496
+		// args for getting related registrations
1497
+		$approved_query_args        = [
1498
+			[
1499
+				'REG_deleted' => 0,
1500
+				'STS_ID'      => EEM_Registration::status_id_approved,
1501
+			],
1502
+		];
1503
+		$not_approved_query_args    = [
1504
+			[
1505
+				'REG_deleted' => 0,
1506
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1507
+			],
1508
+		];
1509
+		$pending_payment_query_args = [
1510
+			[
1511
+				'REG_deleted' => 0,
1512
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1513
+			],
1514
+		];
1515
+		// publish box
1516
+		$publish_box_extra_args = [
1517
+			'view_approved_reg_url'        => add_query_arg(
1518
+				[
1519
+					'action'      => 'default',
1520
+					'event_id'    => $this->_cpt_model_obj->ID(),
1521
+					'_reg_status' => EEM_Registration::status_id_approved,
1522
+					'use_filters' => true,
1523
+				],
1524
+				REG_ADMIN_URL
1525
+			),
1526
+			'view_not_approved_reg_url'    => add_query_arg(
1527
+				[
1528
+					'action'      => 'default',
1529
+					'event_id'    => $this->_cpt_model_obj->ID(),
1530
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1531
+					'use_filters' => true,
1532
+				],
1533
+				REG_ADMIN_URL
1534
+			),
1535
+			'view_pending_payment_reg_url' => add_query_arg(
1536
+				[
1537
+					'action'      => 'default',
1538
+					'event_id'    => $this->_cpt_model_obj->ID(),
1539
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1540
+					'use_filters' => true,
1541
+				],
1542
+				REG_ADMIN_URL
1543
+			),
1544
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1545
+				'Registration',
1546
+				$approved_query_args
1547
+			),
1548
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1549
+				'Registration',
1550
+				$not_approved_query_args
1551
+			),
1552
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1553
+				'Registration',
1554
+				$pending_payment_query_args
1555
+			),
1556
+			'misc_pub_section_class'       => apply_filters(
1557
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1558
+				'misc-pub-section'
1559
+			),
1560
+		];
1561
+		ob_start();
1562
+		do_action(
1563
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1564
+			$this->_cpt_model_obj
1565
+		);
1566
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1567
+		// load template
1568
+		EEH_Template::display_template(
1569
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1570
+			$publish_box_extra_args
1571
+		);
1572
+	}
1573
+
1574
+
1575
+	/**
1576
+	 * @return EE_Event
1577
+	 */
1578
+	public function get_event_object()
1579
+	{
1580
+		return $this->_cpt_model_obj;
1581
+	}
1582
+
1583
+
1584
+
1585
+
1586
+	/** METABOXES * */
1587
+	/**
1588
+	 * _register_event_editor_meta_boxes
1589
+	 * add all metaboxes related to the event_editor
1590
+	 *
1591
+	 * @return void
1592
+	 * @throws EE_Error
1593
+	 * @throws ReflectionException
1594
+	 */
1595
+	protected function _register_event_editor_meta_boxes()
1596
+	{
1597
+		$this->verify_cpt_object();
1598
+		add_meta_box(
1599
+			'espresso_event_editor_tickets',
1600
+			esc_html__('Event Datetime & Ticket', 'event_espresso'),
1601
+			[$this, 'ticket_metabox'],
1602
+			$this->page_slug,
1603
+			'normal',
1604
+			'high'
1605
+		);
1606
+		add_meta_box(
1607
+			'espresso_event_editor_event_options',
1608
+			esc_html__('Event Registration Options', 'event_espresso'),
1609
+			[$this, 'registration_options_meta_box'],
1610
+			$this->page_slug,
1611
+			'side'
1612
+		);
1613
+		// NOTE: if you're looking for other metaboxes in here,
1614
+		// where a metabox has a related management page in the admin
1615
+		// you will find it setup in the related management page's "_Hooks" file.
1616
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1617
+	}
1618
+
1619
+
1620
+	/**
1621
+	 * @throws DomainException
1622
+	 * @throws EE_Error
1623
+	 * @throws ReflectionException
1624
+	 */
1625
+	public function ticket_metabox()
1626
+	{
1627
+		$existing_datetime_ids = $existing_ticket_ids = [];
1628
+		// defaults for template args
1629
+		$template_args = [
1630
+			'ticket_rows'              => '',
1631
+			'total_ticket_rows'        => 1,
1632
+			'trash_icon'               => 'ee-lock-icon',
1633
+			'disabled'                 => '',
1634
+		];
1635
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1636
+		/**
1637
+		 * 1. Start with retrieving Datetimes
1638
+		 * 2. Fore each datetime get related tickets
1639
+		 * 3. For each ticket get related prices
1640
+		 */
1641
+		$times          = EEM_Datetime::instance()->get_all_event_dates($event_id);
1642
+		$first_datetime = reset($times);
1643
+		// do we get related tickets?
1644
+		if (
1645
+			$first_datetime instanceof EE_Datetime
1646
+			&& $first_datetime->ID() !== 0
1647
+		) {
1648
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1649
+			$template_args['time']   = $first_datetime;
1650
+			$related_tickets         = $first_datetime->tickets(
1651
+				[
1652
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1653
+					'default_where_conditions' => 'none',
1654
+				]
1655
+			);
1656
+			if (! empty($related_tickets)) {
1657
+				$template_args['total_ticket_rows'] = count($related_tickets);
1658
+				$row                                = 0;
1659
+				foreach ($related_tickets as $ticket) {
1660
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1661
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1662
+					$row++;
1663
+				}
1664
+			} else {
1665
+				$template_args['total_ticket_rows'] = 1;
1666
+				$ticket                       = EEM_Ticket::instance()->create_default_object();
1667
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1668
+			}
1669
+		} else {
1670
+			$template_args['time']        = $times[0];
1671
+			$tickets                      = EEM_Ticket::instance()->get_all_default_tickets();
1672
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1673
+			// NOTE: we're just sending the first default row
1674
+			// (decaf can't manage default tickets so this should be sufficient);
1675
+		}
1676
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1677
+			'event_editor_event_datetimes_help_tab'
1678
+		);
1679
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1680
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1681
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1682
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1683
+			EEM_Ticket::instance()->create_default_object(),
1684
+			true
1685
+		);
1686
+		$template                                  = apply_filters(
1687
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1688
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1689
+		);
1690
+		EEH_Template::display_template($template, $template_args);
1691
+	}
1692
+
1693
+
1694
+	/**
1695
+	 * Setup an individual ticket form for the decaf event editor page
1696
+	 *
1697
+	 * @access private
1698
+	 * @param EE_Ticket $ticket   the ticket object
1699
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1700
+	 * @param int       $row
1701
+	 * @return string generated html for the ticket row.
1702
+	 * @throws EE_Error
1703
+	 * @throws ReflectionException
1704
+	 */
1705
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1706
+	{
1707
+		$template_args = [
1708
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1709
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1710
+				: '',
1711
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1712
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1713
+			'TKT_name'            => $ticket->get('TKT_name'),
1714
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1715
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1716
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1717
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1718
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1719
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1720
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1721
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1722
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1723
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1724
+				: ' disabled=disabled',
1725
+		];
1726
+		$price         = $ticket->ID() !== 0
1727
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1728
+			: null;
1729
+		$price         = $price instanceof EE_Price
1730
+			? $price
1731
+			: EEM_Price::instance()->create_default_object();
1732
+		$price_args    = [
1733
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1734
+			'PRC_amount'            => $price->get('PRC_amount'),
1735
+			'PRT_ID'                => $price->get('PRT_ID'),
1736
+			'PRC_ID'                => $price->get('PRC_ID'),
1737
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1738
+		];
1739
+		// make sure we have default start and end dates if skeleton
1740
+		// handle rows that should NOT be empty
1741
+		if (empty($template_args['TKT_start_date'])) {
1742
+			// if empty then the start date will be now.
1743
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1744
+		}
1745
+		if (empty($template_args['TKT_end_date'])) {
1746
+			// get the earliest datetime (if present);
1747
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1748
+				? $this->_cpt_model_obj->get_first_related(
1749
+					'Datetime',
1750
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1751
+				)
1752
+				: null;
1753
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1754
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1755
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1756
+		}
1757
+		$template_args = array_merge($template_args, $price_args);
1758
+		$template      = apply_filters(
1759
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1760
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1761
+			$ticket
1762
+		);
1763
+		return EEH_Template::display_template($template, $template_args, true);
1764
+	}
1765
+
1766
+
1767
+	/**
1768
+	 * @throws EE_Error
1769
+	 * @throws ReflectionException
1770
+	 */
1771
+	public function registration_options_meta_box()
1772
+	{
1773
+		$yes_no_values             = [
1774
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1775
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1776
+		];
1777
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1778
+			[
1779
+				EEM_Registration::status_id_cancelled,
1780
+				EEM_Registration::status_id_declined,
1781
+				EEM_Registration::status_id_incomplete,
1782
+			],
1783
+			true
1784
+		);
1785
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1786
+		$template_args['_event']                          = $this->_cpt_model_obj;
1787
+		$template_args['event']                           = $this->_cpt_model_obj;
1788
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1789
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1790
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1791
+			'default_reg_status',
1792
+			$default_reg_status_values,
1793
+			$this->_cpt_model_obj->default_registration_status()
1794
+		);
1795
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1796
+			'display_desc',
1797
+			$yes_no_values,
1798
+			$this->_cpt_model_obj->display_description()
1799
+		);
1800
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1801
+			'display_ticket_selector',
1802
+			$yes_no_values,
1803
+			$this->_cpt_model_obj->display_ticket_selector(),
1804
+			'',
1805
+			'',
1806
+			false
1807
+		);
1808
+		$template_args['additional_registration_options'] = apply_filters(
1809
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1810
+			'',
1811
+			$template_args,
1812
+			$yes_no_values,
1813
+			$default_reg_status_values
1814
+		);
1815
+		EEH_Template::display_template(
1816
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1817
+			$template_args
1818
+		);
1819
+	}
1820
+
1821
+
1822
+	/**
1823
+	 * _get_events()
1824
+	 * This method simply returns all the events (for the given _view and paging)
1825
+	 *
1826
+	 * @access public
1827
+	 * @param int  $per_page     count of items per page (20 default);
1828
+	 * @param int  $current_page what is the current page being viewed.
1829
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1830
+	 *                           If FALSE then we return an array of event objects
1831
+	 *                           that match the given _view and paging parameters.
1832
+	 * @return array|int         an array of event objects or a count of them.
1833
+	 * @throws Exception
1834
+	 */
1835
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1836
+	{
1837
+		$EEM_Event   = $this->_event_model();
1838
+		$offset      = ($current_page - 1) * $per_page;
1839
+		$limit       = $count ? null : $offset . ',' . $per_page;
1840
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1841
+		$order       = $this->request->getRequestParam('order', 'DESC');
1842
+		$month_range = $this->request->getRequestParam('month_range');
1843
+		if ($month_range) {
1844
+			$pieces = explode(' ', $month_range, 3);
1845
+			// simulate the FIRST day of the month, that fixes issues for months like February
1846
+			// where PHP doesn't know what to assume for date.
1847
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1848
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1849
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1850
+		}
1851
+		$where  = [];
1852
+		$status = $this->request->getRequestParam('status');
1853
+		// determine what post_status our condition will have for the query.
1854
+		switch ($status) {
1855
+			case 'month':
1856
+			case 'today':
1857
+			case null:
1858
+			case 'all':
1859
+				break;
1860
+			case 'draft':
1861
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1862
+				break;
1863
+			default:
1864
+				$where['status'] = $status;
1865
+		}
1866
+		// categories? The default for all categories is -1
1867
+		$category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1868
+		if ($category !== -1) {
1869
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1870
+			$where['Term_Taxonomy.term_id']  = $category;
1871
+		}
1872
+		// date where conditions
1873
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874
+		if ($month_range) {
1875
+			$DateTime = new DateTime(
1876
+				$year_r . '-' . $month_r . '-01 00:00:00',
1877
+				new DateTimeZone('UTC')
1878
+			);
1879
+			$start    = $DateTime->getTimestamp();
1880
+			// set the datetime to be the end of the month
1881
+			$DateTime->setDate(
1882
+				$year_r,
1883
+				$month_r,
1884
+				$DateTime->format('t')
1885
+			)->setTime(23, 59, 59);
1886
+			$end                             = $DateTime->getTimestamp();
1887
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1888
+		} elseif ($status === 'today') {
1889
+			$DateTime                        =
1890
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1891
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1892
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1893
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1894
+		} elseif ($status === 'month') {
1895
+			$now                             = date('Y-m-01');
1896
+			$DateTime                        =
1897
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1898
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1899
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1900
+														->setTime(23, 59, 59)
1901
+														->format(implode(' ', $start_formats));
1902
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1903
+		}
1904
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1905
+			$where['EVT_wp_user'] = get_current_user_id();
1906
+		} else {
1907
+			if (! isset($where['status'])) {
1908
+				if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1909
+					$where['OR'] = [
1910
+						'status*restrict_private' => ['!=', 'private'],
1911
+						'AND'                     => [
1912
+							'status*inclusive' => ['=', 'private'],
1913
+							'EVT_wp_user'      => get_current_user_id(),
1914
+						],
1915
+					];
1916
+				}
1917
+			}
1918
+		}
1919
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1920
+		if (
1921
+			$wp_user
1922
+			&& $wp_user !== get_current_user_id()
1923
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1924
+		) {
1925
+			$where['EVT_wp_user'] = $wp_user;
1926
+		}
1927
+		// search query handling
1928
+		$search_term = $this->request->getRequestParam('s');
1929
+		if ($search_term) {
1930
+			$search_term = '%' . $search_term . '%';
1931
+			$where['OR'] = [
1932
+				'EVT_name'       => ['LIKE', $search_term],
1933
+				'EVT_desc'       => ['LIKE', $search_term],
1934
+				'EVT_short_desc' => ['LIKE', $search_term],
1935
+			];
1936
+		}
1937
+		// filter events by venue.
1938
+		$venue = $this->request->getRequestParam('venue', 0, 'int');
1939
+		if ($venue) {
1940
+			$where['Venue.VNU_ID'] = $venue;
1941
+		}
1942
+		$request_params = $this->request->requestParams();
1943
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
1944
+		$query_params   = apply_filters(
1945
+			'FHEE__Events_Admin_Page__get_events__query_params',
1946
+			[
1947
+				$where,
1948
+				'limit'    => $limit,
1949
+				'order_by' => $orderby,
1950
+				'order'    => $order,
1951
+				'group_by' => 'EVT_ID',
1952
+			],
1953
+			$request_params
1954
+		);
1955
+
1956
+		// let's first check if we have special requests coming in.
1957
+		$active_status = $this->request->getRequestParam('active_status');
1958
+		if ($active_status) {
1959
+			switch ($active_status) {
1960
+				case 'upcoming':
1961
+					return $EEM_Event->get_upcoming_events($query_params, $count);
1962
+				case 'expired':
1963
+					return $EEM_Event->get_expired_events($query_params, $count);
1964
+				case 'active':
1965
+					return $EEM_Event->get_active_events($query_params, $count);
1966
+				case 'inactive':
1967
+					return $EEM_Event->get_inactive_events($query_params, $count);
1968
+			}
1969
+		}
1970
+
1971
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
1972
+	}
1973
+
1974
+
1975
+	/**
1976
+	 * handling for WordPress CPT actions (trash, restore, delete)
1977
+	 *
1978
+	 * @param string $post_id
1979
+	 * @throws EE_Error
1980
+	 * @throws ReflectionException
1981
+	 */
1982
+	public function trash_cpt_item($post_id)
1983
+	{
1984
+		$this->request->setRequestParam('EVT_ID', $post_id);
1985
+		$this->_trash_or_restore_event('trash', false);
1986
+	}
1987
+
1988
+
1989
+	/**
1990
+	 * @param string $post_id
1991
+	 * @throws EE_Error
1992
+	 * @throws ReflectionException
1993
+	 */
1994
+	public function restore_cpt_item($post_id)
1995
+	{
1996
+		$this->request->setRequestParam('EVT_ID', $post_id);
1997
+		$this->_trash_or_restore_event('draft', false);
1998
+	}
1999
+
2000
+
2001
+	/**
2002
+	 * @param string $post_id
2003
+	 * @throws EE_Error
2004
+	 * @throws EE_Error
2005
+	 */
2006
+	public function delete_cpt_item($post_id)
2007
+	{
2008
+		throw new EE_Error(
2009
+			esc_html__(
2010
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2011
+				'event_espresso'
2012
+			)
2013
+		);
2014
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2015
+		// $this->_delete_event();
2016
+	}
2017
+
2018
+
2019
+	/**
2020
+	 * _trash_or_restore_event
2021
+	 *
2022
+	 * @access protected
2023
+	 * @param string $event_status
2024
+	 * @param bool   $redirect_after
2025
+	 * @throws EE_Error
2026
+	 * @throws EE_Error
2027
+	 * @throws ReflectionException
2028
+	 */
2029
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2030
+	{
2031
+		// determine the event id and set to array.
2032
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2033
+		// loop thru events
2034
+		if ($EVT_ID) {
2035
+			// clean status
2036
+			$event_status = sanitize_key($event_status);
2037
+			// grab status
2038
+			if (! empty($event_status)) {
2039
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2040
+			} else {
2041
+				$success = false;
2042
+				$msg     = esc_html__(
2043
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2044
+					'event_espresso'
2045
+				);
2046
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2047
+			}
2048
+		} else {
2049
+			$success = false;
2050
+			$msg     = esc_html__(
2051
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2052
+				'event_espresso'
2053
+			);
2054
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2055
+		}
2056
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2057
+		if ($redirect_after) {
2058
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2059
+		}
2060
+	}
2061
+
2062
+
2063
+	/**
2064
+	 * _trash_or_restore_events
2065
+	 *
2066
+	 * @access protected
2067
+	 * @param string $event_status
2068
+	 * @return void
2069
+	 * @throws EE_Error
2070
+	 * @throws EE_Error
2071
+	 * @throws ReflectionException
2072
+	 */
2073
+	protected function _trash_or_restore_events($event_status = 'trash')
2074
+	{
2075
+		// clean status
2076
+		$event_status = sanitize_key($event_status);
2077
+		// grab status
2078
+		if (! empty($event_status)) {
2079
+			$success = true;
2080
+			// determine the event id and set to array.
2081
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2082
+			// loop thru events
2083
+			foreach ($EVT_IDs as $EVT_ID) {
2084
+				if ($EVT_ID = absint($EVT_ID)) {
2085
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2086
+					$success = $results !== false ? $success : false;
2087
+				} else {
2088
+					$msg = sprintf(
2089
+						esc_html__(
2090
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2091
+							'event_espresso'
2092
+						),
2093
+						$EVT_ID
2094
+					);
2095
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2096
+					$success = false;
2097
+				}
2098
+			}
2099
+		} else {
2100
+			$success = false;
2101
+			$msg     = esc_html__(
2102
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2103
+				'event_espresso'
2104
+			);
2105
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2106
+		}
2107
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2108
+		$success = $success ? 2 : false;
2109
+		$action  = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2110
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2111
+	}
2112
+
2113
+
2114
+	/**
2115
+	 * @param int    $EVT_ID
2116
+	 * @param string $event_status
2117
+	 * @return bool
2118
+	 * @throws EE_Error
2119
+	 * @throws ReflectionException
2120
+	 */
2121
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2122
+	{
2123
+		// grab event id
2124
+		if (! $EVT_ID) {
2125
+			$msg = esc_html__(
2126
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2127
+				'event_espresso'
2128
+			);
2129
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2130
+			return false;
2131
+		}
2132
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2133
+		// clean status
2134
+		$event_status = sanitize_key($event_status);
2135
+		// grab status
2136
+		if (empty($event_status)) {
2137
+			$msg = esc_html__(
2138
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2139
+				'event_espresso'
2140
+			);
2141
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2142
+			return false;
2143
+		}
2144
+		// was event trashed or restored ?
2145
+		switch ($event_status) {
2146
+			case 'draft':
2147
+				$action = 'restored from the trash';
2148
+				$hook   = 'AHEE_event_restored_from_trash';
2149
+				break;
2150
+			case 'trash':
2151
+				$action = 'moved to the trash';
2152
+				$hook   = 'AHEE_event_moved_to_trash';
2153
+				break;
2154
+			default:
2155
+				$action = 'updated';
2156
+				$hook   = false;
2157
+		}
2158
+		// use class to change status
2159
+		$this->_cpt_model_obj->set_status($event_status);
2160
+		$success = $this->_cpt_model_obj->save();
2161
+		if (! $success) {
2162
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2163
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2164
+			return false;
2165
+		}
2166
+		if ($hook) {
2167
+			do_action($hook);
2168
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2169
+			// because events side step that and it otherwise won't get called
2170
+			do_action(
2171
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2172
+				$this->_cpt_model_obj,
2173
+				$hook === 'AHEE_event_moved_to_trash',
2174
+				$success
2175
+			);
2176
+		}
2177
+		return true;
2178
+	}
2179
+
2180
+
2181
+	/**
2182
+	 * @param array $event_ids
2183
+	 * @return array
2184
+	 * @since   4.10.23.p
2185
+	 */
2186
+	private function cleanEventIds(array $event_ids)
2187
+	{
2188
+		return array_map('absint', $event_ids);
2189
+	}
2190
+
2191
+
2192
+	/**
2193
+	 * @return array
2194
+	 * @since   4.10.23.p
2195
+	 */
2196
+	private function getEventIdsFromRequest()
2197
+	{
2198
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2199
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2200
+		} else {
2201
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2202
+		}
2203
+	}
2204
+
2205
+
2206
+	/**
2207
+	 * @param bool $preview_delete
2208
+	 * @throws EE_Error
2209
+	 * @throws ReflectionException
2210
+	 */
2211
+	protected function _delete_event($preview_delete = true)
2212
+	{
2213
+		$this->_delete_events($preview_delete);
2214
+	}
2215
+
2216
+
2217
+	/**
2218
+	 * Gets the tree traversal batch persister.
2219
+	 *
2220
+	 * @return NodeGroupDao
2221
+	 * @throws InvalidArgumentException
2222
+	 * @throws InvalidDataTypeException
2223
+	 * @throws InvalidInterfaceException
2224
+	 * @since 4.10.12.p
2225
+	 */
2226
+	protected function getModelObjNodeGroupPersister()
2227
+	{
2228
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2229
+			$this->model_obj_node_group_persister =
2230
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2231
+		}
2232
+		return $this->model_obj_node_group_persister;
2233
+	}
2234
+
2235
+
2236
+	/**
2237
+	 * @param bool $preview_delete
2238
+	 * @return void
2239
+	 * @throws EE_Error
2240
+	 * @throws ReflectionException
2241
+	 */
2242
+	protected function _delete_events($preview_delete = true)
2243
+	{
2244
+		$event_ids = $this->getEventIdsFromRequest();
2245
+		if ($preview_delete) {
2246
+			$this->generateDeletionPreview($event_ids);
2247
+		} else {
2248
+			foreach ($event_ids as $event_id) {
2249
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2250
+				if ($event instanceof EE_Event) {
2251
+					$event->delete_permanently();
2252
+				}
2253
+			}
2254
+		}
2255
+	}
2256
+
2257
+
2258
+	/**
2259
+	 * @param array $event_ids
2260
+	 */
2261
+	protected function generateDeletionPreview(array $event_ids)
2262
+	{
2263
+		$event_ids = $this->cleanEventIds($event_ids);
2264
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2265
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2266
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2267
+			[
2268
+				'action'            => 'preview_deletion',
2269
+				'deletion_job_code' => $deletion_job_code,
2270
+			],
2271
+			$this->_admin_base_url
2272
+		);
2273
+		EEH_URL::safeRedirectAndExit(
2274
+			EE_Admin_Page::add_query_args_and_nonce(
2275
+				[
2276
+					'page'              => 'espresso_batch',
2277
+					'batch'             => EED_Batch::batch_job,
2278
+					'EVT_IDs'           => $event_ids,
2279
+					'deletion_job_code' => $deletion_job_code,
2280
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2281
+					'return_url'        => urlencode($return_url),
2282
+				],
2283
+				admin_url()
2284
+			)
2285
+		);
2286
+	}
2287
+
2288
+
2289
+	/**
2290
+	 * Checks for a POST submission
2291
+	 *
2292
+	 * @since 4.10.12.p
2293
+	 */
2294
+	protected function confirmDeletion()
2295
+	{
2296
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2297
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2298
+		);
2299
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2300
+	}
2301
+
2302
+
2303
+	/**
2304
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2305
+	 *
2306
+	 * @throws EE_Error
2307
+	 * @since 4.10.12.p
2308
+	 */
2309
+	protected function previewDeletion()
2310
+	{
2311
+		$preview_deletion_logic = $this->getLoader()->getShared(
2312
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2313
+		);
2314
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2315
+		$this->display_admin_page_with_no_sidebar();
2316
+	}
2317
+
2318
+
2319
+	/**
2320
+	 * get total number of events
2321
+	 *
2322
+	 * @access public
2323
+	 * @return int
2324
+	 * @throws EE_Error
2325
+	 * @throws EE_Error
2326
+	 */
2327
+	public function total_events()
2328
+	{
2329
+		return EEM_Event::instance()->count(
2330
+			['caps' => 'read_admin'],
2331
+			'EVT_ID',
2332
+			true
2333
+		);
2334
+	}
2335
+
2336
+
2337
+	/**
2338
+	 * get total number of draft events
2339
+	 *
2340
+	 * @access public
2341
+	 * @return int
2342
+	 * @throws EE_Error
2343
+	 * @throws EE_Error
2344
+	 */
2345
+	public function total_events_draft()
2346
+	{
2347
+		return EEM_Event::instance()->count(
2348
+			[
2349
+				['status' => ['IN', ['draft', 'auto-draft']]],
2350
+				'caps' => 'read_admin',
2351
+			],
2352
+			'EVT_ID',
2353
+			true
2354
+		);
2355
+	}
2356
+
2357
+
2358
+	/**
2359
+	 * get total number of trashed events
2360
+	 *
2361
+	 * @access public
2362
+	 * @return int
2363
+	 * @throws EE_Error
2364
+	 * @throws EE_Error
2365
+	 */
2366
+	public function total_trashed_events()
2367
+	{
2368
+		return EEM_Event::instance()->count(
2369
+			[
2370
+				['status' => 'trash'],
2371
+				'caps' => 'read_admin',
2372
+			],
2373
+			'EVT_ID',
2374
+			true
2375
+		);
2376
+	}
2377
+
2378
+
2379
+	/**
2380
+	 *    _default_event_settings
2381
+	 *    This generates the Default Settings Tab
2382
+	 *
2383
+	 * @return void
2384
+	 * @throws EE_Error
2385
+	 */
2386
+	protected function _default_event_settings()
2387
+	{
2388
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2389
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2390
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2391
+		$this->display_admin_page_with_sidebar();
2392
+	}
2393
+
2394
+
2395
+	/**
2396
+	 * Return the form for event settings.
2397
+	 *
2398
+	 * @return EE_Form_Section_Proper
2399
+	 * @throws EE_Error
2400
+	 */
2401
+	protected function _default_event_settings_form()
2402
+	{
2403
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2404
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2405
+		// exclude
2406
+			[
2407
+				EEM_Registration::status_id_cancelled,
2408
+				EEM_Registration::status_id_declined,
2409
+				EEM_Registration::status_id_incomplete,
2410
+				EEM_Registration::status_id_wait_list,
2411
+			],
2412
+			true
2413
+		);
2414
+		return new EE_Form_Section_Proper(
2415
+			[
2416
+				'name'            => 'update_default_event_settings',
2417
+				'html_id'         => 'update_default_event_settings',
2418
+				'html_class'      => 'form-table',
2419
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2420
+				'subsections'     => apply_filters(
2421
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2422
+					[
2423
+						'default_reg_status'  => new EE_Select_Input(
2424
+							$registration_stati_for_selection,
2425
+							[
2426
+								'default'         => isset($registration_config->default_STS_ID)
2427
+													 && array_key_exists(
2428
+														 $registration_config->default_STS_ID,
2429
+														 $registration_stati_for_selection
2430
+													 )
2431
+									? sanitize_text_field($registration_config->default_STS_ID)
2432
+									: EEM_Registration::status_id_pending_payment,
2433
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2434
+													 . EEH_Template::get_help_tab_link(
2435
+														 'default_settings_status_help_tab'
2436
+													 ),
2437
+								'html_help_text'  => esc_html__(
2438
+									'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.',
2439
+									'event_espresso'
2440
+								),
2441
+							]
2442
+						),
2443
+						'default_max_tickets' => new EE_Integer_Input(
2444
+							[
2445
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2446
+									? $registration_config->default_maximum_number_of_tickets
2447
+									: EEM_Event::get_default_additional_limit(),
2448
+								'html_label_text' => esc_html__(
2449
+									'Default Maximum Tickets Allowed Per Order:',
2450
+									'event_espresso'
2451
+								)
2452
+								. EEH_Template::get_help_tab_link(
2453
+									'default_maximum_tickets_help_tab"'
2454
+								),
2455
+								'html_help_text'  => esc_html__(
2456
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2457
+									'event_espresso'
2458
+								),
2459
+							]
2460
+						),
2461
+					]
2462
+				),
2463
+			]
2464
+		);
2465
+	}
2466
+
2467
+
2468
+	/**
2469
+	 * _update_default_event_settings
2470
+	 *
2471
+	 * @access protected
2472
+	 * @return void
2473
+	 * @throws EE_Error
2474
+	 */
2475
+	protected function _update_default_event_settings()
2476
+	{
2477
+		$registration_config = EE_Registry::instance()->CFG->registration;
2478
+		$form                = $this->_default_event_settings_form();
2479
+		if ($form->was_submitted()) {
2480
+			$form->receive_form_submission();
2481
+			if ($form->is_valid()) {
2482
+				$valid_data = $form->valid_data();
2483
+				if (isset($valid_data['default_reg_status'])) {
2484
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2485
+				}
2486
+				if (isset($valid_data['default_max_tickets'])) {
2487
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2488
+				}
2489
+				// update because data was valid!
2490
+				EE_Registry::instance()->CFG->update_espresso_config();
2491
+				EE_Error::overwrite_success();
2492
+				EE_Error::add_success(
2493
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2494
+				);
2495
+			}
2496
+		}
2497
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2498
+	}
2499
+
2500
+
2501
+	/*************        Templates        *************
20 2502
      *
21
-     * @var EE_Event $_event
22
-     */
23
-    protected $_event;
24
-
25
-
26
-    /**
27
-     * This will hold the category object for category_details screen.
28
-     *
29
-     * @var stdClass $_category
30
-     */
31
-    protected $_category;
32
-
33
-
34
-    /**
35
-     * This will hold the event model instance
36
-     *
37
-     * @var EEM_Event $_event_model
38
-     */
39
-    protected $_event_model;
40
-
41
-
42
-    /**
43
-     * @var EE_Event
44
-     */
45
-    protected $_cpt_model_obj = false;
46
-
47
-
48
-    /**
49
-     * @var NodeGroupDao
50
-     */
51
-    protected $model_obj_node_group_persister;
52
-
53
-
54
-    /**
55
-     * Initialize page props for this admin page group.
56
-     */
57
-    protected function _init_page_props()
58
-    {
59
-        $this->page_slug        = EVENTS_PG_SLUG;
60
-        $this->page_label       = EVENTS_LABEL;
61
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
62
-        $this->_admin_base_path = EVENTS_ADMIN;
63
-        $this->_cpt_model_names = [
64
-            'create_new' => 'EEM_Event',
65
-            'edit'       => 'EEM_Event',
66
-        ];
67
-        $this->_cpt_edit_routes = [
68
-            'espresso_events' => 'edit',
69
-        ];
70
-        add_action(
71
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
72
-            [$this, 'verify_event_edit'],
73
-            10,
74
-            2
75
-        );
76
-    }
77
-
78
-
79
-    /**
80
-     * Sets the ajax hooks used for this admin page group.
81
-     */
82
-    protected function _ajax_hooks()
83
-    {
84
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
85
-    }
86
-
87
-
88
-    /**
89
-     * Sets the page properties for this admin page group.
90
-     */
91
-    protected function _define_page_props()
92
-    {
93
-        $this->_admin_page_title = EVENTS_LABEL;
94
-        $this->_labels           = [
95
-            'buttons'      => [
96
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
97
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
98
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
99
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
100
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
101
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
102
-            ],
103
-            'editor_title' => [
104
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
105
-            ],
106
-            'publishbox'   => [
107
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
108
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
109
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
110
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
111
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
112
-            ],
113
-        ];
114
-    }
115
-
116
-
117
-    /**
118
-     * Sets the page routes property for this admin page group.
119
-     */
120
-    protected function _set_page_routes()
121
-    {
122
-        // load formatter helper
123
-        // load field generator helper
124
-        // is there a evt_id in the request?
125
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
126
-        $EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
127
-
128
-        $this->_page_routes = [
129
-            'default'                       => [
130
-                'func'       => [$this, '_events_overview_list_table'],
131
-                'capability' => 'ee_read_events',
132
-            ],
133
-            'create_new'                    => [
134
-                'func'       => [$this, '_create_new_cpt_item'],
135
-                'capability' => 'ee_edit_events',
136
-            ],
137
-            'edit'                          => [
138
-                'func'       => [$this, '_edit_cpt_item'],
139
-                'capability' => 'ee_edit_event',
140
-                'obj_id'     => $EVT_ID,
141
-            ],
142
-            'copy_event'                    => [
143
-                'func'       => [$this, '_copy_events'],
144
-                'capability' => 'ee_edit_event',
145
-                'obj_id'     => $EVT_ID,
146
-                'noheader'   => true,
147
-            ],
148
-            'trash_event'                   => [
149
-                'func'       => [$this, '_trash_or_restore_event'],
150
-                'args'       => ['event_status' => 'trash'],
151
-                'capability' => 'ee_delete_event',
152
-                'obj_id'     => $EVT_ID,
153
-                'noheader'   => true,
154
-            ],
155
-            'trash_events'                  => [
156
-                'func'       => [$this, '_trash_or_restore_events'],
157
-                'args'       => ['event_status' => 'trash'],
158
-                'capability' => 'ee_delete_events',
159
-                'noheader'   => true,
160
-            ],
161
-            'restore_event'                 => [
162
-                'func'       => [$this, '_trash_or_restore_event'],
163
-                'args'       => ['event_status' => 'draft'],
164
-                'capability' => 'ee_delete_event',
165
-                'obj_id'     => $EVT_ID,
166
-                'noheader'   => true,
167
-            ],
168
-            'restore_events'                => [
169
-                'func'       => [$this, '_trash_or_restore_events'],
170
-                'args'       => ['event_status' => 'draft'],
171
-                'capability' => 'ee_delete_events',
172
-                'noheader'   => true,
173
-            ],
174
-            'delete_event'                  => [
175
-                'func'       => [$this, '_delete_event'],
176
-                'capability' => 'ee_delete_event',
177
-                'obj_id'     => $EVT_ID,
178
-                'noheader'   => true,
179
-            ],
180
-            'delete_events'                 => [
181
-                'func'       => [$this, '_delete_events'],
182
-                'capability' => 'ee_delete_events',
183
-                'noheader'   => true,
184
-            ],
185
-            'view_report'                   => [
186
-                'func'       => [$this, '_view_report'],
187
-                'capability' => 'ee_edit_events',
188
-            ],
189
-            'default_event_settings'        => [
190
-                'func'       => [$this, '_default_event_settings'],
191
-                'capability' => 'manage_options',
192
-            ],
193
-            'update_default_event_settings' => [
194
-                'func'       => [$this, '_update_default_event_settings'],
195
-                'capability' => 'manage_options',
196
-                'noheader'   => true,
197
-            ],
198
-            'template_settings'             => [
199
-                'func'       => [$this, '_template_settings'],
200
-                'capability' => 'manage_options',
201
-            ],
202
-            // event category tab related
203
-            'add_category'                  => [
204
-                'func'       => [$this, '_category_details'],
205
-                'capability' => 'ee_edit_event_category',
206
-                'args'       => ['add'],
207
-            ],
208
-            'edit_category'                 => [
209
-                'func'       => [$this, '_category_details'],
210
-                'capability' => 'ee_edit_event_category',
211
-                'args'       => ['edit'],
212
-            ],
213
-            'delete_categories'             => [
214
-                'func'       => [$this, '_delete_categories'],
215
-                'capability' => 'ee_delete_event_category',
216
-                'noheader'   => true,
217
-            ],
218
-            'delete_category'               => [
219
-                'func'       => [$this, '_delete_categories'],
220
-                'capability' => 'ee_delete_event_category',
221
-                'noheader'   => true,
222
-            ],
223
-            'insert_category'               => [
224
-                'func'       => [$this, '_insert_or_update_category'],
225
-                'args'       => ['new_category' => true],
226
-                'capability' => 'ee_edit_event_category',
227
-                'noheader'   => true,
228
-            ],
229
-            'update_category'               => [
230
-                'func'       => [$this, '_insert_or_update_category'],
231
-                'args'       => ['new_category' => false],
232
-                'capability' => 'ee_edit_event_category',
233
-                'noheader'   => true,
234
-            ],
235
-            'category_list'                 => [
236
-                'func'       => [$this, '_category_list_table'],
237
-                'capability' => 'ee_manage_event_categories',
238
-            ],
239
-            'preview_deletion'              => [
240
-                'func'       => [$this, 'previewDeletion'],
241
-                'capability' => 'ee_delete_events',
242
-            ],
243
-            'confirm_deletion'              => [
244
-                'func'       => [$this, 'confirmDeletion'],
245
-                'capability' => 'ee_delete_events',
246
-                'noheader'   => true,
247
-            ],
248
-        ];
249
-    }
250
-
251
-
252
-    /**
253
-     * Set the _page_config property for this admin page group.
254
-     */
255
-    protected function _set_page_config()
256
-    {
257
-        $post_id            = $this->request->getRequestParam('post', 0, 'int');
258
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
259
-        $this->_page_config = [
260
-            'default'                => [
261
-                'nav'           => [
262
-                    'label' => esc_html__('Overview', 'event_espresso'),
263
-                    'order' => 10,
264
-                ],
265
-                'list_table'    => 'Events_Admin_List_Table',
266
-                'help_tabs'     => [
267
-                    'events_overview_help_tab'                       => [
268
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
269
-                        'filename' => 'events_overview',
270
-                    ],
271
-                    'events_overview_table_column_headings_help_tab' => [
272
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
273
-                        'filename' => 'events_overview_table_column_headings',
274
-                    ],
275
-                    'events_overview_filters_help_tab'               => [
276
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
277
-                        'filename' => 'events_overview_filters',
278
-                    ],
279
-                    'events_overview_view_help_tab'                  => [
280
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
281
-                        'filename' => 'events_overview_views',
282
-                    ],
283
-                    'events_overview_other_help_tab'                 => [
284
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
285
-                        'filename' => 'events_overview_other',
286
-                    ],
287
-                ],
288
-                'qtips'         => [
289
-                    'EE_Event_List_Table_Tips',
290
-                ],
291
-                'require_nonce' => false,
292
-            ],
293
-            'create_new'             => [
294
-                'nav'           => [
295
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
296
-                    'order'      => 5,
297
-                    'persistent' => false,
298
-                ],
299
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
300
-                'help_tabs'     => [
301
-                    'event_editor_help_tab'                            => [
302
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
303
-                        'filename' => 'event_editor',
304
-                    ],
305
-                    'event_editor_title_richtexteditor_help_tab'       => [
306
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
307
-                        'filename' => 'event_editor_title_richtexteditor',
308
-                    ],
309
-                    'event_editor_venue_details_help_tab'              => [
310
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
311
-                        'filename' => 'event_editor_venue_details',
312
-                    ],
313
-                    'event_editor_event_datetimes_help_tab'            => [
314
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
315
-                        'filename' => 'event_editor_event_datetimes',
316
-                    ],
317
-                    'event_editor_event_tickets_help_tab'              => [
318
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
319
-                        'filename' => 'event_editor_event_tickets',
320
-                    ],
321
-                    'event_editor_event_registration_options_help_tab' => [
322
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
323
-                        'filename' => 'event_editor_event_registration_options',
324
-                    ],
325
-                    'event_editor_tags_categories_help_tab'            => [
326
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
327
-                        'filename' => 'event_editor_tags_categories',
328
-                    ],
329
-                    'event_editor_questions_registrants_help_tab'      => [
330
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
331
-                        'filename' => 'event_editor_questions_registrants',
332
-                    ],
333
-                    'event_editor_save_new_event_help_tab'             => [
334
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
335
-                        'filename' => 'event_editor_save_new_event',
336
-                    ],
337
-                    'event_editor_other_help_tab'                      => [
338
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
339
-                        'filename' => 'event_editor_other',
340
-                    ],
341
-                ],
342
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
343
-                'require_nonce' => false,
344
-            ],
345
-            'edit'                   => [
346
-                'nav'           => [
347
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
348
-                    'order'      => 5,
349
-                    'persistent' => false,
350
-                    'url'        => $post_id
351
-                        ? EE_Admin_Page::add_query_args_and_nonce(
352
-                            ['post' => $post_id, 'action' => 'edit'],
353
-                            $this->_current_page_view_url
354
-                        )
355
-                        : $this->_admin_base_url,
356
-                ],
357
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
358
-                'help_tabs'     => [
359
-                    'event_editor_help_tab'                            => [
360
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
361
-                        'filename' => 'event_editor',
362
-                    ],
363
-                    'event_editor_title_richtexteditor_help_tab'       => [
364
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
365
-                        'filename' => 'event_editor_title_richtexteditor',
366
-                    ],
367
-                    'event_editor_venue_details_help_tab'              => [
368
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
369
-                        'filename' => 'event_editor_venue_details',
370
-                    ],
371
-                    'event_editor_event_datetimes_help_tab'            => [
372
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
373
-                        'filename' => 'event_editor_event_datetimes',
374
-                    ],
375
-                    'event_editor_event_tickets_help_tab'              => [
376
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
377
-                        'filename' => 'event_editor_event_tickets',
378
-                    ],
379
-                    'event_editor_event_registration_options_help_tab' => [
380
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
381
-                        'filename' => 'event_editor_event_registration_options',
382
-                    ],
383
-                    'event_editor_tags_categories_help_tab'            => [
384
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
385
-                        'filename' => 'event_editor_tags_categories',
386
-                    ],
387
-                    'event_editor_questions_registrants_help_tab'      => [
388
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
389
-                        'filename' => 'event_editor_questions_registrants',
390
-                    ],
391
-                    'event_editor_save_new_event_help_tab'             => [
392
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
393
-                        'filename' => 'event_editor_save_new_event',
394
-                    ],
395
-                    'event_editor_other_help_tab'                      => [
396
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
397
-                        'filename' => 'event_editor_other',
398
-                    ],
399
-                ],
400
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
401
-                'require_nonce' => false,
402
-            ],
403
-            'default_event_settings' => [
404
-                'nav'           => [
405
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
406
-                    'order' => 40,
407
-                ],
408
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
409
-                'labels'        => [
410
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
411
-                ],
412
-                'help_tabs'     => [
413
-                    'default_settings_help_tab'        => [
414
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
415
-                        'filename' => 'events_default_settings',
416
-                    ],
417
-                    'default_settings_status_help_tab' => [
418
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
419
-                        'filename' => 'events_default_settings_status',
420
-                    ],
421
-                    'default_maximum_tickets_help_tab' => [
422
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
423
-                        'filename' => 'events_default_settings_max_tickets',
424
-                    ],
425
-                ],
426
-                'require_nonce' => false,
427
-            ],
428
-            // template settings
429
-            'template_settings'      => [
430
-                'nav'           => [
431
-                    'label' => esc_html__('Templates', 'event_espresso'),
432
-                    'order' => 30,
433
-                ],
434
-                'metaboxes'     => $this->_default_espresso_metaboxes,
435
-                'help_tabs'     => [
436
-                    'general_settings_templates_help_tab' => [
437
-                        'title'    => esc_html__('Templates', 'event_espresso'),
438
-                        'filename' => 'general_settings_templates',
439
-                    ],
440
-                ],
441
-                'require_nonce' => false,
442
-            ],
443
-            // event category stuff
444
-            'add_category'           => [
445
-                'nav'           => [
446
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
447
-                    'order'      => 15,
448
-                    'persistent' => false,
449
-                ],
450
-                'help_tabs'     => [
451
-                    'add_category_help_tab' => [
452
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
453
-                        'filename' => 'events_add_category',
454
-                    ],
455
-                ],
456
-                'metaboxes'     => ['_publish_post_box'],
457
-                'require_nonce' => false,
458
-            ],
459
-            'edit_category'          => [
460
-                'nav'           => [
461
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
462
-                    'order'      => 15,
463
-                    'persistent' => false,
464
-                    'url'        => $EVT_CAT_ID
465
-                        ? add_query_arg(
466
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
467
-                            $this->_current_page_view_url
468
-                        )
469
-                        : $this->_admin_base_url,
470
-                ],
471
-                'help_tabs'     => [
472
-                    'edit_category_help_tab' => [
473
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
474
-                        'filename' => 'events_edit_category',
475
-                    ],
476
-                ],
477
-                'metaboxes'     => ['_publish_post_box'],
478
-                'require_nonce' => false,
479
-            ],
480
-            'category_list'          => [
481
-                'nav'           => [
482
-                    'label' => esc_html__('Categories', 'event_espresso'),
483
-                    'order' => 20,
484
-                ],
485
-                'list_table'    => 'Event_Categories_Admin_List_Table',
486
-                'help_tabs'     => [
487
-                    'events_categories_help_tab'                       => [
488
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
489
-                        'filename' => 'events_categories',
490
-                    ],
491
-                    'events_categories_table_column_headings_help_tab' => [
492
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
493
-                        'filename' => 'events_categories_table_column_headings',
494
-                    ],
495
-                    'events_categories_view_help_tab'                  => [
496
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
497
-                        'filename' => 'events_categories_views',
498
-                    ],
499
-                    'events_categories_other_help_tab'                 => [
500
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
501
-                        'filename' => 'events_categories_other',
502
-                    ],
503
-                ],
504
-                'metaboxes'     => $this->_default_espresso_metaboxes,
505
-                'require_nonce' => false,
506
-            ],
507
-            'preview_deletion'       => [
508
-                'nav'           => [
509
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
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
-    protected function _add_screen_options_default()
532
-    {
533
-        $this->_per_page_screen_option();
534
-    }
535
-
536
-
537
-    /**
538
-     * Implementing screen options for the category list route.
539
-     */
540
-    protected function _add_screen_options_category_list()
541
-    {
542
-        $page_title              = $this->_admin_page_title;
543
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
544
-        $this->_per_page_screen_option();
545
-        $this->_admin_page_title = $page_title;
546
-    }
547
-
548
-
549
-    /**
550
-     * Used to register any global feature pointers for the admin page group.
551
-     */
552
-    protected function _add_feature_pointers()
553
-    {
554
-    }
555
-
556
-
557
-    /**
558
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
559
-     */
560
-    public function load_scripts_styles()
561
-    {
562
-        wp_register_style(
563
-            'events-admin-css',
564
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
565
-            [],
566
-            EVENT_ESPRESSO_VERSION
567
-        );
568
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
569
-        wp_enqueue_style('events-admin-css');
570
-        wp_enqueue_style('ee-cat-admin');
571
-        // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
572
-        // registers for all views
573
-        // scripts
574
-        wp_register_script(
575
-            'event_editor_js',
576
-            EVENTS_ASSETS_URL . 'event_editor.js',
577
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
578
-            EVENT_ESPRESSO_VERSION,
579
-            true
580
-        );
581
-    }
582
-
583
-
584
-    /**
585
-     * Enqueuing scripts and styles specific to this view
586
-     */
587
-    public function load_scripts_styles_create_new()
588
-    {
589
-        $this->load_scripts_styles_edit();
590
-    }
591
-
592
-
593
-    /**
594
-     * Enqueuing scripts and styles specific to this view
595
-     */
596
-    public function load_scripts_styles_edit()
597
-    {
598
-        // styles
599
-        wp_enqueue_style('espresso-ui-theme');
600
-        wp_register_style(
601
-            'event-editor-css',
602
-            EVENTS_ASSETS_URL . 'event-editor.css',
603
-            ['ee-admin-css'],
604
-            EVENT_ESPRESSO_VERSION
605
-        );
606
-        wp_enqueue_style('event-editor-css');
607
-        // scripts
608
-        wp_register_script(
609
-            'event-datetime-metabox',
610
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
611
-            ['event_editor_js', 'ee-datepicker'],
612
-            EVENT_ESPRESSO_VERSION
613
-        );
614
-        wp_enqueue_script('event-datetime-metabox');
615
-    }
616
-
617
-
618
-    /**
619
-     * Populating the _views property for the category list table view.
620
-     */
621
-    protected function _set_list_table_views_category_list()
622
-    {
623
-        $this->_views = [
624
-            'all' => [
625
-                'slug'        => 'all',
626
-                'label'       => esc_html__('All', 'event_espresso'),
627
-                'count'       => 0,
628
-                'bulk_action' => [
629
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
630
-                ],
631
-            ],
632
-        ];
633
-    }
634
-
635
-
636
-    /**
637
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
638
-     */
639
-    public function admin_init()
640
-    {
641
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
642
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
643
-            'event_espresso'
644
-        );
645
-    }
646
-
647
-
648
-    /**
649
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
650
-     * group.
651
-     */
652
-    public function admin_notices()
653
-    {
654
-    }
655
-
656
-
657
-    /**
658
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
659
-     * this admin page group.
660
-     */
661
-    public function admin_footer_scripts()
662
-    {
663
-    }
664
-
665
-
666
-    /**
667
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
668
-     * warning (via EE_Error::add_error());
669
-     *
670
-     * @param EE_Event $event Event object
671
-     * @param string   $req_type
672
-     * @return void
673
-     * @throws EE_Error
674
-     * @throws ReflectionException
675
-     */
676
-    public function verify_event_edit($event = null, $req_type = '')
677
-    {
678
-        // don't need to do this when processing
679
-        if (! empty($req_type)) {
680
-            return;
681
-        }
682
-        // no event?
683
-        if (empty($event)) {
684
-            // set event
685
-            $event = $this->_cpt_model_obj;
686
-        }
687
-        // STILL no event?
688
-        if (! $event instanceof EE_Event) {
689
-            return;
690
-        }
691
-        $orig_status = $event->status();
692
-        // first check if event is active.
693
-        if (
694
-            $orig_status === EEM_Event::cancelled
695
-            || $orig_status === EEM_Event::postponed
696
-            || $event->is_expired()
697
-            || $event->is_inactive()
698
-        ) {
699
-            return;
700
-        }
701
-        // made it here so it IS active... next check that any of the tickets are sold.
702
-        if ($event->is_sold_out(true)) {
703
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
704
-                EE_Error::add_attention(
705
-                    sprintf(
706
-                        esc_html__(
707
-                            '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.',
708
-                            'event_espresso'
709
-                        ),
710
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
711
-                    )
712
-                );
713
-            }
714
-            return;
715
-        } elseif ($orig_status === EEM_Event::sold_out) {
716
-            EE_Error::add_attention(
717
-                sprintf(
718
-                    esc_html__(
719
-                        '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.',
720
-                        'event_espresso'
721
-                    ),
722
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
723
-                )
724
-            );
725
-        }
726
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
727
-        if (! $event->tickets_on_sale()) {
728
-            return;
729
-        }
730
-        // made it here so show warning
731
-        $this->_edit_event_warning();
732
-    }
733
-
734
-
735
-    /**
736
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
737
-     * When needed, hook this into a EE_Error::add_error() notice.
738
-     *
739
-     * @access protected
740
-     * @return void
741
-     */
742
-    protected function _edit_event_warning()
743
-    {
744
-        // we don't want to add warnings during these requests
745
-        if ($this->request->getRequestParam('action') === 'editpost') {
746
-            return;
747
-        }
748
-        EE_Error::add_attention(
749
-            sprintf(
750
-                esc_html__(
751
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
752
-                    'event_espresso'
753
-                ),
754
-                '<a class="espresso-help-tab-lnk">',
755
-                '</a>'
756
-            )
757
-        );
758
-    }
759
-
760
-
761
-    /**
762
-     * When a user is creating a new event, notify them if they haven't set their timezone.
763
-     * Otherwise, do the normal logic
764
-     *
765
-     * @return void
766
-     * @throws EE_Error
767
-     */
768
-    protected function _create_new_cpt_item()
769
-    {
770
-        $has_timezone_string = get_option('timezone_string');
771
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
772
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
773
-            EE_Error::add_attention(
774
-                sprintf(
775
-                    esc_html__(
776
-                        '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',
777
-                        'event_espresso'
778
-                    ),
779
-                    '<br>',
780
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
781
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
782
-                    . '</select>',
783
-                    '<button class="button button-secondary timezone-submit">',
784
-                    '</button><span class="spinner"></span>'
785
-                ),
786
-                __FILE__,
787
-                __FUNCTION__,
788
-                __LINE__
789
-            );
790
-        }
791
-        parent::_create_new_cpt_item();
792
-    }
793
-
794
-
795
-    /**
796
-     * Sets the _views property for the default route in this admin page group.
797
-     */
798
-    protected function _set_list_table_views_default()
799
-    {
800
-        $this->_views = [
801
-            'all'   => [
802
-                'slug'        => 'all',
803
-                'label'       => esc_html__('View All Events', 'event_espresso'),
804
-                'count'       => 0,
805
-                'bulk_action' => [
806
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
807
-                ],
808
-            ],
809
-            'draft' => [
810
-                'slug'        => 'draft',
811
-                'label'       => esc_html__('Draft', 'event_espresso'),
812
-                'count'       => 0,
813
-                'bulk_action' => [
814
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
815
-                ],
816
-            ],
817
-        ];
818
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
819
-            $this->_views['trash'] = [
820
-                'slug'        => 'trash',
821
-                'label'       => esc_html__('Trash', 'event_espresso'),
822
-                'count'       => 0,
823
-                'bulk_action' => [
824
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
825
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
826
-                ],
827
-            ];
828
-        }
829
-    }
830
-
831
-
832
-    /**
833
-     * Provides the legend item array for the default list table view.
834
-     *
835
-     * @return array
836
-     * @throws EE_Error
837
-     * @throws EE_Error
838
-     */
839
-    protected function _event_legend_items()
840
-    {
841
-        $items    = [
842
-            'view_details'   => [
843
-                'class' => 'dashicons dashicons-search',
844
-                'desc'  => esc_html__('View Event', 'event_espresso'),
845
-            ],
846
-            'edit_event'     => [
847
-                'class' => 'ee-icon ee-icon-calendar-edit',
848
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
849
-            ],
850
-            'view_attendees' => [
851
-                'class' => 'dashicons dashicons-groups',
852
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
853
-            ],
854
-        ];
855
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856
-        $statuses = [
857
-            'sold_out_status'  => [
858
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
859
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860
-            ],
861
-            'active_status'    => [
862
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
863
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864
-            ],
865
-            'upcoming_status'  => [
866
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
867
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868
-            ],
869
-            'postponed_status' => [
870
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
871
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872
-            ],
873
-            'cancelled_status' => [
874
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
875
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876
-            ],
877
-            'expired_status'   => [
878
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
879
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880
-            ],
881
-            'inactive_status'  => [
882
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
883
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884
-            ],
885
-        ];
886
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
887
-        return array_merge($items, $statuses);
888
-    }
889
-
890
-
891
-    /**
892
-     * @return EEM_Event
893
-     * @throws EE_Error
894
-     * @throws ReflectionException
895
-     */
896
-    private function _event_model()
897
-    {
898
-        if (! $this->_event_model instanceof EEM_Event) {
899
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
900
-        }
901
-        return $this->_event_model;
902
-    }
903
-
904
-
905
-    /**
906
-     * Adds extra buttons to the WP CPT permalink field row.
907
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
908
-     *
909
-     * @param string $return    the current html
910
-     * @param int    $id        the post id for the page
911
-     * @param string $new_title What the title is
912
-     * @param string $new_slug  what the slug is
913
-     * @return string            The new html string for the permalink area
914
-     */
915
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
916
-    {
917
-        // make sure this is only when editing
918
-        if (! empty($id)) {
919
-            $post   = get_post($id);
920
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
921
-                       . esc_html__('Shortcode', 'event_espresso')
922
-                       . '</a> ';
923
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
924
-                       . $post->ID
925
-                       . ']">';
926
-        }
927
-        return $return;
928
-    }
929
-
930
-
931
-    /**
932
-     * _events_overview_list_table
933
-     * This contains the logic for showing the events_overview list
934
-     *
935
-     * @access protected
936
-     * @return void
937
-     * @throws EE_Error
938
-     */
939
-    protected function _events_overview_list_table()
940
-    {
941
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
942
-        $this->_template_args['after_list_table']                           =
943
-            ! empty($this->_template_args['after_list_table'])
944
-                ? (array) $this->_template_args['after_list_table']
945
-                : [];
946
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
947
-            . EEH_Template::get_button_or_link(
948
-                get_post_type_archive_link('espresso_events'),
949
-                esc_html__("View Event Archive Page", "event_espresso"),
950
-                'button'
951
-            );
952
-        $this->_template_args['after_list_table']['legend']                 = $this->_display_legend(
953
-            $this->_event_legend_items()
954
-        );
955
-        $this->_admin_page_title                                            .= ' ' . $this->get_action_link_or_button(
956
-            'create_new',
957
-            'add',
958
-            [],
959
-            'add-new-h2'
960
-        );
961
-        $this->display_admin_list_table_page_with_no_sidebar();
962
-    }
963
-
964
-
965
-    /**
966
-     * this allows for extra misc actions in the default WP publish box
967
-     *
968
-     * @return void
969
-     * @throws EE_Error
970
-     * @throws ReflectionException
971
-     */
972
-    public function extra_misc_actions_publish_box()
973
-    {
974
-        $this->_generate_publish_box_extra_content();
975
-    }
976
-
977
-
978
-    /**
979
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
980
-     * saved.
981
-     * Typically you would use this to save any additional data.
982
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
983
-     * ALSO very important.  When a post transitions from scheduled to published,
984
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
985
-     * other meta saves. So MAKE sure that you handle this accordingly.
986
-     *
987
-     * @access protected
988
-     * @abstract
989
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
990
-     * @param WP_Post $post    The post object of the cpt that was saved.
991
-     * @return void
992
-     * @throws EE_Error
993
-     * @throws ReflectionException
994
-     */
995
-    protected function _insert_update_cpt_item($post_id, $post)
996
-    {
997
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
998
-            // get out we're not processing an event save.
999
-            return;
1000
-        }
1001
-
1002
-        $event_values = [
1003
-            'EVT_display_desc'                => $this->request->getRequestParam('display_desc', false, 'bool'),
1004
-            'EVT_display_ticket_selector'     => $this->request->getRequestParam(
1005
-                'display_ticket_selector',
1006
-                false,
1007
-                'bool'
1008
-            ),
1009
-            'EVT_additional_limit'            => min(
1010
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1011
-                $this->request->getRequestParam('additional_limit', null, 'int')
1012
-            ),
1013
-            'EVT_default_registration_status' => $this->request->getRequestParam(
1014
-                'EVT_default_registration_status',
1015
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1016
-            ),
1017
-
1018
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1019
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1020
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1021
-            'EVT_external_URL'    => $this->request->getRequestParam('externalURL'),
1022
-            'EVT_phone'           => $this->request->getRequestParam('event_phone'),
1023
-        ];
1024
-        // update event
1025
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1026
-        // get event_object for other metaboxes...
1027
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1028
-        // i have to setup where conditions to override the filters in the model
1029
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1030
-        $event = $this->_event_model()->get_one(
1031
-            [
1032
-                [
1033
-                    $this->_event_model()->primary_key_name() => $post_id,
1034
-                    'OR'                                      => [
1035
-                        'status'   => $post->post_status,
1036
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1037
-                        // but the returned object here has a status of "publish", so use the original post status as well
1038
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1039
-                    ],
1040
-                ],
1041
-            ]
1042
-        );
1043
-        // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1044
-        $event_update_callbacks = apply_filters(
1045
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1046
-            [
1047
-                [$this, '_default_venue_update'],
1048
-                [$this, '_default_tickets_update'],
1049
-            ]
1050
-        );
1051
-        $att_success            = true;
1052
-        foreach ($event_update_callbacks as $e_callback) {
1053
-            $_success = is_callable($e_callback)
1054
-                ? call_user_func($e_callback, $event, $this->request->requestParams())
1055
-                : false;
1056
-            // if ANY of these updates fail then we want the appropriate global error message
1057
-            $att_success = ! $att_success ? $att_success : $_success;
1058
-        }
1059
-        // any errors?
1060
-        if ($success && false === $att_success) {
1061
-            EE_Error::add_error(
1062
-                esc_html__(
1063
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1064
-                    'event_espresso'
1065
-                ),
1066
-                __FILE__,
1067
-                __FUNCTION__,
1068
-                __LINE__
1069
-            );
1070
-        } elseif ($success === false) {
1071
-            EE_Error::add_error(
1072
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1073
-                __FILE__,
1074
-                __FUNCTION__,
1075
-                __LINE__
1076
-            );
1077
-        }
1078
-    }
1079
-
1080
-
1081
-    /**
1082
-     * @param int $post_id
1083
-     * @param int $revision_id
1084
-     * @throws EE_Error
1085
-     * @throws EE_Error
1086
-     * @throws ReflectionException
1087
-     * @see parent::restore_item()
1088
-     */
1089
-    protected function _restore_cpt_item($post_id, $revision_id)
1090
-    {
1091
-        // copy existing event meta to new post
1092
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1093
-        if ($post_evt instanceof EE_Event) {
1094
-            // meta revision restore
1095
-            $post_evt->restore_revision($revision_id);
1096
-            // related objs restore
1097
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1098
-        }
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * Attach the venue to the Event
1104
-     *
1105
-     * @param EE_Event $event Event Object to add the venue to
1106
-     * @param array    $data  The request data from the form
1107
-     * @return bool           Success or fail.
1108
-     * @throws EE_Error
1109
-     * @throws ReflectionException
1110
-     */
1111
-    protected function _default_venue_update(EE_Event $event, $data)
1112
-    {
1113
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1114
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1115
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1116
-        // very important.  If we don't have a venue name...
1117
-        // then we'll get out because not necessary to create empty venue
1118
-        if (empty($data['venue_title'])) {
1119
-            return false;
1120
-        }
1121
-        $venue_array = [
1122
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1123
-            'VNU_name'            => $data['venue_title'],
1124
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1125
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1126
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1127
-                ? $data['venue_short_description']
1128
-                : null,
1129
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1130
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1131
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1132
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1133
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1134
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1135
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1136
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1137
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1138
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1139
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1140
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1141
-            'status'              => 'publish',
1142
-        ];
1143
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1144
-        if (! empty($venue_id)) {
1145
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1146
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1147
-            // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1148
-            $event->_add_relation_to($venue_id, 'Venue');
1149
-            return $rows_affected > 0;
1150
-        }
1151
-        // we insert the venue
1152
-        $venue_id = $venue_model->insert($venue_array);
1153
-        $event->_add_relation_to($venue_id, 'Venue');
1154
-        return ! empty($venue_id);
1155
-        // when we have the ancestor come in it's already been handled by the revision save.
1156
-    }
1157
-
1158
-
1159
-    /**
1160
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1161
-     *
1162
-     * @param EE_Event $event The Event object we're attaching data to
1163
-     * @param array    $data  The request data from the form
1164
-     * @return array
1165
-     * @throws EE_Error
1166
-     * @throws ReflectionException
1167
-     * @throws Exception
1168
-     */
1169
-    protected function _default_tickets_update(EE_Event $event, $data)
1170
-    {
1171
-        $datetime       = null;
1172
-        $saved_tickets  = [];
1173
-        $event_timezone = $event->get_timezone();
1174
-        $date_formats   = ['Y-m-d', 'h:i a'];
1175
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1176
-            // trim all values to ensure any excess whitespace is removed.
1177
-            $datetime_data                = array_map('trim', $datetime_data);
1178
-            $datetime_data['DTT_EVT_end'] =
1179
-                isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1180
-                    ? $datetime_data['DTT_EVT_end']
1181
-                    : $datetime_data['DTT_EVT_start'];
1182
-            $datetime_values              = [
1183
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1184
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1185
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1186
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1187
-                'DTT_order'     => $row,
1188
-            ];
1189
-            // if we have an id then let's get existing object first and then set the new values.
1190
-            //  Otherwise we instantiate a new object for save.
1191
-            if (! empty($datetime_data['DTT_ID'])) {
1192
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1193
-                if (! $datetime instanceof EE_Datetime) {
1194
-                    throw new RuntimeException(
1195
-                        sprintf(
1196
-                            esc_html__(
1197
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1198
-                                'event_espresso'
1199
-                            ),
1200
-                            $datetime_data['DTT_ID']
1201
-                        )
1202
-                    );
1203
-                }
1204
-                $datetime->set_date_format($date_formats[0]);
1205
-                $datetime->set_time_format($date_formats[1]);
1206
-                foreach ($datetime_values as $field => $value) {
1207
-                    $datetime->set($field, $value);
1208
-                }
1209
-            } else {
1210
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1211
-            }
1212
-            if (! $datetime instanceof EE_Datetime) {
1213
-                throw new RuntimeException(
1214
-                    sprintf(
1215
-                        esc_html__(
1216
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1217
-                            'event_espresso'
1218
-                        ),
1219
-                        print_r($datetime_values, true)
1220
-                    )
1221
-                );
1222
-            }
1223
-            // before going any further make sure our dates are setup correctly
1224
-            // so that the end date is always equal or greater than the start date.
1225
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1226
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1227
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1228
-            }
1229
-            $datetime->save();
1230
-            $event->_add_relation_to($datetime, 'Datetime');
1231
-        }
1232
-        // no datetimes get deleted so we don't do any of that logic here.
1233
-        // update tickets next
1234
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1235
-
1236
-        // set up some default start and end dates in case those are not present in the incoming data
1237
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1238
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1239
-        // use the start date of the first datetime for the end date
1240
-        $first_datetime   = $event->first_datetime();
1241
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1242
-
1243
-        // now process the incoming data
1244
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1245
-            $update_prices = false;
1246
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1247
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1248
-                : 0;
1249
-            // trim inputs to ensure any excess whitespace is removed.
1250
-            $ticket_data   = array_map('trim', $ticket_data);
1251
-            $ticket_values = [
1252
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1253
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1254
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1255
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1256
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1257
-                    ? $ticket_data['TKT_start_date']
1258
-                    : $default_start_date,
1259
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1260
-                    ? $ticket_data['TKT_end_date']
1261
-                    : $default_end_date,
1262
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1263
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1264
-                    ? $ticket_data['TKT_qty']
1265
-                    : EE_INF,
1266
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1267
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1268
-                    ? $ticket_data['TKT_uses']
1269
-                    : EE_INF,
1270
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1271
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1272
-                'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1273
-                'TKT_price'       => $ticket_price,
1274
-                'TKT_row'         => $row,
1275
-            ];
1276
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1277
-            // which means in turn that the prices will become new prices as well.
1278
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1279
-                $ticket_values['TKT_ID']         = 0;
1280
-                $ticket_values['TKT_is_default'] = 0;
1281
-                $update_prices                   = true;
1282
-            }
1283
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1284
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1285
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1286
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1287
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1288
-            if (! empty($ticket_data['TKT_ID'])) {
1289
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1290
-                if (! $existing_ticket instanceof EE_Ticket) {
1291
-                    throw new RuntimeException(
1292
-                        sprintf(
1293
-                            esc_html__(
1294
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1295
-                                'event_espresso'
1296
-                            ),
1297
-                            $ticket_data['TKT_ID']
1298
-                        )
1299
-                    );
1300
-                }
1301
-                $ticket_sold = $existing_ticket->count_related(
1302
-                    'Registration',
1303
-                    [
1304
-                        [
1305
-                            'STS_ID' => [
1306
-                                'NOT IN',
1307
-                                [EEM_Registration::status_id_incomplete],
1308
-                            ],
1309
-                        ],
1310
-                    ]
1311
-                ) > 0;
1312
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1313
-                // if they are different then we create a new ticket (if $ticket_sold)
1314
-                // if they aren't different then we go ahead and modify existing ticket.
1315
-                $create_new_ticket = $ticket_sold
1316
-                                     && $ticket_price !== $existing_ticket->price()
1317
-                                     && ! $existing_ticket->deleted();
1318
-                $existing_ticket->set_date_format($date_formats[0]);
1319
-                $existing_ticket->set_time_format($date_formats[1]);
1320
-                // set new values
1321
-                foreach ($ticket_values as $field => $value) {
1322
-                    if ($field == 'TKT_qty') {
1323
-                        $existing_ticket->set_qty($value);
1324
-                    } elseif ($field == 'TKT_price') {
1325
-                        $existing_ticket->set('TKT_price', $ticket_price);
1326
-                    } else {
1327
-                        $existing_ticket->set($field, $value);
1328
-                    }
1329
-                }
1330
-                $ticket = $existing_ticket;
1331
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1332
-                //  Otherwise we have to create a new ticket.
1333
-                if ($create_new_ticket) {
1334
-                    // archive the old ticket first
1335
-                    $existing_ticket->set('TKT_deleted', 1);
1336
-                    $existing_ticket->save();
1337
-                    // make sure this ticket is still recorded in our $saved_tickets
1338
-                    // so we don't run it through the regular trash routine.
1339
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1340
-                    // create new ticket that's a copy of the existing except,
1341
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1342
-                    $new_ticket = clone $existing_ticket;
1343
-                    $new_ticket->set('TKT_ID', 0);
1344
-                    $new_ticket->set('TKT_deleted', 0);
1345
-                    $new_ticket->set('TKT_sold', 0);
1346
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1347
-                    $update_prices = true;
1348
-                    $ticket        = $new_ticket;
1349
-                }
1350
-            } else {
1351
-                // no TKT_id so a new ticket
1352
-                $ticket_values['TKT_price'] = $ticket_price;
1353
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1354
-                $update_prices              = true;
1355
-            }
1356
-            if (! $ticket instanceof EE_Ticket) {
1357
-                throw new RuntimeException(
1358
-                    sprintf(
1359
-                        esc_html__(
1360
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1361
-                            'event_espresso'
1362
-                        ),
1363
-                        print_r($ticket_values, true)
1364
-                    )
1365
-                );
1366
-            }
1367
-            // cap ticket qty by datetime reg limits
1368
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1369
-            // update ticket.
1370
-            $ticket->save();
1371
-            // before going any further make sure our dates are setup correctly
1372
-            // so that the end date is always equal or greater than the start date.
1373
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1374
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1375
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1376
-                $ticket->save();
1377
-            }
1378
-            // initially let's add the ticket to the datetime
1379
-            $datetime->_add_relation_to($ticket, 'Ticket');
1380
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1381
-            // add prices to ticket
1382
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1383
-                ? $data['edit_prices'][ $row ]
1384
-                : [];
1385
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1386
-        }
1387
-        // however now we need to handle permanently deleting tickets via the ui.
1388
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1389
-        // However, it does allow for deleting tickets that have no tickets sold,
1390
-        // in which case we want to get rid of permanently because there is no need to save in db.
1391
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? [] : $old_tickets;
1392
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1393
-        foreach ($tickets_removed as $id) {
1394
-            $id = absint($id);
1395
-            // get the ticket for this id
1396
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1397
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1398
-                continue;
1399
-            }
1400
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1401
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1402
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1403
-            foreach ($related_datetimes as $related_datetime) {
1404
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1405
-            }
1406
-            // need to do the same for prices (except these prices can also be deleted because again,
1407
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1408
-            $ticket_to_remove->delete_related_permanently('Price');
1409
-            // finally let's delete this ticket
1410
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1411
-            $ticket_to_remove->delete_permanently();
1412
-        }
1413
-        return [$datetime, $saved_tickets];
1414
-    }
1415
-
1416
-
1417
-    /**
1418
-     * This attaches a list of given prices to a ticket.
1419
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1420
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1421
-     * price info and prices are automatically "archived" via the ticket.
1422
-     *
1423
-     * @access  private
1424
-     * @param array     $prices_data Array of prices from the form.
1425
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1426
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1427
-     * @return  void
1428
-     * @throws EE_Error
1429
-     * @throws ReflectionException
1430
-     */
1431
-    private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1432
-    {
1433
-        $timezone = $ticket->get_timezone();
1434
-        foreach ($prices_data as $row => $price_data) {
1435
-            $price_values = [
1436
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1437
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1438
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1439
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1440
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1441
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1442
-                'PRC_order'      => $row,
1443
-            ];
1444
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1445
-                $price_values['PRC_ID'] = 0;
1446
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1447
-            } else {
1448
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1449
-                // update this price with new values
1450
-                foreach ($price_values as $field => $new_price) {
1451
-                    $price->set($field, $new_price);
1452
-                }
1453
-            }
1454
-            if (! $price instanceof EE_Price) {
1455
-                throw new RuntimeException(
1456
-                    sprintf(
1457
-                        esc_html__(
1458
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1459
-                            'event_espresso'
1460
-                        ),
1461
-                        print_r($price_values, true)
1462
-                    )
1463
-                );
1464
-            }
1465
-            $price->save();
1466
-            $ticket->_add_relation_to($price, 'Price');
1467
-        }
1468
-    }
1469
-
1470
-
1471
-    /**
1472
-     * Add in our autosave ajax handlers
1473
-     *
1474
-     */
1475
-    protected function _ee_autosave_create_new()
1476
-    {
1477
-    }
1478
-
1479
-
1480
-    /**
1481
-     * More autosave handlers.
1482
-     */
1483
-    protected function _ee_autosave_edit()
1484
-    {
1485
-        // TEMPORARILY EXITING CAUSE THIS IS A TODO
1486
-    }
1487
-
1488
-
1489
-    /**
1490
-     * @throws EE_Error
1491
-     * @throws ReflectionException
1492
-     */
1493
-    private function _generate_publish_box_extra_content()
1494
-    {
1495
-        // load formatter helper
1496
-        // args for getting related registrations
1497
-        $approved_query_args        = [
1498
-            [
1499
-                'REG_deleted' => 0,
1500
-                'STS_ID'      => EEM_Registration::status_id_approved,
1501
-            ],
1502
-        ];
1503
-        $not_approved_query_args    = [
1504
-            [
1505
-                'REG_deleted' => 0,
1506
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1507
-            ],
1508
-        ];
1509
-        $pending_payment_query_args = [
1510
-            [
1511
-                'REG_deleted' => 0,
1512
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1513
-            ],
1514
-        ];
1515
-        // publish box
1516
-        $publish_box_extra_args = [
1517
-            'view_approved_reg_url'        => add_query_arg(
1518
-                [
1519
-                    'action'      => 'default',
1520
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1521
-                    '_reg_status' => EEM_Registration::status_id_approved,
1522
-                    'use_filters' => true,
1523
-                ],
1524
-                REG_ADMIN_URL
1525
-            ),
1526
-            'view_not_approved_reg_url'    => add_query_arg(
1527
-                [
1528
-                    'action'      => 'default',
1529
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1530
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1531
-                    'use_filters' => true,
1532
-                ],
1533
-                REG_ADMIN_URL
1534
-            ),
1535
-            'view_pending_payment_reg_url' => add_query_arg(
1536
-                [
1537
-                    'action'      => 'default',
1538
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1539
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1540
-                    'use_filters' => true,
1541
-                ],
1542
-                REG_ADMIN_URL
1543
-            ),
1544
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1545
-                'Registration',
1546
-                $approved_query_args
1547
-            ),
1548
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1549
-                'Registration',
1550
-                $not_approved_query_args
1551
-            ),
1552
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1553
-                'Registration',
1554
-                $pending_payment_query_args
1555
-            ),
1556
-            'misc_pub_section_class'       => apply_filters(
1557
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1558
-                'misc-pub-section'
1559
-            ),
1560
-        ];
1561
-        ob_start();
1562
-        do_action(
1563
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1564
-            $this->_cpt_model_obj
1565
-        );
1566
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1567
-        // load template
1568
-        EEH_Template::display_template(
1569
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1570
-            $publish_box_extra_args
1571
-        );
1572
-    }
1573
-
1574
-
1575
-    /**
1576
-     * @return EE_Event
1577
-     */
1578
-    public function get_event_object()
1579
-    {
1580
-        return $this->_cpt_model_obj;
1581
-    }
1582
-
1583
-
1584
-
1585
-
1586
-    /** METABOXES * */
1587
-    /**
1588
-     * _register_event_editor_meta_boxes
1589
-     * add all metaboxes related to the event_editor
1590
-     *
1591
-     * @return void
1592
-     * @throws EE_Error
1593
-     * @throws ReflectionException
1594
-     */
1595
-    protected function _register_event_editor_meta_boxes()
1596
-    {
1597
-        $this->verify_cpt_object();
1598
-        add_meta_box(
1599
-            'espresso_event_editor_tickets',
1600
-            esc_html__('Event Datetime & Ticket', 'event_espresso'),
1601
-            [$this, 'ticket_metabox'],
1602
-            $this->page_slug,
1603
-            'normal',
1604
-            'high'
1605
-        );
1606
-        add_meta_box(
1607
-            'espresso_event_editor_event_options',
1608
-            esc_html__('Event Registration Options', 'event_espresso'),
1609
-            [$this, 'registration_options_meta_box'],
1610
-            $this->page_slug,
1611
-            'side'
1612
-        );
1613
-        // NOTE: if you're looking for other metaboxes in here,
1614
-        // where a metabox has a related management page in the admin
1615
-        // you will find it setup in the related management page's "_Hooks" file.
1616
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1617
-    }
1618
-
1619
-
1620
-    /**
1621
-     * @throws DomainException
1622
-     * @throws EE_Error
1623
-     * @throws ReflectionException
1624
-     */
1625
-    public function ticket_metabox()
1626
-    {
1627
-        $existing_datetime_ids = $existing_ticket_ids = [];
1628
-        // defaults for template args
1629
-        $template_args = [
1630
-            'ticket_rows'              => '',
1631
-            'total_ticket_rows'        => 1,
1632
-            'trash_icon'               => 'ee-lock-icon',
1633
-            'disabled'                 => '',
1634
-        ];
1635
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1636
-        /**
1637
-         * 1. Start with retrieving Datetimes
1638
-         * 2. Fore each datetime get related tickets
1639
-         * 3. For each ticket get related prices
1640
-         */
1641
-        $times          = EEM_Datetime::instance()->get_all_event_dates($event_id);
1642
-        $first_datetime = reset($times);
1643
-        // do we get related tickets?
1644
-        if (
1645
-            $first_datetime instanceof EE_Datetime
1646
-            && $first_datetime->ID() !== 0
1647
-        ) {
1648
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1649
-            $template_args['time']   = $first_datetime;
1650
-            $related_tickets         = $first_datetime->tickets(
1651
-                [
1652
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1653
-                    'default_where_conditions' => 'none',
1654
-                ]
1655
-            );
1656
-            if (! empty($related_tickets)) {
1657
-                $template_args['total_ticket_rows'] = count($related_tickets);
1658
-                $row                                = 0;
1659
-                foreach ($related_tickets as $ticket) {
1660
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1661
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1662
-                    $row++;
1663
-                }
1664
-            } else {
1665
-                $template_args['total_ticket_rows'] = 1;
1666
-                $ticket                       = EEM_Ticket::instance()->create_default_object();
1667
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1668
-            }
1669
-        } else {
1670
-            $template_args['time']        = $times[0];
1671
-            $tickets                      = EEM_Ticket::instance()->get_all_default_tickets();
1672
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1673
-            // NOTE: we're just sending the first default row
1674
-            // (decaf can't manage default tickets so this should be sufficient);
1675
-        }
1676
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1677
-            'event_editor_event_datetimes_help_tab'
1678
-        );
1679
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1680
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1681
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1682
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1683
-            EEM_Ticket::instance()->create_default_object(),
1684
-            true
1685
-        );
1686
-        $template                                  = apply_filters(
1687
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1688
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1689
-        );
1690
-        EEH_Template::display_template($template, $template_args);
1691
-    }
1692
-
1693
-
1694
-    /**
1695
-     * Setup an individual ticket form for the decaf event editor page
1696
-     *
1697
-     * @access private
1698
-     * @param EE_Ticket $ticket   the ticket object
1699
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1700
-     * @param int       $row
1701
-     * @return string generated html for the ticket row.
1702
-     * @throws EE_Error
1703
-     * @throws ReflectionException
1704
-     */
1705
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1706
-    {
1707
-        $template_args = [
1708
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1709
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1710
-                : '',
1711
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1712
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1713
-            'TKT_name'            => $ticket->get('TKT_name'),
1714
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1715
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1716
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1717
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1718
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1719
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1720
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1721
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1722
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1723
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1724
-                : ' disabled=disabled',
1725
-        ];
1726
-        $price         = $ticket->ID() !== 0
1727
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1728
-            : null;
1729
-        $price         = $price instanceof EE_Price
1730
-            ? $price
1731
-            : EEM_Price::instance()->create_default_object();
1732
-        $price_args    = [
1733
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1734
-            'PRC_amount'            => $price->get('PRC_amount'),
1735
-            'PRT_ID'                => $price->get('PRT_ID'),
1736
-            'PRC_ID'                => $price->get('PRC_ID'),
1737
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1738
-        ];
1739
-        // make sure we have default start and end dates if skeleton
1740
-        // handle rows that should NOT be empty
1741
-        if (empty($template_args['TKT_start_date'])) {
1742
-            // if empty then the start date will be now.
1743
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1744
-        }
1745
-        if (empty($template_args['TKT_end_date'])) {
1746
-            // get the earliest datetime (if present);
1747
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1748
-                ? $this->_cpt_model_obj->get_first_related(
1749
-                    'Datetime',
1750
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1751
-                )
1752
-                : null;
1753
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1754
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1755
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1756
-        }
1757
-        $template_args = array_merge($template_args, $price_args);
1758
-        $template      = apply_filters(
1759
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1760
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1761
-            $ticket
1762
-        );
1763
-        return EEH_Template::display_template($template, $template_args, true);
1764
-    }
1765
-
1766
-
1767
-    /**
1768
-     * @throws EE_Error
1769
-     * @throws ReflectionException
1770
-     */
1771
-    public function registration_options_meta_box()
1772
-    {
1773
-        $yes_no_values             = [
1774
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1775
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1776
-        ];
1777
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1778
-            [
1779
-                EEM_Registration::status_id_cancelled,
1780
-                EEM_Registration::status_id_declined,
1781
-                EEM_Registration::status_id_incomplete,
1782
-            ],
1783
-            true
1784
-        );
1785
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1786
-        $template_args['_event']                          = $this->_cpt_model_obj;
1787
-        $template_args['event']                           = $this->_cpt_model_obj;
1788
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1789
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1790
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1791
-            'default_reg_status',
1792
-            $default_reg_status_values,
1793
-            $this->_cpt_model_obj->default_registration_status()
1794
-        );
1795
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1796
-            'display_desc',
1797
-            $yes_no_values,
1798
-            $this->_cpt_model_obj->display_description()
1799
-        );
1800
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1801
-            'display_ticket_selector',
1802
-            $yes_no_values,
1803
-            $this->_cpt_model_obj->display_ticket_selector(),
1804
-            '',
1805
-            '',
1806
-            false
1807
-        );
1808
-        $template_args['additional_registration_options'] = apply_filters(
1809
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1810
-            '',
1811
-            $template_args,
1812
-            $yes_no_values,
1813
-            $default_reg_status_values
1814
-        );
1815
-        EEH_Template::display_template(
1816
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1817
-            $template_args
1818
-        );
1819
-    }
1820
-
1821
-
1822
-    /**
1823
-     * _get_events()
1824
-     * This method simply returns all the events (for the given _view and paging)
1825
-     *
1826
-     * @access public
1827
-     * @param int  $per_page     count of items per page (20 default);
1828
-     * @param int  $current_page what is the current page being viewed.
1829
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1830
-     *                           If FALSE then we return an array of event objects
1831
-     *                           that match the given _view and paging parameters.
1832
-     * @return array|int         an array of event objects or a count of them.
1833
-     * @throws Exception
1834
-     */
1835
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1836
-    {
1837
-        $EEM_Event   = $this->_event_model();
1838
-        $offset      = ($current_page - 1) * $per_page;
1839
-        $limit       = $count ? null : $offset . ',' . $per_page;
1840
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1841
-        $order       = $this->request->getRequestParam('order', 'DESC');
1842
-        $month_range = $this->request->getRequestParam('month_range');
1843
-        if ($month_range) {
1844
-            $pieces = explode(' ', $month_range, 3);
1845
-            // simulate the FIRST day of the month, that fixes issues for months like February
1846
-            // where PHP doesn't know what to assume for date.
1847
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1848
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1849
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1850
-        }
1851
-        $where  = [];
1852
-        $status = $this->request->getRequestParam('status');
1853
-        // determine what post_status our condition will have for the query.
1854
-        switch ($status) {
1855
-            case 'month':
1856
-            case 'today':
1857
-            case null:
1858
-            case 'all':
1859
-                break;
1860
-            case 'draft':
1861
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1862
-                break;
1863
-            default:
1864
-                $where['status'] = $status;
1865
-        }
1866
-        // categories? The default for all categories is -1
1867
-        $category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1868
-        if ($category !== -1) {
1869
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1870
-            $where['Term_Taxonomy.term_id']  = $category;
1871
-        }
1872
-        // date where conditions
1873
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874
-        if ($month_range) {
1875
-            $DateTime = new DateTime(
1876
-                $year_r . '-' . $month_r . '-01 00:00:00',
1877
-                new DateTimeZone('UTC')
1878
-            );
1879
-            $start    = $DateTime->getTimestamp();
1880
-            // set the datetime to be the end of the month
1881
-            $DateTime->setDate(
1882
-                $year_r,
1883
-                $month_r,
1884
-                $DateTime->format('t')
1885
-            )->setTime(23, 59, 59);
1886
-            $end                             = $DateTime->getTimestamp();
1887
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1888
-        } elseif ($status === 'today') {
1889
-            $DateTime                        =
1890
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1891
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1892
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1893
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1894
-        } elseif ($status === 'month') {
1895
-            $now                             = date('Y-m-01');
1896
-            $DateTime                        =
1897
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1898
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1899
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1900
-                                                        ->setTime(23, 59, 59)
1901
-                                                        ->format(implode(' ', $start_formats));
1902
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1903
-        }
1904
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1905
-            $where['EVT_wp_user'] = get_current_user_id();
1906
-        } else {
1907
-            if (! isset($where['status'])) {
1908
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1909
-                    $where['OR'] = [
1910
-                        'status*restrict_private' => ['!=', 'private'],
1911
-                        'AND'                     => [
1912
-                            'status*inclusive' => ['=', 'private'],
1913
-                            'EVT_wp_user'      => get_current_user_id(),
1914
-                        ],
1915
-                    ];
1916
-                }
1917
-            }
1918
-        }
1919
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1920
-        if (
1921
-            $wp_user
1922
-            && $wp_user !== get_current_user_id()
1923
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1924
-        ) {
1925
-            $where['EVT_wp_user'] = $wp_user;
1926
-        }
1927
-        // search query handling
1928
-        $search_term = $this->request->getRequestParam('s');
1929
-        if ($search_term) {
1930
-            $search_term = '%' . $search_term . '%';
1931
-            $where['OR'] = [
1932
-                'EVT_name'       => ['LIKE', $search_term],
1933
-                'EVT_desc'       => ['LIKE', $search_term],
1934
-                'EVT_short_desc' => ['LIKE', $search_term],
1935
-            ];
1936
-        }
1937
-        // filter events by venue.
1938
-        $venue = $this->request->getRequestParam('venue', 0, 'int');
1939
-        if ($venue) {
1940
-            $where['Venue.VNU_ID'] = $venue;
1941
-        }
1942
-        $request_params = $this->request->requestParams();
1943
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
1944
-        $query_params   = apply_filters(
1945
-            'FHEE__Events_Admin_Page__get_events__query_params',
1946
-            [
1947
-                $where,
1948
-                'limit'    => $limit,
1949
-                'order_by' => $orderby,
1950
-                'order'    => $order,
1951
-                'group_by' => 'EVT_ID',
1952
-            ],
1953
-            $request_params
1954
-        );
1955
-
1956
-        // let's first check if we have special requests coming in.
1957
-        $active_status = $this->request->getRequestParam('active_status');
1958
-        if ($active_status) {
1959
-            switch ($active_status) {
1960
-                case 'upcoming':
1961
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
1962
-                case 'expired':
1963
-                    return $EEM_Event->get_expired_events($query_params, $count);
1964
-                case 'active':
1965
-                    return $EEM_Event->get_active_events($query_params, $count);
1966
-                case 'inactive':
1967
-                    return $EEM_Event->get_inactive_events($query_params, $count);
1968
-            }
1969
-        }
1970
-
1971
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
1972
-    }
1973
-
1974
-
1975
-    /**
1976
-     * handling for WordPress CPT actions (trash, restore, delete)
1977
-     *
1978
-     * @param string $post_id
1979
-     * @throws EE_Error
1980
-     * @throws ReflectionException
1981
-     */
1982
-    public function trash_cpt_item($post_id)
1983
-    {
1984
-        $this->request->setRequestParam('EVT_ID', $post_id);
1985
-        $this->_trash_or_restore_event('trash', false);
1986
-    }
1987
-
1988
-
1989
-    /**
1990
-     * @param string $post_id
1991
-     * @throws EE_Error
1992
-     * @throws ReflectionException
1993
-     */
1994
-    public function restore_cpt_item($post_id)
1995
-    {
1996
-        $this->request->setRequestParam('EVT_ID', $post_id);
1997
-        $this->_trash_or_restore_event('draft', false);
1998
-    }
1999
-
2000
-
2001
-    /**
2002
-     * @param string $post_id
2003
-     * @throws EE_Error
2004
-     * @throws EE_Error
2005
-     */
2006
-    public function delete_cpt_item($post_id)
2007
-    {
2008
-        throw new EE_Error(
2009
-            esc_html__(
2010
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2011
-                'event_espresso'
2012
-            )
2013
-        );
2014
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2015
-        // $this->_delete_event();
2016
-    }
2017
-
2018
-
2019
-    /**
2020
-     * _trash_or_restore_event
2021
-     *
2022
-     * @access protected
2023
-     * @param string $event_status
2024
-     * @param bool   $redirect_after
2025
-     * @throws EE_Error
2026
-     * @throws EE_Error
2027
-     * @throws ReflectionException
2028
-     */
2029
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2030
-    {
2031
-        // determine the event id and set to array.
2032
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2033
-        // loop thru events
2034
-        if ($EVT_ID) {
2035
-            // clean status
2036
-            $event_status = sanitize_key($event_status);
2037
-            // grab status
2038
-            if (! empty($event_status)) {
2039
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2040
-            } else {
2041
-                $success = false;
2042
-                $msg     = esc_html__(
2043
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2044
-                    'event_espresso'
2045
-                );
2046
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2047
-            }
2048
-        } else {
2049
-            $success = false;
2050
-            $msg     = esc_html__(
2051
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2052
-                'event_espresso'
2053
-            );
2054
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2055
-        }
2056
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2057
-        if ($redirect_after) {
2058
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2059
-        }
2060
-    }
2061
-
2062
-
2063
-    /**
2064
-     * _trash_or_restore_events
2065
-     *
2066
-     * @access protected
2067
-     * @param string $event_status
2068
-     * @return void
2069
-     * @throws EE_Error
2070
-     * @throws EE_Error
2071
-     * @throws ReflectionException
2072
-     */
2073
-    protected function _trash_or_restore_events($event_status = 'trash')
2074
-    {
2075
-        // clean status
2076
-        $event_status = sanitize_key($event_status);
2077
-        // grab status
2078
-        if (! empty($event_status)) {
2079
-            $success = true;
2080
-            // determine the event id and set to array.
2081
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2082
-            // loop thru events
2083
-            foreach ($EVT_IDs as $EVT_ID) {
2084
-                if ($EVT_ID = absint($EVT_ID)) {
2085
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2086
-                    $success = $results !== false ? $success : false;
2087
-                } else {
2088
-                    $msg = sprintf(
2089
-                        esc_html__(
2090
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2091
-                            'event_espresso'
2092
-                        ),
2093
-                        $EVT_ID
2094
-                    );
2095
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2096
-                    $success = false;
2097
-                }
2098
-            }
2099
-        } else {
2100
-            $success = false;
2101
-            $msg     = esc_html__(
2102
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2103
-                'event_espresso'
2104
-            );
2105
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2106
-        }
2107
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2108
-        $success = $success ? 2 : false;
2109
-        $action  = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2110
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2111
-    }
2112
-
2113
-
2114
-    /**
2115
-     * @param int    $EVT_ID
2116
-     * @param string $event_status
2117
-     * @return bool
2118
-     * @throws EE_Error
2119
-     * @throws ReflectionException
2120
-     */
2121
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2122
-    {
2123
-        // grab event id
2124
-        if (! $EVT_ID) {
2125
-            $msg = esc_html__(
2126
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2127
-                'event_espresso'
2128
-            );
2129
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2130
-            return false;
2131
-        }
2132
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2133
-        // clean status
2134
-        $event_status = sanitize_key($event_status);
2135
-        // grab status
2136
-        if (empty($event_status)) {
2137
-            $msg = esc_html__(
2138
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2139
-                'event_espresso'
2140
-            );
2141
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2142
-            return false;
2143
-        }
2144
-        // was event trashed or restored ?
2145
-        switch ($event_status) {
2146
-            case 'draft':
2147
-                $action = 'restored from the trash';
2148
-                $hook   = 'AHEE_event_restored_from_trash';
2149
-                break;
2150
-            case 'trash':
2151
-                $action = 'moved to the trash';
2152
-                $hook   = 'AHEE_event_moved_to_trash';
2153
-                break;
2154
-            default:
2155
-                $action = 'updated';
2156
-                $hook   = false;
2157
-        }
2158
-        // use class to change status
2159
-        $this->_cpt_model_obj->set_status($event_status);
2160
-        $success = $this->_cpt_model_obj->save();
2161
-        if (! $success) {
2162
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2163
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2164
-            return false;
2165
-        }
2166
-        if ($hook) {
2167
-            do_action($hook);
2168
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2169
-            // because events side step that and it otherwise won't get called
2170
-            do_action(
2171
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2172
-                $this->_cpt_model_obj,
2173
-                $hook === 'AHEE_event_moved_to_trash',
2174
-                $success
2175
-            );
2176
-        }
2177
-        return true;
2178
-    }
2179
-
2180
-
2181
-    /**
2182
-     * @param array $event_ids
2183
-     * @return array
2184
-     * @since   4.10.23.p
2185
-     */
2186
-    private function cleanEventIds(array $event_ids)
2187
-    {
2188
-        return array_map('absint', $event_ids);
2189
-    }
2190
-
2191
-
2192
-    /**
2193
-     * @return array
2194
-     * @since   4.10.23.p
2195
-     */
2196
-    private function getEventIdsFromRequest()
2197
-    {
2198
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2199
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2200
-        } else {
2201
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2202
-        }
2203
-    }
2204
-
2205
-
2206
-    /**
2207
-     * @param bool $preview_delete
2208
-     * @throws EE_Error
2209
-     * @throws ReflectionException
2210
-     */
2211
-    protected function _delete_event($preview_delete = true)
2212
-    {
2213
-        $this->_delete_events($preview_delete);
2214
-    }
2215
-
2216
-
2217
-    /**
2218
-     * Gets the tree traversal batch persister.
2219
-     *
2220
-     * @return NodeGroupDao
2221
-     * @throws InvalidArgumentException
2222
-     * @throws InvalidDataTypeException
2223
-     * @throws InvalidInterfaceException
2224
-     * @since 4.10.12.p
2225
-     */
2226
-    protected function getModelObjNodeGroupPersister()
2227
-    {
2228
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2229
-            $this->model_obj_node_group_persister =
2230
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2231
-        }
2232
-        return $this->model_obj_node_group_persister;
2233
-    }
2234
-
2235
-
2236
-    /**
2237
-     * @param bool $preview_delete
2238
-     * @return void
2239
-     * @throws EE_Error
2240
-     * @throws ReflectionException
2241
-     */
2242
-    protected function _delete_events($preview_delete = true)
2243
-    {
2244
-        $event_ids = $this->getEventIdsFromRequest();
2245
-        if ($preview_delete) {
2246
-            $this->generateDeletionPreview($event_ids);
2247
-        } else {
2248
-            foreach ($event_ids as $event_id) {
2249
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2250
-                if ($event instanceof EE_Event) {
2251
-                    $event->delete_permanently();
2252
-                }
2253
-            }
2254
-        }
2255
-    }
2256
-
2257
-
2258
-    /**
2259
-     * @param array $event_ids
2260
-     */
2261
-    protected function generateDeletionPreview(array $event_ids)
2262
-    {
2263
-        $event_ids = $this->cleanEventIds($event_ids);
2264
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2265
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2266
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2267
-            [
2268
-                'action'            => 'preview_deletion',
2269
-                'deletion_job_code' => $deletion_job_code,
2270
-            ],
2271
-            $this->_admin_base_url
2272
-        );
2273
-        EEH_URL::safeRedirectAndExit(
2274
-            EE_Admin_Page::add_query_args_and_nonce(
2275
-                [
2276
-                    'page'              => 'espresso_batch',
2277
-                    'batch'             => EED_Batch::batch_job,
2278
-                    'EVT_IDs'           => $event_ids,
2279
-                    'deletion_job_code' => $deletion_job_code,
2280
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2281
-                    'return_url'        => urlencode($return_url),
2282
-                ],
2283
-                admin_url()
2284
-            )
2285
-        );
2286
-    }
2287
-
2288
-
2289
-    /**
2290
-     * Checks for a POST submission
2291
-     *
2292
-     * @since 4.10.12.p
2293
-     */
2294
-    protected function confirmDeletion()
2295
-    {
2296
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2297
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2298
-        );
2299
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2300
-    }
2301
-
2302
-
2303
-    /**
2304
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2305
-     *
2306
-     * @throws EE_Error
2307
-     * @since 4.10.12.p
2308
-     */
2309
-    protected function previewDeletion()
2310
-    {
2311
-        $preview_deletion_logic = $this->getLoader()->getShared(
2312
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2313
-        );
2314
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2315
-        $this->display_admin_page_with_no_sidebar();
2316
-    }
2317
-
2318
-
2319
-    /**
2320
-     * get total number of events
2321
-     *
2322
-     * @access public
2323
-     * @return int
2324
-     * @throws EE_Error
2325
-     * @throws EE_Error
2326
-     */
2327
-    public function total_events()
2328
-    {
2329
-        return EEM_Event::instance()->count(
2330
-            ['caps' => 'read_admin'],
2331
-            'EVT_ID',
2332
-            true
2333
-        );
2334
-    }
2335
-
2336
-
2337
-    /**
2338
-     * get total number of draft events
2339
-     *
2340
-     * @access public
2341
-     * @return int
2342
-     * @throws EE_Error
2343
-     * @throws EE_Error
2344
-     */
2345
-    public function total_events_draft()
2346
-    {
2347
-        return EEM_Event::instance()->count(
2348
-            [
2349
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2350
-                'caps' => 'read_admin',
2351
-            ],
2352
-            'EVT_ID',
2353
-            true
2354
-        );
2355
-    }
2356
-
2357
-
2358
-    /**
2359
-     * get total number of trashed events
2360
-     *
2361
-     * @access public
2362
-     * @return int
2363
-     * @throws EE_Error
2364
-     * @throws EE_Error
2365
-     */
2366
-    public function total_trashed_events()
2367
-    {
2368
-        return EEM_Event::instance()->count(
2369
-            [
2370
-                ['status' => 'trash'],
2371
-                'caps' => 'read_admin',
2372
-            ],
2373
-            'EVT_ID',
2374
-            true
2375
-        );
2376
-    }
2377
-
2378
-
2379
-    /**
2380
-     *    _default_event_settings
2381
-     *    This generates the Default Settings Tab
2382
-     *
2383
-     * @return void
2384
-     * @throws EE_Error
2385
-     */
2386
-    protected function _default_event_settings()
2387
-    {
2388
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2389
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2390
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2391
-        $this->display_admin_page_with_sidebar();
2392
-    }
2393
-
2394
-
2395
-    /**
2396
-     * Return the form for event settings.
2397
-     *
2398
-     * @return EE_Form_Section_Proper
2399
-     * @throws EE_Error
2400
-     */
2401
-    protected function _default_event_settings_form()
2402
-    {
2403
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2404
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2405
-        // exclude
2406
-            [
2407
-                EEM_Registration::status_id_cancelled,
2408
-                EEM_Registration::status_id_declined,
2409
-                EEM_Registration::status_id_incomplete,
2410
-                EEM_Registration::status_id_wait_list,
2411
-            ],
2412
-            true
2413
-        );
2414
-        return new EE_Form_Section_Proper(
2415
-            [
2416
-                'name'            => 'update_default_event_settings',
2417
-                'html_id'         => 'update_default_event_settings',
2418
-                'html_class'      => 'form-table',
2419
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2420
-                'subsections'     => apply_filters(
2421
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2422
-                    [
2423
-                        'default_reg_status'  => new EE_Select_Input(
2424
-                            $registration_stati_for_selection,
2425
-                            [
2426
-                                'default'         => isset($registration_config->default_STS_ID)
2427
-                                                     && array_key_exists(
2428
-                                                         $registration_config->default_STS_ID,
2429
-                                                         $registration_stati_for_selection
2430
-                                                     )
2431
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2432
-                                    : EEM_Registration::status_id_pending_payment,
2433
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2434
-                                                     . EEH_Template::get_help_tab_link(
2435
-                                                         'default_settings_status_help_tab'
2436
-                                                     ),
2437
-                                'html_help_text'  => esc_html__(
2438
-                                    '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.',
2439
-                                    'event_espresso'
2440
-                                ),
2441
-                            ]
2442
-                        ),
2443
-                        'default_max_tickets' => new EE_Integer_Input(
2444
-                            [
2445
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2446
-                                    ? $registration_config->default_maximum_number_of_tickets
2447
-                                    : EEM_Event::get_default_additional_limit(),
2448
-                                'html_label_text' => esc_html__(
2449
-                                    'Default Maximum Tickets Allowed Per Order:',
2450
-                                    'event_espresso'
2451
-                                )
2452
-                                . EEH_Template::get_help_tab_link(
2453
-                                    'default_maximum_tickets_help_tab"'
2454
-                                ),
2455
-                                'html_help_text'  => esc_html__(
2456
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2457
-                                    'event_espresso'
2458
-                                ),
2459
-                            ]
2460
-                        ),
2461
-                    ]
2462
-                ),
2463
-            ]
2464
-        );
2465
-    }
2466
-
2467
-
2468
-    /**
2469
-     * _update_default_event_settings
2470
-     *
2471
-     * @access protected
2472
-     * @return void
2473
-     * @throws EE_Error
2474
-     */
2475
-    protected function _update_default_event_settings()
2476
-    {
2477
-        $registration_config = EE_Registry::instance()->CFG->registration;
2478
-        $form                = $this->_default_event_settings_form();
2479
-        if ($form->was_submitted()) {
2480
-            $form->receive_form_submission();
2481
-            if ($form->is_valid()) {
2482
-                $valid_data = $form->valid_data();
2483
-                if (isset($valid_data['default_reg_status'])) {
2484
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2485
-                }
2486
-                if (isset($valid_data['default_max_tickets'])) {
2487
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2488
-                }
2489
-                // update because data was valid!
2490
-                EE_Registry::instance()->CFG->update_espresso_config();
2491
-                EE_Error::overwrite_success();
2492
-                EE_Error::add_success(
2493
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2494
-                );
2495
-            }
2496
-        }
2497
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2498
-    }
2499
-
2500
-
2501
-    /*************        Templates        *************
2502
-     *
2503
-     * @throws EE_Error
2504
-     */
2505
-    protected function _template_settings()
2506
-    {
2507
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2508
-        $this->_template_args['preview_img']  = '<img src="'
2509
-                                                . EVENTS_ASSETS_URL
2510
-                                                . '/images/'
2511
-                                                . 'caffeinated_template_features.jpg" alt="'
2512
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2513
-                                                . '" />';
2514
-        $this->_template_args['preview_text'] = '<strong>'
2515
-                                                . esc_html__(
2516
-                                                    '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.',
2517
-                                                    'event_espresso'
2518
-                                                ) . '</strong>';
2519
-        $this->display_admin_caf_preview_page('template_settings_tab');
2520
-    }
2521
-
2522
-
2523
-    /** Event Category Stuff **/
2524
-    /**
2525
-     * set the _category property with the category object for the loaded page.
2526
-     *
2527
-     * @access private
2528
-     * @return void
2529
-     */
2530
-    private function _set_category_object()
2531
-    {
2532
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2533
-            return;
2534
-        } //already have the category object so get out.
2535
-        // set default category object
2536
-        $this->_set_empty_category_object();
2537
-        // only set if we've got an id
2538
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2539
-        if (! $category_ID) {
2540
-            return;
2541
-        }
2542
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2543
-        if (! empty($term)) {
2544
-            $this->_category->category_name       = $term->name;
2545
-            $this->_category->category_identifier = $term->slug;
2546
-            $this->_category->category_desc       = $term->description;
2547
-            $this->_category->id                  = $term->term_id;
2548
-            $this->_category->parent              = $term->parent;
2549
-        }
2550
-    }
2551
-
2552
-
2553
-    /**
2554
-     * Clears out category properties.
2555
-     */
2556
-    private function _set_empty_category_object()
2557
-    {
2558
-        $this->_category                = new stdClass();
2559
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2560
-        $this->_category->id            = $this->_category->parent = 0;
2561
-    }
2562
-
2563
-
2564
-    /**
2565
-     * @throws EE_Error
2566
-     */
2567
-    protected function _category_list_table()
2568
-    {
2569
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2570
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2571
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2572
-            'add_category',
2573
-            'add_category',
2574
-            [],
2575
-            'add-new-h2'
2576
-        );
2577
-        $this->display_admin_list_table_page_with_sidebar();
2578
-    }
2579
-
2580
-
2581
-    /**
2582
-     * Output category details view.
2583
-     *
2584
-     * @throws EE_Error
2585
-     * @throws EE_Error
2586
-     */
2587
-    protected function _category_details($view)
2588
-    {
2589
-        // load formatter helper
2590
-        // load field generator helper
2591
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
2592
-        $this->_set_add_edit_form_tags($route);
2593
-        $this->_set_category_object();
2594
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2595
-        $delete_action = 'delete_category';
2596
-        // custom redirect
2597
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2598
-            ['action' => 'category_list'],
2599
-            $this->_admin_base_url
2600
-        );
2601
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2602
-        // take care of contents
2603
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2604
-        $this->display_admin_page_with_sidebar();
2605
-    }
2606
-
2607
-
2608
-    /**
2609
-     * Output category details content.
2610
-     */
2611
-    protected function _category_details_content()
2612
-    {
2613
-        $editor_args['category_desc'] = [
2614
-            'type'          => 'wp_editor',
2615
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2616
-            'class'         => 'my_editor_custom',
2617
-            'wpeditor_args' => ['media_buttons' => false],
2618
-        ];
2619
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2620
-        $all_terms                    = get_terms(
2621
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2622
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2623
-        );
2624
-        // setup category select for term parents.
2625
-        $category_select_values[] = [
2626
-            'text' => esc_html__('No Parent', 'event_espresso'),
2627
-            'id'   => 0,
2628
-        ];
2629
-        foreach ($all_terms as $term) {
2630
-            $category_select_values[] = [
2631
-                'text' => $term->name,
2632
-                'id'   => $term->term_id,
2633
-            ];
2634
-        }
2635
-        $category_select = EEH_Form_Fields::select_input(
2636
-            'category_parent',
2637
-            $category_select_values,
2638
-            $this->_category->parent
2639
-        );
2640
-        $template_args   = [
2641
-            'category'                 => $this->_category,
2642
-            'category_select'          => $category_select,
2643
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2644
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2645
-            'disable'                  => '',
2646
-            'disabled_message'         => false,
2647
-        ];
2648
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2649
-        return EEH_Template::display_template($template, $template_args, true);
2650
-    }
2651
-
2652
-
2653
-    /**
2654
-     * Handles deleting categories.
2655
-     *
2656
-     * @throws EE_Error
2657
-     */
2658
-    protected function _delete_categories()
2659
-    {
2660
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2661
-        foreach ($category_IDs as $category_ID) {
2662
-            $this->_delete_category($category_ID);
2663
-        }
2664
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2665
-        $query_args = [
2666
-            'action' => 'category_list',
2667
-        ];
2668
-        $this->_redirect_after_action(0, '', '', $query_args);
2669
-    }
2670
-
2671
-
2672
-    /**
2673
-     * Handles deleting specific category.
2674
-     *
2675
-     * @param int $cat_id
2676
-     */
2677
-    protected function _delete_category($cat_id)
2678
-    {
2679
-        $cat_id = absint($cat_id);
2680
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2681
-    }
2682
-
2683
-
2684
-    /**
2685
-     * Handles triggering the update or insertion of a new category.
2686
-     *
2687
-     * @param bool $new_category true means we're triggering the insert of a new category.
2688
-     * @throws EE_Error
2689
-     * @throws EE_Error
2690
-     */
2691
-    protected function _insert_or_update_category($new_category)
2692
-    {
2693
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2694
-        $success = 0; // we already have a success message so lets not send another.
2695
-        if ($cat_id) {
2696
-            $query_args = [
2697
-                'action'     => 'edit_category',
2698
-                'EVT_CAT_ID' => $cat_id,
2699
-            ];
2700
-        } else {
2701
-            $query_args = ['action' => 'add_category'];
2702
-        }
2703
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2704
-    }
2705
-
2706
-
2707
-    /**
2708
-     * Inserts or updates category
2709
-     *
2710
-     * @param bool $update (true indicates we're updating a category).
2711
-     * @return bool|mixed|string
2712
-     */
2713
-    private function _insert_category($update = false)
2714
-    {
2715
-        $category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2716
-        $category_name       = $this->request->getRequestParam('category_name', '');
2717
-        $category_desc       = $this->request->getRequestParam('category_desc', '');
2718
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2719
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2720
-
2721
-        if (empty($category_name)) {
2722
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2723
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2724
-            return false;
2725
-        }
2726
-        $term_args = [
2727
-            'name'        => $category_name,
2728
-            'description' => $category_desc,
2729
-            'parent'      => $category_parent,
2730
-        ];
2731
-        // was the category_identifier input disabled?
2732
-        if ($category_identifier) {
2733
-            $term_args['slug'] = $category_identifier;
2734
-        }
2735
-        $insert_ids = $update
2736
-            ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2737
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2738
-        if (! is_array($insert_ids)) {
2739
-            $msg = esc_html__(
2740
-                'An error occurred and the category has not been saved to the database.',
2741
-                'event_espresso'
2742
-            );
2743
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2744
-        } else {
2745
-            $category_ID = $insert_ids['term_id'];
2746
-            $msg         =
2747
-                sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2748
-            EE_Error::add_success($msg);
2749
-        }
2750
-        return $category_ID;
2751
-    }
2752
-
2753
-
2754
-    /**
2755
-     * Gets categories or count of categories matching the arguments in the request.
2756
-     *
2757
-     * @param int  $per_page
2758
-     * @param int  $current_page
2759
-     * @param bool $count
2760
-     * @return EE_Term_Taxonomy[]|int
2761
-     * @throws EE_Error
2762
-     * @throws EE_Error
2763
-     */
2764
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2765
-    {
2766
-        // testing term stuff
2767
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2768
-        $order       = $this->request->getRequestParam('order', 'DESC');
2769
-        $limit       = ($current_page - 1) * $per_page;
2770
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2771
-        $search_term = $this->request->getRequestParam('s');
2772
-        if ($search_term) {
2773
-            $search_term = '%' . $search_term . '%';
2774
-            $where['OR'] = [
2775
-                'Term.name'   => ['LIKE', $search_term],
2776
-                'description' => ['LIKE', $search_term],
2777
-            ];
2778
-        }
2779
-        $query_params = [
2780
-            $where,
2781
-            'order_by'   => [$orderby => $order],
2782
-            'limit'      => $limit . ',' . $per_page,
2783
-            'force_join' => ['Term'],
2784
-        ];
2785
-        return $count
2786
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2787
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2788
-    }
2789
-
2790
-    /* end category stuff */
2791
-    /**************/
2792
-
2793
-
2794
-    /**
2795
-     * Callback for the `ee_save_timezone_setting` ajax action.
2796
-     *
2797
-     * @throws EE_Error
2798
-     */
2799
-    public function saveTimezoneString()
2800
-    {
2801
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2802
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2803
-            EE_Error::add_error(
2804
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2805
-                __FILE__,
2806
-                __FUNCTION__,
2807
-                __LINE__
2808
-            );
2809
-            $this->_template_args['error'] = true;
2810
-            $this->_return_json();
2811
-        }
2812
-
2813
-        update_option('timezone_string', $timezone_string);
2814
-        EE_Error::add_success(
2815
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2816
-        );
2817
-        $this->_template_args['success'] = true;
2818
-        $this->_return_json(true, ['action' => 'create_new']);
2819
-    }
2820
-
2821
-
2822
-    /**
2823 2503
      * @throws EE_Error
2824
-     * @deprecated 4.10.25.p
2825 2504
      */
2826
-    public function save_timezonestring_setting()
2827
-    {
2828
-        $this->saveTimezoneString();
2829
-    }
2505
+	protected function _template_settings()
2506
+	{
2507
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2508
+		$this->_template_args['preview_img']  = '<img src="'
2509
+												. EVENTS_ASSETS_URL
2510
+												. '/images/'
2511
+												. 'caffeinated_template_features.jpg" alt="'
2512
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2513
+												. '" />';
2514
+		$this->_template_args['preview_text'] = '<strong>'
2515
+												. esc_html__(
2516
+													'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.',
2517
+													'event_espresso'
2518
+												) . '</strong>';
2519
+		$this->display_admin_caf_preview_page('template_settings_tab');
2520
+	}
2521
+
2522
+
2523
+	/** Event Category Stuff **/
2524
+	/**
2525
+	 * set the _category property with the category object for the loaded page.
2526
+	 *
2527
+	 * @access private
2528
+	 * @return void
2529
+	 */
2530
+	private function _set_category_object()
2531
+	{
2532
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2533
+			return;
2534
+		} //already have the category object so get out.
2535
+		// set default category object
2536
+		$this->_set_empty_category_object();
2537
+		// only set if we've got an id
2538
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2539
+		if (! $category_ID) {
2540
+			return;
2541
+		}
2542
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2543
+		if (! empty($term)) {
2544
+			$this->_category->category_name       = $term->name;
2545
+			$this->_category->category_identifier = $term->slug;
2546
+			$this->_category->category_desc       = $term->description;
2547
+			$this->_category->id                  = $term->term_id;
2548
+			$this->_category->parent              = $term->parent;
2549
+		}
2550
+	}
2551
+
2552
+
2553
+	/**
2554
+	 * Clears out category properties.
2555
+	 */
2556
+	private function _set_empty_category_object()
2557
+	{
2558
+		$this->_category                = new stdClass();
2559
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2560
+		$this->_category->id            = $this->_category->parent = 0;
2561
+	}
2562
+
2563
+
2564
+	/**
2565
+	 * @throws EE_Error
2566
+	 */
2567
+	protected function _category_list_table()
2568
+	{
2569
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2570
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2571
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2572
+			'add_category',
2573
+			'add_category',
2574
+			[],
2575
+			'add-new-h2'
2576
+		);
2577
+		$this->display_admin_list_table_page_with_sidebar();
2578
+	}
2579
+
2580
+
2581
+	/**
2582
+	 * Output category details view.
2583
+	 *
2584
+	 * @throws EE_Error
2585
+	 * @throws EE_Error
2586
+	 */
2587
+	protected function _category_details($view)
2588
+	{
2589
+		// load formatter helper
2590
+		// load field generator helper
2591
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
2592
+		$this->_set_add_edit_form_tags($route);
2593
+		$this->_set_category_object();
2594
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2595
+		$delete_action = 'delete_category';
2596
+		// custom redirect
2597
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2598
+			['action' => 'category_list'],
2599
+			$this->_admin_base_url
2600
+		);
2601
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2602
+		// take care of contents
2603
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2604
+		$this->display_admin_page_with_sidebar();
2605
+	}
2606
+
2607
+
2608
+	/**
2609
+	 * Output category details content.
2610
+	 */
2611
+	protected function _category_details_content()
2612
+	{
2613
+		$editor_args['category_desc'] = [
2614
+			'type'          => 'wp_editor',
2615
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2616
+			'class'         => 'my_editor_custom',
2617
+			'wpeditor_args' => ['media_buttons' => false],
2618
+		];
2619
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2620
+		$all_terms                    = get_terms(
2621
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2622
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2623
+		);
2624
+		// setup category select for term parents.
2625
+		$category_select_values[] = [
2626
+			'text' => esc_html__('No Parent', 'event_espresso'),
2627
+			'id'   => 0,
2628
+		];
2629
+		foreach ($all_terms as $term) {
2630
+			$category_select_values[] = [
2631
+				'text' => $term->name,
2632
+				'id'   => $term->term_id,
2633
+			];
2634
+		}
2635
+		$category_select = EEH_Form_Fields::select_input(
2636
+			'category_parent',
2637
+			$category_select_values,
2638
+			$this->_category->parent
2639
+		);
2640
+		$template_args   = [
2641
+			'category'                 => $this->_category,
2642
+			'category_select'          => $category_select,
2643
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2644
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2645
+			'disable'                  => '',
2646
+			'disabled_message'         => false,
2647
+		];
2648
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2649
+		return EEH_Template::display_template($template, $template_args, true);
2650
+	}
2651
+
2652
+
2653
+	/**
2654
+	 * Handles deleting categories.
2655
+	 *
2656
+	 * @throws EE_Error
2657
+	 */
2658
+	protected function _delete_categories()
2659
+	{
2660
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2661
+		foreach ($category_IDs as $category_ID) {
2662
+			$this->_delete_category($category_ID);
2663
+		}
2664
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2665
+		$query_args = [
2666
+			'action' => 'category_list',
2667
+		];
2668
+		$this->_redirect_after_action(0, '', '', $query_args);
2669
+	}
2670
+
2671
+
2672
+	/**
2673
+	 * Handles deleting specific category.
2674
+	 *
2675
+	 * @param int $cat_id
2676
+	 */
2677
+	protected function _delete_category($cat_id)
2678
+	{
2679
+		$cat_id = absint($cat_id);
2680
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2681
+	}
2682
+
2683
+
2684
+	/**
2685
+	 * Handles triggering the update or insertion of a new category.
2686
+	 *
2687
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2688
+	 * @throws EE_Error
2689
+	 * @throws EE_Error
2690
+	 */
2691
+	protected function _insert_or_update_category($new_category)
2692
+	{
2693
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2694
+		$success = 0; // we already have a success message so lets not send another.
2695
+		if ($cat_id) {
2696
+			$query_args = [
2697
+				'action'     => 'edit_category',
2698
+				'EVT_CAT_ID' => $cat_id,
2699
+			];
2700
+		} else {
2701
+			$query_args = ['action' => 'add_category'];
2702
+		}
2703
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2704
+	}
2705
+
2706
+
2707
+	/**
2708
+	 * Inserts or updates category
2709
+	 *
2710
+	 * @param bool $update (true indicates we're updating a category).
2711
+	 * @return bool|mixed|string
2712
+	 */
2713
+	private function _insert_category($update = false)
2714
+	{
2715
+		$category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2716
+		$category_name       = $this->request->getRequestParam('category_name', '');
2717
+		$category_desc       = $this->request->getRequestParam('category_desc', '');
2718
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2719
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2720
+
2721
+		if (empty($category_name)) {
2722
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2723
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2724
+			return false;
2725
+		}
2726
+		$term_args = [
2727
+			'name'        => $category_name,
2728
+			'description' => $category_desc,
2729
+			'parent'      => $category_parent,
2730
+		];
2731
+		// was the category_identifier input disabled?
2732
+		if ($category_identifier) {
2733
+			$term_args['slug'] = $category_identifier;
2734
+		}
2735
+		$insert_ids = $update
2736
+			? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2737
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2738
+		if (! is_array($insert_ids)) {
2739
+			$msg = esc_html__(
2740
+				'An error occurred and the category has not been saved to the database.',
2741
+				'event_espresso'
2742
+			);
2743
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2744
+		} else {
2745
+			$category_ID = $insert_ids['term_id'];
2746
+			$msg         =
2747
+				sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2748
+			EE_Error::add_success($msg);
2749
+		}
2750
+		return $category_ID;
2751
+	}
2752
+
2753
+
2754
+	/**
2755
+	 * Gets categories or count of categories matching the arguments in the request.
2756
+	 *
2757
+	 * @param int  $per_page
2758
+	 * @param int  $current_page
2759
+	 * @param bool $count
2760
+	 * @return EE_Term_Taxonomy[]|int
2761
+	 * @throws EE_Error
2762
+	 * @throws EE_Error
2763
+	 */
2764
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2765
+	{
2766
+		// testing term stuff
2767
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2768
+		$order       = $this->request->getRequestParam('order', 'DESC');
2769
+		$limit       = ($current_page - 1) * $per_page;
2770
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2771
+		$search_term = $this->request->getRequestParam('s');
2772
+		if ($search_term) {
2773
+			$search_term = '%' . $search_term . '%';
2774
+			$where['OR'] = [
2775
+				'Term.name'   => ['LIKE', $search_term],
2776
+				'description' => ['LIKE', $search_term],
2777
+			];
2778
+		}
2779
+		$query_params = [
2780
+			$where,
2781
+			'order_by'   => [$orderby => $order],
2782
+			'limit'      => $limit . ',' . $per_page,
2783
+			'force_join' => ['Term'],
2784
+		];
2785
+		return $count
2786
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2787
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2788
+	}
2789
+
2790
+	/* end category stuff */
2791
+	/**************/
2792
+
2793
+
2794
+	/**
2795
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2796
+	 *
2797
+	 * @throws EE_Error
2798
+	 */
2799
+	public function saveTimezoneString()
2800
+	{
2801
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2802
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2803
+			EE_Error::add_error(
2804
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2805
+				__FILE__,
2806
+				__FUNCTION__,
2807
+				__LINE__
2808
+			);
2809
+			$this->_template_args['error'] = true;
2810
+			$this->_return_json();
2811
+		}
2812
+
2813
+		update_option('timezone_string', $timezone_string);
2814
+		EE_Error::add_success(
2815
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2816
+		);
2817
+		$this->_template_args['success'] = true;
2818
+		$this->_return_json(true, ['action' => 'create_new']);
2819
+	}
2820
+
2821
+
2822
+	/**
2823
+	 * @throws EE_Error
2824
+	 * @deprecated 4.10.25.p
2825
+	 */
2826
+	public function save_timezonestring_setting()
2827
+	{
2828
+		$this->saveTimezoneString();
2829
+	}
2830 2830
 }
Please login to merge, or discard this patch.
Spacing   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -561,11 +561,11 @@  discard block
 block discarded – undo
561 561
     {
562 562
         wp_register_style(
563 563
             'events-admin-css',
564
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
564
+            EVENTS_ASSETS_URL.'events-admin-page.css',
565 565
             [],
566 566
             EVENT_ESPRESSO_VERSION
567 567
         );
568
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
568
+        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
569 569
         wp_enqueue_style('events-admin-css');
570 570
         wp_enqueue_style('ee-cat-admin');
571 571
         // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
@@ -573,7 +573,7 @@  discard block
 block discarded – undo
573 573
         // scripts
574 574
         wp_register_script(
575 575
             'event_editor_js',
576
-            EVENTS_ASSETS_URL . 'event_editor.js',
576
+            EVENTS_ASSETS_URL.'event_editor.js',
577 577
             ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
578 578
             EVENT_ESPRESSO_VERSION,
579 579
             true
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
         wp_enqueue_style('espresso-ui-theme');
600 600
         wp_register_style(
601 601
             'event-editor-css',
602
-            EVENTS_ASSETS_URL . 'event-editor.css',
602
+            EVENTS_ASSETS_URL.'event-editor.css',
603 603
             ['ee-admin-css'],
604 604
             EVENT_ESPRESSO_VERSION
605 605
         );
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
         // scripts
608 608
         wp_register_script(
609 609
             'event-datetime-metabox',
610
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
610
+            EVENTS_ASSETS_URL.'event-datetime-metabox.js',
611 611
             ['event_editor_js', 'ee-datepicker'],
612 612
             EVENT_ESPRESSO_VERSION
613 613
         );
@@ -676,7 +676,7 @@  discard block
 block discarded – undo
676 676
     public function verify_event_edit($event = null, $req_type = '')
677 677
     {
678 678
         // don't need to do this when processing
679
-        if (! empty($req_type)) {
679
+        if ( ! empty($req_type)) {
680 680
             return;
681 681
         }
682 682
         // no event?
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
             $event = $this->_cpt_model_obj;
686 686
         }
687 687
         // STILL no event?
688
-        if (! $event instanceof EE_Event) {
688
+        if ( ! $event instanceof EE_Event) {
689 689
             return;
690 690
         }
691 691
         $orig_status = $event->status();
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
             );
725 725
         }
726 726
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
727
-        if (! $event->tickets_on_sale()) {
727
+        if ( ! $event->tickets_on_sale()) {
728 728
             return;
729 729
         }
730 730
         // made it here so show warning
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
     {
770 770
         $has_timezone_string = get_option('timezone_string');
771 771
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
772
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
772
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
773 773
             EE_Error::add_attention(
774 774
                 sprintf(
775 775
                     esc_html__(
@@ -838,7 +838,7 @@  discard block
 block discarded – undo
838 838
      */
839 839
     protected function _event_legend_items()
840 840
     {
841
-        $items    = [
841
+        $items = [
842 842
             'view_details'   => [
843 843
                 'class' => 'dashicons dashicons-search',
844 844
                 'desc'  => esc_html__('View Event', 'event_espresso'),
@@ -855,31 +855,31 @@  discard block
 block discarded – undo
855 855
         $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856 856
         $statuses = [
857 857
             'sold_out_status'  => [
858
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
858
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::sold_out,
859 859
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860 860
             ],
861 861
             'active_status'    => [
862
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
862
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::active,
863 863
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864 864
             ],
865 865
             'upcoming_status'  => [
866
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
866
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::upcoming,
867 867
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868 868
             ],
869 869
             'postponed_status' => [
870
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
870
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::postponed,
871 871
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872 872
             ],
873 873
             'cancelled_status' => [
874
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
874
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::cancelled,
875 875
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876 876
             ],
877 877
             'expired_status'   => [
878
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
878
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::expired,
879 879
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880 880
             ],
881 881
             'inactive_status'  => [
882
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
882
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::inactive,
883 883
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884 884
             ],
885 885
         ];
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
      */
896 896
     private function _event_model()
897 897
     {
898
-        if (! $this->_event_model instanceof EEM_Event) {
898
+        if ( ! $this->_event_model instanceof EEM_Event) {
899 899
             $this->_event_model = EE_Registry::instance()->load_model('Event');
900 900
         }
901 901
         return $this->_event_model;
@@ -915,8 +915,8 @@  discard block
 block discarded – undo
915 915
     public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
916 916
     {
917 917
         // make sure this is only when editing
918
-        if (! empty($id)) {
919
-            $post   = get_post($id);
918
+        if ( ! empty($id)) {
919
+            $post = get_post($id);
920 920
             $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
921 921
                        . esc_html__('Shortcode', 'event_espresso')
922 922
                        . '</a> ';
@@ -939,7 +939,7 @@  discard block
 block discarded – undo
939 939
     protected function _events_overview_list_table()
940 940
     {
941 941
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
942
-        $this->_template_args['after_list_table']                           =
942
+        $this->_template_args['after_list_table'] =
943 943
             ! empty($this->_template_args['after_list_table'])
944 944
                 ? (array) $this->_template_args['after_list_table']
945 945
                 : [];
@@ -949,10 +949,10 @@  discard block
 block discarded – undo
949 949
                 esc_html__("View Event Archive Page", "event_espresso"),
950 950
                 'button'
951 951
             );
952
-        $this->_template_args['after_list_table']['legend']                 = $this->_display_legend(
952
+        $this->_template_args['after_list_table']['legend'] = $this->_display_legend(
953 953
             $this->_event_legend_items()
954 954
         );
955
-        $this->_admin_page_title                                            .= ' ' . $this->get_action_link_or_button(
955
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
956 956
             'create_new',
957 957
             'add',
958 958
             [],
@@ -1048,7 +1048,7 @@  discard block
 block discarded – undo
1048 1048
                 [$this, '_default_tickets_update'],
1049 1049
             ]
1050 1050
         );
1051
-        $att_success            = true;
1051
+        $att_success = true;
1052 1052
         foreach ($event_update_callbacks as $e_callback) {
1053 1053
             $_success = is_callable($e_callback)
1054 1054
                 ? call_user_func($e_callback, $event, $this->request->requestParams())
@@ -1110,7 +1110,7 @@  discard block
 block discarded – undo
1110 1110
      */
1111 1111
     protected function _default_venue_update(EE_Event $event, $data)
1112 1112
     {
1113
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1113
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1114 1114
         $venue_model = EE_Registry::instance()->load_model('Venue');
1115 1115
         $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1116 1116
         // very important.  If we don't have a venue name...
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
             'status'              => 'publish',
1142 1142
         ];
1143 1143
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1144
-        if (! empty($venue_id)) {
1144
+        if ( ! empty($venue_id)) {
1145 1145
             $update_where  = [$venue_model->primary_key_name() => $venue_id];
1146 1146
             $rows_affected = $venue_model->update($venue_array, [$update_where]);
1147 1147
             // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
@@ -1179,7 +1179,7 @@  discard block
 block discarded – undo
1179 1179
                 isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1180 1180
                     ? $datetime_data['DTT_EVT_end']
1181 1181
                     : $datetime_data['DTT_EVT_start'];
1182
-            $datetime_values              = [
1182
+            $datetime_values = [
1183 1183
                 'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1184 1184
                 'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1185 1185
                 'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
@@ -1188,9 +1188,9 @@  discard block
 block discarded – undo
1188 1188
             ];
1189 1189
             // if we have an id then let's get existing object first and then set the new values.
1190 1190
             //  Otherwise we instantiate a new object for save.
1191
-            if (! empty($datetime_data['DTT_ID'])) {
1191
+            if ( ! empty($datetime_data['DTT_ID'])) {
1192 1192
                 $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1193
-                if (! $datetime instanceof EE_Datetime) {
1193
+                if ( ! $datetime instanceof EE_Datetime) {
1194 1194
                     throw new RuntimeException(
1195 1195
                         sprintf(
1196 1196
                             esc_html__(
@@ -1209,7 +1209,7 @@  discard block
 block discarded – undo
1209 1209
             } else {
1210 1210
                 $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1211 1211
             }
1212
-            if (! $datetime instanceof EE_Datetime) {
1212
+            if ( ! $datetime instanceof EE_Datetime) {
1213 1213
                 throw new RuntimeException(
1214 1214
                     sprintf(
1215 1215
                         esc_html__(
@@ -1235,7 +1235,7 @@  discard block
 block discarded – undo
1235 1235
 
1236 1236
         // set up some default start and end dates in case those are not present in the incoming data
1237 1237
         $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1238
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1238
+        $default_start_date = $default_start_date->format($date_formats[0].' '.$date_formats[1]);
1239 1239
         // use the start date of the first datetime for the end date
1240 1240
         $first_datetime   = $event->first_datetime();
1241 1241
         $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
@@ -1243,8 +1243,8 @@  discard block
 block discarded – undo
1243 1243
         // now process the incoming data
1244 1244
         foreach ($data['edit_tickets'] as $row => $ticket_data) {
1245 1245
             $update_prices = false;
1246
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1247
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1246
+            $ticket_price  = isset($data['edit_prices'][$row][1]['PRC_amount'])
1247
+                ? $data['edit_prices'][$row][1]['PRC_amount']
1248 1248
                 : 0;
1249 1249
             // trim inputs to ensure any excess whitespace is removed.
1250 1250
             $ticket_data   = array_map('trim', $ticket_data);
@@ -1285,9 +1285,9 @@  discard block
 block discarded – undo
1285 1285
             // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1286 1286
             // keep in mind that if the ticket has been sold (and we have changed pricing information),
1287 1287
             // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1288
-            if (! empty($ticket_data['TKT_ID'])) {
1288
+            if ( ! empty($ticket_data['TKT_ID'])) {
1289 1289
                 $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1290
-                if (! $existing_ticket instanceof EE_Ticket) {
1290
+                if ( ! $existing_ticket instanceof EE_Ticket) {
1291 1291
                     throw new RuntimeException(
1292 1292
                         sprintf(
1293 1293
                             esc_html__(
@@ -1336,7 +1336,7 @@  discard block
 block discarded – undo
1336 1336
                     $existing_ticket->save();
1337 1337
                     // make sure this ticket is still recorded in our $saved_tickets
1338 1338
                     // so we don't run it through the regular trash routine.
1339
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1339
+                    $saved_tickets[$existing_ticket->ID()] = $existing_ticket;
1340 1340
                     // create new ticket that's a copy of the existing except,
1341 1341
                     // (a new id of course and not archived) AND has the new TKT_price associated with it.
1342 1342
                     $new_ticket = clone $existing_ticket;
@@ -1353,7 +1353,7 @@  discard block
 block discarded – undo
1353 1353
                 $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1354 1354
                 $update_prices              = true;
1355 1355
             }
1356
-            if (! $ticket instanceof EE_Ticket) {
1356
+            if ( ! $ticket instanceof EE_Ticket) {
1357 1357
                 throw new RuntimeException(
1358 1358
                     sprintf(
1359 1359
                         esc_html__(
@@ -1377,10 +1377,10 @@  discard block
 block discarded – undo
1377 1377
             }
1378 1378
             // initially let's add the ticket to the datetime
1379 1379
             $datetime->_add_relation_to($ticket, 'Ticket');
1380
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1380
+            $saved_tickets[$ticket->ID()] = $ticket;
1381 1381
             // add prices to ticket
1382
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1383
-                ? $data['edit_prices'][ $row ]
1382
+            $prices_data = isset($data['edit_prices'][$row]) && is_array($data['edit_prices'][$row])
1383
+                ? $data['edit_prices'][$row]
1384 1384
                 : [];
1385 1385
             $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1386 1386
         }
@@ -1394,7 +1394,7 @@  discard block
 block discarded – undo
1394 1394
             $id = absint($id);
1395 1395
             // get the ticket for this id
1396 1396
             $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1397
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1397
+            if ( ! $ticket_to_remove instanceof EE_Ticket) {
1398 1398
                 continue;
1399 1399
             }
1400 1400
             // need to get all the related datetimes on this ticket and remove from every single one of them
@@ -1451,7 +1451,7 @@  discard block
 block discarded – undo
1451 1451
                     $price->set($field, $new_price);
1452 1452
                 }
1453 1453
             }
1454
-            if (! $price instanceof EE_Price) {
1454
+            if ( ! $price instanceof EE_Price) {
1455 1455
                 throw new RuntimeException(
1456 1456
                     sprintf(
1457 1457
                         esc_html__(
@@ -1494,13 +1494,13 @@  discard block
 block discarded – undo
1494 1494
     {
1495 1495
         // load formatter helper
1496 1496
         // args for getting related registrations
1497
-        $approved_query_args        = [
1497
+        $approved_query_args = [
1498 1498
             [
1499 1499
                 'REG_deleted' => 0,
1500 1500
                 'STS_ID'      => EEM_Registration::status_id_approved,
1501 1501
             ],
1502 1502
         ];
1503
-        $not_approved_query_args    = [
1503
+        $not_approved_query_args = [
1504 1504
             [
1505 1505
                 'REG_deleted' => 0,
1506 1506
                 'STS_ID'      => EEM_Registration::status_id_not_approved,
@@ -1566,7 +1566,7 @@  discard block
 block discarded – undo
1566 1566
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1567 1567
         // load template
1568 1568
         EEH_Template::display_template(
1569
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1569
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1570 1570
             $publish_box_extra_args
1571 1571
         );
1572 1572
     }
@@ -1632,7 +1632,7 @@  discard block
 block discarded – undo
1632 1632
             'trash_icon'               => 'ee-lock-icon',
1633 1633
             'disabled'                 => '',
1634 1634
         ];
1635
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1635
+        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1636 1636
         /**
1637 1637
          * 1. Start with retrieving Datetimes
1638 1638
          * 2. Fore each datetime get related tickets
@@ -1653,17 +1653,17 @@  discard block
 block discarded – undo
1653 1653
                     'default_where_conditions' => 'none',
1654 1654
                 ]
1655 1655
             );
1656
-            if (! empty($related_tickets)) {
1656
+            if ( ! empty($related_tickets)) {
1657 1657
                 $template_args['total_ticket_rows'] = count($related_tickets);
1658 1658
                 $row                                = 0;
1659 1659
                 foreach ($related_tickets as $ticket) {
1660
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1660
+                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1661 1661
                     $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1662 1662
                     $row++;
1663 1663
                 }
1664 1664
             } else {
1665 1665
                 $template_args['total_ticket_rows'] = 1;
1666
-                $ticket                       = EEM_Ticket::instance()->create_default_object();
1666
+                $ticket = EEM_Ticket::instance()->create_default_object();
1667 1667
                 $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1668 1668
             }
1669 1669
         } else {
@@ -1683,9 +1683,9 @@  discard block
 block discarded – undo
1683 1683
             EEM_Ticket::instance()->create_default_object(),
1684 1684
             true
1685 1685
         );
1686
-        $template                                  = apply_filters(
1686
+        $template = apply_filters(
1687 1687
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1688
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1688
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1689 1689
         );
1690 1690
         EEH_Template::display_template($template, $template_args);
1691 1691
     }
@@ -1705,7 +1705,7 @@  discard block
 block discarded – undo
1705 1705
     private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1706 1706
     {
1707 1707
         $template_args = [
1708
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1708
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1709 1709
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1710 1710
                 : '',
1711 1711
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1717,10 +1717,10 @@  discard block
 block discarded – undo
1717 1717
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1718 1718
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1719 1719
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1720
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1721
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1720
+            'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1721
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1722 1722
                 ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1723
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1723
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1724 1724
                 : ' disabled=disabled',
1725 1725
         ];
1726 1726
         $price         = $ticket->ID() !== 0
@@ -1744,7 +1744,7 @@  discard block
 block discarded – undo
1744 1744
         }
1745 1745
         if (empty($template_args['TKT_end_date'])) {
1746 1746
             // get the earliest datetime (if present);
1747
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1747
+            $earliest_datetime = $this->_cpt_model_obj->ID() > 0
1748 1748
                 ? $this->_cpt_model_obj->get_first_related(
1749 1749
                     'Datetime',
1750 1750
                     ['order_by' => ['DTT_EVT_start' => 'ASC']]
@@ -1757,7 +1757,7 @@  discard block
 block discarded – undo
1757 1757
         $template_args = array_merge($template_args, $price_args);
1758 1758
         $template      = apply_filters(
1759 1759
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1760
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1760
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1761 1761
             $ticket
1762 1762
         );
1763 1763
         return EEH_Template::display_template($template, $template_args, true);
@@ -1770,7 +1770,7 @@  discard block
 block discarded – undo
1770 1770
      */
1771 1771
     public function registration_options_meta_box()
1772 1772
     {
1773
-        $yes_no_values             = [
1773
+        $yes_no_values = [
1774 1774
             ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1775 1775
             ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1776 1776
         ];
@@ -1792,12 +1792,12 @@  discard block
 block discarded – undo
1792 1792
             $default_reg_status_values,
1793 1793
             $this->_cpt_model_obj->default_registration_status()
1794 1794
         );
1795
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1795
+        $template_args['display_description'] = EEH_Form_Fields::select_input(
1796 1796
             'display_desc',
1797 1797
             $yes_no_values,
1798 1798
             $this->_cpt_model_obj->display_description()
1799 1799
         );
1800
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1800
+        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1801 1801
             'display_ticket_selector',
1802 1802
             $yes_no_values,
1803 1803
             $this->_cpt_model_obj->display_ticket_selector(),
@@ -1813,7 +1813,7 @@  discard block
 block discarded – undo
1813 1813
             $default_reg_status_values
1814 1814
         );
1815 1815
         EEH_Template::display_template(
1816
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1816
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1817 1817
             $template_args
1818 1818
         );
1819 1819
     }
@@ -1836,7 +1836,7 @@  discard block
 block discarded – undo
1836 1836
     {
1837 1837
         $EEM_Event   = $this->_event_model();
1838 1838
         $offset      = ($current_page - 1) * $per_page;
1839
-        $limit       = $count ? null : $offset . ',' . $per_page;
1839
+        $limit       = $count ? null : $offset.','.$per_page;
1840 1840
         $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1841 1841
         $order       = $this->request->getRequestParam('order', 'DESC');
1842 1842
         $month_range = $this->request->getRequestParam('month_range');
@@ -1873,10 +1873,10 @@  discard block
 block discarded – undo
1873 1873
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874 1874
         if ($month_range) {
1875 1875
             $DateTime = new DateTime(
1876
-                $year_r . '-' . $month_r . '-01 00:00:00',
1876
+                $year_r.'-'.$month_r.'-01 00:00:00',
1877 1877
                 new DateTimeZone('UTC')
1878 1878
             );
1879
-            $start    = $DateTime->getTimestamp();
1879
+            $start = $DateTime->getTimestamp();
1880 1880
             // set the datetime to be the end of the month
1881 1881
             $DateTime->setDate(
1882 1882
                 $year_r,
@@ -1901,11 +1901,11 @@  discard block
 block discarded – undo
1901 1901
                                                         ->format(implode(' ', $start_formats));
1902 1902
             $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1903 1903
         }
1904
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1904
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1905 1905
             $where['EVT_wp_user'] = get_current_user_id();
1906 1906
         } else {
1907
-            if (! isset($where['status'])) {
1908
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1907
+            if ( ! isset($where['status'])) {
1908
+                if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1909 1909
                     $where['OR'] = [
1910 1910
                         'status*restrict_private' => ['!=', 'private'],
1911 1911
                         'AND'                     => [
@@ -1927,7 +1927,7 @@  discard block
 block discarded – undo
1927 1927
         // search query handling
1928 1928
         $search_term = $this->request->getRequestParam('s');
1929 1929
         if ($search_term) {
1930
-            $search_term = '%' . $search_term . '%';
1930
+            $search_term = '%'.$search_term.'%';
1931 1931
             $where['OR'] = [
1932 1932
                 'EVT_name'       => ['LIKE', $search_term],
1933 1933
                 'EVT_desc'       => ['LIKE', $search_term],
@@ -2035,7 +2035,7 @@  discard block
 block discarded – undo
2035 2035
             // clean status
2036 2036
             $event_status = sanitize_key($event_status);
2037 2037
             // grab status
2038
-            if (! empty($event_status)) {
2038
+            if ( ! empty($event_status)) {
2039 2039
                 $success = $this->_change_event_status($EVT_ID, $event_status);
2040 2040
             } else {
2041 2041
                 $success = false;
@@ -2075,7 +2075,7 @@  discard block
 block discarded – undo
2075 2075
         // clean status
2076 2076
         $event_status = sanitize_key($event_status);
2077 2077
         // grab status
2078
-        if (! empty($event_status)) {
2078
+        if ( ! empty($event_status)) {
2079 2079
             $success = true;
2080 2080
             // determine the event id and set to array.
2081 2081
             $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
@@ -2121,7 +2121,7 @@  discard block
 block discarded – undo
2121 2121
     private function _change_event_status($EVT_ID = 0, $event_status = '')
2122 2122
     {
2123 2123
         // grab event id
2124
-        if (! $EVT_ID) {
2124
+        if ( ! $EVT_ID) {
2125 2125
             $msg = esc_html__(
2126 2126
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2127 2127
                 'event_espresso'
@@ -2158,7 +2158,7 @@  discard block
 block discarded – undo
2158 2158
         // use class to change status
2159 2159
         $this->_cpt_model_obj->set_status($event_status);
2160 2160
         $success = $this->_cpt_model_obj->save();
2161
-        if (! $success) {
2161
+        if ( ! $success) {
2162 2162
             $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2163 2163
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2164 2164
             return false;
@@ -2225,7 +2225,7 @@  discard block
 block discarded – undo
2225 2225
      */
2226 2226
     protected function getModelObjNodeGroupPersister()
2227 2227
     {
2228
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2228
+        if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2229 2229
             $this->model_obj_node_group_persister =
2230 2230
                 $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2231 2231
         }
@@ -2515,7 +2515,7 @@  discard block
 block discarded – undo
2515 2515
                                                 . esc_html__(
2516 2516
                                                     '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.',
2517 2517
                                                     'event_espresso'
2518
-                                                ) . '</strong>';
2518
+                                                ).'</strong>';
2519 2519
         $this->display_admin_caf_preview_page('template_settings_tab');
2520 2520
     }
2521 2521
 
@@ -2536,11 +2536,11 @@  discard block
 block discarded – undo
2536 2536
         $this->_set_empty_category_object();
2537 2537
         // only set if we've got an id
2538 2538
         $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2539
-        if (! $category_ID) {
2539
+        if ( ! $category_ID) {
2540 2540
             return;
2541 2541
         }
2542 2542
         $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2543
-        if (! empty($term)) {
2543
+        if ( ! empty($term)) {
2544 2544
             $this->_category->category_name       = $term->name;
2545 2545
             $this->_category->category_identifier = $term->slug;
2546 2546
             $this->_category->category_desc       = $term->description;
@@ -2568,7 +2568,7 @@  discard block
 block discarded – undo
2568 2568
     {
2569 2569
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2570 2570
         $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2571
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2571
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
2572 2572
             'add_category',
2573 2573
             'add_category',
2574 2574
             [],
@@ -2637,7 +2637,7 @@  discard block
 block discarded – undo
2637 2637
             $category_select_values,
2638 2638
             $this->_category->parent
2639 2639
         );
2640
-        $template_args   = [
2640
+        $template_args = [
2641 2641
             'category'                 => $this->_category,
2642 2642
             'category_select'          => $category_select,
2643 2643
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -2645,7 +2645,7 @@  discard block
 block discarded – undo
2645 2645
             'disable'                  => '',
2646 2646
             'disabled_message'         => false,
2647 2647
         ];
2648
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2648
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2649 2649
         return EEH_Template::display_template($template, $template_args, true);
2650 2650
     }
2651 2651
 
@@ -2735,7 +2735,7 @@  discard block
 block discarded – undo
2735 2735
         $insert_ids = $update
2736 2736
             ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2737 2737
             : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2738
-        if (! is_array($insert_ids)) {
2738
+        if ( ! is_array($insert_ids)) {
2739 2739
             $msg = esc_html__(
2740 2740
                 'An error occurred and the category has not been saved to the database.',
2741 2741
                 'event_espresso'
@@ -2770,7 +2770,7 @@  discard block
 block discarded – undo
2770 2770
         $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2771 2771
         $search_term = $this->request->getRequestParam('s');
2772 2772
         if ($search_term) {
2773
-            $search_term = '%' . $search_term . '%';
2773
+            $search_term = '%'.$search_term.'%';
2774 2774
             $where['OR'] = [
2775 2775
                 'Term.name'   => ['LIKE', $search_term],
2776 2776
                 'description' => ['LIKE', $search_term],
@@ -2779,7 +2779,7 @@  discard block
 block discarded – undo
2779 2779
         $query_params = [
2780 2780
             $where,
2781 2781
             'order_by'   => [$orderby => $order],
2782
-            'limit'      => $limit . ',' . $per_page,
2782
+            'limit'      => $limit.','.$per_page,
2783 2783
             'force_join' => ['Term'],
2784 2784
         ];
2785 2785
         return $count
Please login to merge, or discard this patch.