Completed
Branch BUG/datetime-ticket-sold-count... (9dc6e7)
by
unknown
03:39 queued 01:13
created
caffeinated/admin/new/pricing/espresso_events_Pricing_Hooks.class.php 2 patches
Indentation   +2143 added lines, -2143 removed lines patch added patch discarded remove patch
@@ -15,2205 +15,2205 @@
 block discarded – undo
15 15
 class espresso_events_Pricing_Hooks extends EE_Admin_Hooks
16 16
 {
17 17
 
18
-    /**
19
-     * This property is just used to hold the status of whether an event is currently being
20
-     * created (true) or edited (false)
21
-     *
22
-     * @access protected
23
-     * @var bool
24
-     */
25
-    protected $_is_creating_event;
18
+	/**
19
+	 * This property is just used to hold the status of whether an event is currently being
20
+	 * created (true) or edited (false)
21
+	 *
22
+	 * @access protected
23
+	 * @var bool
24
+	 */
25
+	protected $_is_creating_event;
26 26
 
27
-    /**
28
-     * Used to contain the format strings for date and time that will be used for php date and
29
-     * time.
30
-     * Is set in the _set_hooks_properties() method.
31
-     *
32
-     * @var array
33
-     */
34
-    protected $_date_format_strings;
27
+	/**
28
+	 * Used to contain the format strings for date and time that will be used for php date and
29
+	 * time.
30
+	 * Is set in the _set_hooks_properties() method.
31
+	 *
32
+	 * @var array
33
+	 */
34
+	protected $_date_format_strings;
35 35
 
36
-    /**
37
-     * @var string $_date_time_format
38
-     */
39
-    protected $_date_time_format;
36
+	/**
37
+	 * @var string $_date_time_format
38
+	 */
39
+	protected $_date_time_format;
40 40
 
41 41
 
42
-    /**
43
-     * @throws InvalidArgumentException
44
-     * @throws InvalidInterfaceException
45
-     * @throws InvalidDataTypeException
46
-     */
47
-    protected function _set_hooks_properties()
48
-    {
49
-        $this->_name = 'pricing';
50
-        // capability check
51
-        if (
52
-            $this->_adminpage_obj->adminConfig()->useAdvancedEditor()
53
-            || ! EE_Registry::instance()->CAP->current_user_can(
54
-                'ee_read_default_prices',
55
-                'advanced_ticket_datetime_metabox'
56
-            )
57
-        ) {
58
-            $this->_metaboxes      = [];
59
-            $this->_scripts_styles = [];
60
-            return;
61
-        }
62
-        $this->_setup_metaboxes();
63
-        $this->_set_date_time_formats();
64
-        $this->_validate_format_strings();
65
-        $this->_set_scripts_styles();
66
-        // commented out temporarily until logic is implemented in callback
67
-        // add_action(
68
-        //     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
69
-        //     array($this, 'autosave_handling')
70
-        // );
71
-        add_filter(
72
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
73
-            array($this, 'caf_updates')
74
-        );
75
-    }
42
+	/**
43
+	 * @throws InvalidArgumentException
44
+	 * @throws InvalidInterfaceException
45
+	 * @throws InvalidDataTypeException
46
+	 */
47
+	protected function _set_hooks_properties()
48
+	{
49
+		$this->_name = 'pricing';
50
+		// capability check
51
+		if (
52
+			$this->_adminpage_obj->adminConfig()->useAdvancedEditor()
53
+			|| ! EE_Registry::instance()->CAP->current_user_can(
54
+				'ee_read_default_prices',
55
+				'advanced_ticket_datetime_metabox'
56
+			)
57
+		) {
58
+			$this->_metaboxes      = [];
59
+			$this->_scripts_styles = [];
60
+			return;
61
+		}
62
+		$this->_setup_metaboxes();
63
+		$this->_set_date_time_formats();
64
+		$this->_validate_format_strings();
65
+		$this->_set_scripts_styles();
66
+		// commented out temporarily until logic is implemented in callback
67
+		// add_action(
68
+		//     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
69
+		//     array($this, 'autosave_handling')
70
+		// );
71
+		add_filter(
72
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
73
+			array($this, 'caf_updates')
74
+		);
75
+	}
76 76
 
77 77
 
78
-    /**
79
-     * @return void
80
-     */
81
-    protected function _setup_metaboxes()
82
-    {
83
-        // if we were going to add our own metaboxes we'd use the below.
84
-        $this->_metaboxes = array(
85
-            0 => array(
86
-                'page_route' => array('edit', 'create_new'),
87
-                'func'       => 'pricing_metabox',
88
-                'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
89
-                'priority'   => 'high',
90
-                'context'    => 'normal',
91
-            ),
92
-        );
93
-        $this->_remove_metaboxes = array(
94
-            0 => array(
95
-                'page_route' => array('edit', 'create_new'),
96
-                'id'         => 'espresso_event_editor_tickets',
97
-                'context'    => 'normal',
98
-            ),
99
-        );
100
-    }
78
+	/**
79
+	 * @return void
80
+	 */
81
+	protected function _setup_metaboxes()
82
+	{
83
+		// if we were going to add our own metaboxes we'd use the below.
84
+		$this->_metaboxes = array(
85
+			0 => array(
86
+				'page_route' => array('edit', 'create_new'),
87
+				'func'       => 'pricing_metabox',
88
+				'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
89
+				'priority'   => 'high',
90
+				'context'    => 'normal',
91
+			),
92
+		);
93
+		$this->_remove_metaboxes = array(
94
+			0 => array(
95
+				'page_route' => array('edit', 'create_new'),
96
+				'id'         => 'espresso_event_editor_tickets',
97
+				'context'    => 'normal',
98
+			),
99
+		);
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     * @return void
105
-     */
106
-    protected function _set_date_time_formats()
107
-    {
108
-        /**
109
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
110
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
111
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
112
-         *
113
-         * @since 4.6.7
114
-         * @var array  Expected an array returned with 'date' and 'time' keys.
115
-         */
116
-        $this->_date_format_strings = apply_filters(
117
-            'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
118
-            array(
119
-                'date' => 'Y-m-d',
120
-                'time' => 'h:i a',
121
-            )
122
-        );
123
-        // validate
124
-        $this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
125
-            ? $this->_date_format_strings['date']
126
-            : null;
127
-        $this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
128
-            ? $this->_date_format_strings['time']
129
-            : null;
130
-        $this->_date_time_format = $this->_date_format_strings['date']
131
-                                   . ' '
132
-                                   . $this->_date_format_strings['time'];
133
-    }
103
+	/**
104
+	 * @return void
105
+	 */
106
+	protected function _set_date_time_formats()
107
+	{
108
+		/**
109
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
110
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
111
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
112
+		 *
113
+		 * @since 4.6.7
114
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
115
+		 */
116
+		$this->_date_format_strings = apply_filters(
117
+			'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
118
+			array(
119
+				'date' => 'Y-m-d',
120
+				'time' => 'h:i a',
121
+			)
122
+		);
123
+		// validate
124
+		$this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
125
+			? $this->_date_format_strings['date']
126
+			: null;
127
+		$this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
128
+			? $this->_date_format_strings['time']
129
+			: null;
130
+		$this->_date_time_format = $this->_date_format_strings['date']
131
+								   . ' '
132
+								   . $this->_date_format_strings['time'];
133
+	}
134 134
 
135 135
 
136
-    /**
137
-     * @return void
138
-     */
139
-    protected function _validate_format_strings()
140
-    {
141
-        // validate format strings
142
-        $format_validation = EEH_DTT_Helper::validate_format_string(
143
-            $this->_date_time_format
144
-        );
145
-        if (is_array($format_validation)) {
146
-            $msg = '<p>';
147
-            $msg .= sprintf(
148
-                esc_html__(
149
-                    'The format "%s" was likely added via a filter and is invalid for the following reasons:',
150
-                    'event_espresso'
151
-                ),
152
-                $this->_date_time_format
153
-            );
154
-            $msg .= '</p><ul>';
155
-            foreach ($format_validation as $error) {
156
-                $msg .= '<li>' . $error . '</li>';
157
-            }
158
-            $msg .= '</ul><p>';
159
-            $msg .= sprintf(
160
-                esc_html__(
161
-                    '%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
162
-                    'event_espresso'
163
-                ),
164
-                '<span style="color:#D54E21;">',
165
-                '</span>'
166
-            );
167
-            $msg .= '</p>';
168
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
169
-            $this->_date_format_strings = array(
170
-                'date' => 'Y-m-d',
171
-                'time' => 'h:i a',
172
-            );
173
-        }
174
-    }
136
+	/**
137
+	 * @return void
138
+	 */
139
+	protected function _validate_format_strings()
140
+	{
141
+		// validate format strings
142
+		$format_validation = EEH_DTT_Helper::validate_format_string(
143
+			$this->_date_time_format
144
+		);
145
+		if (is_array($format_validation)) {
146
+			$msg = '<p>';
147
+			$msg .= sprintf(
148
+				esc_html__(
149
+					'The format "%s" was likely added via a filter and is invalid for the following reasons:',
150
+					'event_espresso'
151
+				),
152
+				$this->_date_time_format
153
+			);
154
+			$msg .= '</p><ul>';
155
+			foreach ($format_validation as $error) {
156
+				$msg .= '<li>' . $error . '</li>';
157
+			}
158
+			$msg .= '</ul><p>';
159
+			$msg .= sprintf(
160
+				esc_html__(
161
+					'%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
162
+					'event_espresso'
163
+				),
164
+				'<span style="color:#D54E21;">',
165
+				'</span>'
166
+			);
167
+			$msg .= '</p>';
168
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
169
+			$this->_date_format_strings = array(
170
+				'date' => 'Y-m-d',
171
+				'time' => 'h:i a',
172
+			);
173
+		}
174
+	}
175 175
 
176 176
 
177
-    /**
178
-     * @return void
179
-     */
180
-    protected function _set_scripts_styles()
181
-    {
182
-        $this->_scripts_styles = array(
183
-            'registers'   => array(
184
-                'ee-tickets-datetimes-css' => array(
185
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
186
-                    'type' => 'css',
187
-                ),
188
-                'ee-dtt-ticket-metabox'    => array(
189
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
190
-                    'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
191
-                ),
192
-            ),
193
-            'deregisters' => array(
194
-                'event-editor-css'       => array('type' => 'css'),
195
-                'event-datetime-metabox' => array('type' => 'js'),
196
-            ),
197
-            'enqueues'    => array(
198
-                'ee-tickets-datetimes-css' => array('edit', 'create_new'),
199
-                'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
200
-            ),
201
-            'localize'    => array(
202
-                'ee-dtt-ticket-metabox' => array(
203
-                    'DTT_TRASH_BLOCK'       => array(
204
-                        'main_warning'            => esc_html__(
205
-                            'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
206
-                            'event_espresso'
207
-                        ),
208
-                        'after_warning'           => esc_html__(
209
-                            'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
210
-                            'event_espresso'
211
-                        ),
212
-                        'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
213
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
214
-                        'close_button'            => '<button class="button-secondary ee-modal-cancel">'
215
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
216
-                        'single_warning_from_tkt' => esc_html__(
217
-                            '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.',
218
-                            'event_espresso'
219
-                        ),
220
-                        'single_warning_from_dtt' => esc_html__(
221
-                            '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.',
222
-                            'event_espresso'
223
-                        ),
224
-                        'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
225
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
226
-                    ),
227
-                    'DTT_ERROR_MSG'         => array(
228
-                        'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
229
-                        'dismiss_button' => '<div class="save-cancel-button-container">'
230
-                                            . '<button class="button-secondary ee-modal-cancel">'
231
-                                            . esc_html__('Dismiss', 'event_espresso')
232
-                                            . '</button></div>',
233
-                    ),
234
-                    'DTT_OVERSELL_WARNING'  => array(
235
-                        'datetime_ticket' => esc_html__(
236
-                            '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.',
237
-                            'event_espresso'
238
-                        ),
239
-                        'ticket_datetime' => esc_html__(
240
-                            '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.',
241
-                            'event_espresso'
242
-                        ),
243
-                    ),
244
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
245
-                        $this->_date_format_strings['date'],
246
-                        $this->_date_format_strings['time']
247
-                    ),
248
-                    'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
249
-                ),
250
-            ),
251
-        );
252
-    }
177
+	/**
178
+	 * @return void
179
+	 */
180
+	protected function _set_scripts_styles()
181
+	{
182
+		$this->_scripts_styles = array(
183
+			'registers'   => array(
184
+				'ee-tickets-datetimes-css' => array(
185
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
186
+					'type' => 'css',
187
+				),
188
+				'ee-dtt-ticket-metabox'    => array(
189
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
190
+					'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
191
+				),
192
+			),
193
+			'deregisters' => array(
194
+				'event-editor-css'       => array('type' => 'css'),
195
+				'event-datetime-metabox' => array('type' => 'js'),
196
+			),
197
+			'enqueues'    => array(
198
+				'ee-tickets-datetimes-css' => array('edit', 'create_new'),
199
+				'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
200
+			),
201
+			'localize'    => array(
202
+				'ee-dtt-ticket-metabox' => array(
203
+					'DTT_TRASH_BLOCK'       => array(
204
+						'main_warning'            => esc_html__(
205
+							'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
206
+							'event_espresso'
207
+						),
208
+						'after_warning'           => esc_html__(
209
+							'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
210
+							'event_espresso'
211
+						),
212
+						'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
213
+													 . esc_html__('Cancel', 'event_espresso') . '</button>',
214
+						'close_button'            => '<button class="button-secondary ee-modal-cancel">'
215
+													 . esc_html__('Close', 'event_espresso') . '</button>',
216
+						'single_warning_from_tkt' => esc_html__(
217
+							'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.',
218
+							'event_espresso'
219
+						),
220
+						'single_warning_from_dtt' => esc_html__(
221
+							'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.',
222
+							'event_espresso'
223
+						),
224
+						'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
225
+													 . esc_html__('Dismiss', 'event_espresso') . '</button>',
226
+					),
227
+					'DTT_ERROR_MSG'         => array(
228
+						'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
229
+						'dismiss_button' => '<div class="save-cancel-button-container">'
230
+											. '<button class="button-secondary ee-modal-cancel">'
231
+											. esc_html__('Dismiss', 'event_espresso')
232
+											. '</button></div>',
233
+					),
234
+					'DTT_OVERSELL_WARNING'  => array(
235
+						'datetime_ticket' => esc_html__(
236
+							'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.',
237
+							'event_espresso'
238
+						),
239
+						'ticket_datetime' => esc_html__(
240
+							'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.',
241
+							'event_espresso'
242
+						),
243
+					),
244
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
245
+						$this->_date_format_strings['date'],
246
+						$this->_date_format_strings['time']
247
+					),
248
+					'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
249
+				),
250
+			),
251
+		);
252
+	}
253 253
 
254 254
 
255
-    /**
256
-     * @param array $update_callbacks
257
-     * @return array
258
-     */
259
-    public function caf_updates(array $update_callbacks)
260
-    {
261
-        unset($update_callbacks['_default_tickets_update']);
262
-        $update_callbacks['datetime_and_tickets_caf_update'] = array($this, 'datetime_and_tickets_caf_update');
263
-        return $update_callbacks;
264
-    }
255
+	/**
256
+	 * @param array $update_callbacks
257
+	 * @return array
258
+	 */
259
+	public function caf_updates(array $update_callbacks)
260
+	{
261
+		unset($update_callbacks['_default_tickets_update']);
262
+		$update_callbacks['datetime_and_tickets_caf_update'] = 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
-                $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
415
-                // remove tkt relationships.
416
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
417
-                foreach ($related_tickets as $tkt) {
418
-                    $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
419
-                }
420
-                $event->_remove_relation_to($id, 'Datetime');
421
-                $dtt_to_remove->refresh_cache_of_related_objects();
422
-            }
423
-        }
424
-        return $saved_dtt_objs;
425
-    }
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
+				$dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
415
+				// remove tkt relationships.
416
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
417
+				foreach ($related_tickets as $tkt) {
418
+					$dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
419
+				}
420
+				$event->_remove_relation_to($id, 'Datetime');
421
+				$dtt_to_remove->refresh_cache_of_related_objects();
422
+			}
423
+		}
424
+		return $saved_dtt_objs;
425
+	}
426 426
 
427 427
 
428
-    /**
429
-     * update tickets
430
-     *
431
-     * @param  EE_Event      $event           Event object being updated
432
-     * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
433
-     * @param  array         $data            incoming request data
434
-     * @return EE_Ticket[]
435
-     * @throws Exception
436
-     * @throws ReflectionException
437
-     * @throws InvalidInterfaceException
438
-     * @throws InvalidDataTypeException
439
-     * @throws InvalidArgumentException
440
-     * @throws EE_Error
441
-     */
442
-    protected function _update_tickets($event, $saved_datetimes, $data)
443
-    {
444
-        $new_tkt = null;
445
-        $new_default = null;
446
-        // stripslashes because WP filtered the $_POST ($data) array to add slashes
447
-        $data = stripslashes_deep($data);
448
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
449
-        $saved_tickets = $datetimes_on_existing = array();
450
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
451
-        if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
452
-            throw new InvalidArgumentException(
453
-                esc_html__(
454
-                    'The "edit_tickets" array is invalid therefore the event can not be updated.',
455
-                    'event_espresso'
456
-                )
457
-            );
458
-        }
459
-        foreach ($data['edit_tickets'] as $row => $tkt) {
460
-            $update_prices = $create_new_TKT = false;
461
-            // figure out what datetimes were added to the ticket
462
-            // and what datetimes were removed from the ticket in the session.
463
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
464
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
465
-            $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
466
-            $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
467
-            // trim inputs to ensure any excess whitespace is removed.
468
-            $tkt = array_map(
469
-                function ($ticket_data) {
470
-                    return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
471
-                },
472
-                $tkt
473
-            );
474
-            // note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
475
-            // because we're doing calculations prior to using the models.
476
-            // note incoming ['TKT_price'] value is already in standard notation (via js).
477
-            $ticket_price = isset($tkt['TKT_price'])
478
-                ? round((float) $tkt['TKT_price'], 3)
479
-                : 0;
480
-            // note incoming base price needs converted from localized value.
481
-            $base_price = isset($tkt['TKT_base_price'])
482
-                ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
483
-                : 0;
484
-            // if ticket price == 0 and $base_price != 0 then ticket price == base_price
485
-            $ticket_price = $ticket_price === 0 && $base_price !== 0
486
-                ? $base_price
487
-                : $ticket_price;
488
-            $base_price_id = isset($tkt['TKT_base_price_ID'])
489
-                ? $tkt['TKT_base_price_ID']
490
-                : 0;
491
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
492
-                ? $data['edit_prices'][ $row ]
493
-                : array();
494
-            $now = null;
495
-            if (empty($tkt['TKT_start_date'])) {
496
-                // lets' use now in the set timezone.
497
-                $now = new DateTime('now', new DateTimeZone($event->get_timezone()));
498
-                $tkt['TKT_start_date'] = $now->format($this->_date_time_format);
499
-            }
500
-            if (empty($tkt['TKT_end_date'])) {
501
-                /**
502
-                 * set the TKT_end_date to the first datetime attached to the ticket.
503
-                 */
504
-                $first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
505
-                $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
506
-            }
507
-            $TKT_values = array(
508
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
509
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
510
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
511
-                'TKT_description' => ! empty($tkt['TKT_description'])
512
-                                     && $tkt['TKT_description'] !== esc_html__(
513
-                                         'You can modify this description',
514
-                                         'event_espresso'
515
-                                     )
516
-                    ? $tkt['TKT_description']
517
-                    : '',
518
-                'TKT_start_date'  => $tkt['TKT_start_date'],
519
-                'TKT_end_date'    => $tkt['TKT_end_date'],
520
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
521
-                    ? EE_INF
522
-                    : $tkt['TKT_qty'],
523
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
524
-                    ? EE_INF
525
-                    : $tkt['TKT_uses'],
526
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
527
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
528
-                'TKT_row'         => $row,
529
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
530
-                'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
531
-                'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
532
-                'TKT_price'       => $ticket_price,
533
-            );
534
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
535
-            // which means in turn that the prices will become new prices as well.
536
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
537
-                $TKT_values['TKT_ID'] = 0;
538
-                $TKT_values['TKT_is_default'] = 0;
539
-                $update_prices = true;
540
-            }
541
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
542
-            // we actually do our saves ahead of doing any add_relations to
543
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
544
-            // but DID have it's items modified.
545
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
546
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
547
-            if (absint($TKT_values['TKT_ID'])) {
548
-                $ticket = EE_Registry::instance()
549
-                                     ->load_model('Ticket', array($timezone))
550
-                                     ->get_one_by_ID($tkt['TKT_ID']);
551
-                if ($ticket instanceof EE_Ticket) {
552
-                    $ticket = $this->_update_ticket_datetimes(
553
-                        $ticket,
554
-                        $saved_datetimes,
555
-                        $datetimes_added,
556
-                        $datetimes_removed
557
-                    );
558
-                    // are there any registrations using this ticket ?
559
-                    $tickets_sold = $ticket->count_related(
560
-                        'Registration',
561
-                        array(
562
-                            array(
563
-                                'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
564
-                            ),
565
-                        )
566
-                    );
567
-                    // set ticket formats
568
-                    $ticket->set_date_format($this->_date_format_strings['date']);
569
-                    $ticket->set_time_format($this->_date_format_strings['time']);
570
-                    // let's just check the total price for the existing ticket
571
-                    // and determine if it matches the new total price.
572
-                    // if they are different then we create a new ticket (if tickets sold)
573
-                    // if they aren't different then we go ahead and modify existing ticket.
574
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
575
-                    // set new values
576
-                    foreach ($TKT_values as $field => $value) {
577
-                        if ($field === 'TKT_qty') {
578
-                            $ticket->set_qty($value);
579
-                        } else {
580
-                            $ticket->set($field, $value);
581
-                        }
582
-                    }
583
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
584
-                    // Otherwise we have to create a new ticket.
585
-                    if ($create_new_TKT) {
586
-                        $new_tkt = $this->_duplicate_ticket(
587
-                            $ticket,
588
-                            $price_rows,
589
-                            $ticket_price,
590
-                            $base_price,
591
-                            $base_price_id
592
-                        );
593
-                    }
594
-                }
595
-            } else {
596
-                // no TKT_id so a new TKT
597
-                $ticket = EE_Ticket::new_instance(
598
-                    $TKT_values,
599
-                    $timezone,
600
-                    array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
601
-                );
602
-                if ($ticket instanceof EE_Ticket) {
603
-                    // make sure ticket has an ID of setting relations won't work
604
-                    $ticket->save();
605
-                    $ticket = $this->_update_ticket_datetimes(
606
-                        $ticket,
607
-                        $saved_datetimes,
608
-                        $datetimes_added,
609
-                        $datetimes_removed
610
-                    );
611
-                    $update_prices = true;
612
-                }
613
-            }
614
-            // make sure any current values have been saved.
615
-            // $ticket->save();
616
-            // before going any further make sure our dates are setup correctly
617
-            // so that the end date is always equal or greater than the start date.
618
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
619
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
620
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
621
-            }
622
-            // let's make sure the base price is handled
623
-            $ticket = ! $create_new_TKT
624
-                ? $this->_add_prices_to_ticket(
625
-                    array(),
626
-                    $ticket,
627
-                    $update_prices,
628
-                    $base_price,
629
-                    $base_price_id
630
-                )
631
-                : $ticket;
632
-            // add/update price_modifiers
633
-            $ticket = ! $create_new_TKT
634
-                ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
635
-                : $ticket;
636
-            // need to make sue that the TKT_price is accurate after saving the prices.
637
-            $ticket->ensure_TKT_Price_correct();
638
-            // handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
639
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
640
-                $update_prices = true;
641
-                $new_default = clone $ticket;
642
-                $new_default->set('TKT_ID', 0);
643
-                $new_default->set('TKT_is_default', 1);
644
-                $new_default->set('TKT_row', 1);
645
-                $new_default->set('TKT_price', $ticket_price);
646
-                // remove any dtt relations cause we DON'T want dtt relations attached
647
-                // (note this is just removing the cached relations in the object)
648
-                $new_default->_remove_relations('Datetime');
649
-                // @todo we need to add the current attached prices as new prices to the new default ticket.
650
-                $new_default = $this->_add_prices_to_ticket(
651
-                    $price_rows,
652
-                    $new_default,
653
-                    $update_prices
654
-                );
655
-                // don't forget the base price!
656
-                $new_default = $this->_add_prices_to_ticket(
657
-                    array(),
658
-                    $new_default,
659
-                    $update_prices,
660
-                    $base_price,
661
-                    $base_price_id
662
-                );
663
-                $new_default->save();
664
-                do_action(
665
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
666
-                    $new_default,
667
-                    $row,
668
-                    $ticket,
669
-                    $data
670
-                );
671
-            }
672
-            // DO ALL dtt relationships for both current tickets and any archived tickets
673
-            // for the given dtt that are related to the current ticket.
674
-            // TODO... not sure exactly how we're going to do this considering we don't know
675
-            // what current ticket the archived tickets are related to
676
-            // (and TKT_parent is used for autosaves so that's not a field we can reliably use).
677
-            // let's assign any tickets that have been setup to the saved_tickets tracker
678
-            // save existing TKT
679
-            $ticket->save();
680
-            if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
681
-                // save new TKT
682
-                $new_tkt->save();
683
-                // add new ticket to array
684
-                $saved_tickets[ $new_tkt->ID() ] = $new_tkt;
685
-                do_action(
686
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
687
-                    $new_tkt,
688
-                    $row,
689
-                    $tkt,
690
-                    $data
691
-                );
692
-            } else {
693
-                // add tkt to saved tkts
694
-                $saved_tickets[ $ticket->ID() ] = $ticket;
695
-                do_action(
696
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
697
-                    $ticket,
698
-                    $row,
699
-                    $tkt,
700
-                    $data
701
-                );
702
-            }
703
-        }
704
-        // now we need to handle tickets actually "deleted permanently".
705
-        // There are cases where we'd want this to happen
706
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
707
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
708
-        // No sense in keeping all the related data in the db!
709
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
710
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
711
-        foreach ($tickets_removed as $id) {
712
-            $id = absint($id);
713
-            // get the ticket for this id
714
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
715
-            // if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
716
-            if ($tkt_to_remove->get('TKT_is_default')) {
717
-                continue;
718
-            }
719
-            // if this tkt has any registrations attached so then we just ARCHIVE
720
-            // because we don't actually permanently delete these tickets.
721
-            if ($tkt_to_remove->count_related('Registration') > 0) {
722
-                $tkt_to_remove->delete();
723
-                continue;
724
-            }
725
-            // need to get all the related datetimes on this ticket and remove from every single one of them
726
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
727
-            $datetimes = $tkt_to_remove->get_many_related('Datetime');
728
-            foreach ($datetimes as $datetime) {
729
-                $tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
730
-            }
731
-            // need to do the same for prices (except these prices can also be deleted because again,
732
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
733
-            $tkt_to_remove->delete_related_permanently('Price');
734
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
735
-            // finally let's delete this ticket
736
-            // (which should not be blocked at this point b/c we've removed all our relationships)
737
-            $tkt_to_remove->delete_permanently();
738
-        }
739
-        return $saved_tickets;
740
-    }
428
+	/**
429
+	 * update tickets
430
+	 *
431
+	 * @param  EE_Event      $event           Event object being updated
432
+	 * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
433
+	 * @param  array         $data            incoming request data
434
+	 * @return EE_Ticket[]
435
+	 * @throws Exception
436
+	 * @throws ReflectionException
437
+	 * @throws InvalidInterfaceException
438
+	 * @throws InvalidDataTypeException
439
+	 * @throws InvalidArgumentException
440
+	 * @throws EE_Error
441
+	 */
442
+	protected function _update_tickets($event, $saved_datetimes, $data)
443
+	{
444
+		$new_tkt = null;
445
+		$new_default = null;
446
+		// stripslashes because WP filtered the $_POST ($data) array to add slashes
447
+		$data = stripslashes_deep($data);
448
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
449
+		$saved_tickets = $datetimes_on_existing = array();
450
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
451
+		if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
452
+			throw new InvalidArgumentException(
453
+				esc_html__(
454
+					'The "edit_tickets" array is invalid therefore the event can not be updated.',
455
+					'event_espresso'
456
+				)
457
+			);
458
+		}
459
+		foreach ($data['edit_tickets'] as $row => $tkt) {
460
+			$update_prices = $create_new_TKT = false;
461
+			// figure out what datetimes were added to the ticket
462
+			// and what datetimes were removed from the ticket in the session.
463
+			$starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
464
+			$tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
465
+			$datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
466
+			$datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
467
+			// trim inputs to ensure any excess whitespace is removed.
468
+			$tkt = array_map(
469
+				function ($ticket_data) {
470
+					return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
471
+				},
472
+				$tkt
473
+			);
474
+			// note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
475
+			// because we're doing calculations prior to using the models.
476
+			// note incoming ['TKT_price'] value is already in standard notation (via js).
477
+			$ticket_price = isset($tkt['TKT_price'])
478
+				? round((float) $tkt['TKT_price'], 3)
479
+				: 0;
480
+			// note incoming base price needs converted from localized value.
481
+			$base_price = isset($tkt['TKT_base_price'])
482
+				? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
483
+				: 0;
484
+			// if ticket price == 0 and $base_price != 0 then ticket price == base_price
485
+			$ticket_price = $ticket_price === 0 && $base_price !== 0
486
+				? $base_price
487
+				: $ticket_price;
488
+			$base_price_id = isset($tkt['TKT_base_price_ID'])
489
+				? $tkt['TKT_base_price_ID']
490
+				: 0;
491
+			$price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
492
+				? $data['edit_prices'][ $row ]
493
+				: array();
494
+			$now = null;
495
+			if (empty($tkt['TKT_start_date'])) {
496
+				// lets' use now in the set timezone.
497
+				$now = new DateTime('now', new DateTimeZone($event->get_timezone()));
498
+				$tkt['TKT_start_date'] = $now->format($this->_date_time_format);
499
+			}
500
+			if (empty($tkt['TKT_end_date'])) {
501
+				/**
502
+				 * set the TKT_end_date to the first datetime attached to the ticket.
503
+				 */
504
+				$first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
505
+				$tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
506
+			}
507
+			$TKT_values = array(
508
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
509
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
510
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
511
+				'TKT_description' => ! empty($tkt['TKT_description'])
512
+									 && $tkt['TKT_description'] !== esc_html__(
513
+										 'You can modify this description',
514
+										 'event_espresso'
515
+									 )
516
+					? $tkt['TKT_description']
517
+					: '',
518
+				'TKT_start_date'  => $tkt['TKT_start_date'],
519
+				'TKT_end_date'    => $tkt['TKT_end_date'],
520
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
521
+					? EE_INF
522
+					: $tkt['TKT_qty'],
523
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
524
+					? EE_INF
525
+					: $tkt['TKT_uses'],
526
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
527
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
528
+				'TKT_row'         => $row,
529
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
530
+				'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
531
+				'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
532
+				'TKT_price'       => $ticket_price,
533
+			);
534
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
535
+			// which means in turn that the prices will become new prices as well.
536
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
537
+				$TKT_values['TKT_ID'] = 0;
538
+				$TKT_values['TKT_is_default'] = 0;
539
+				$update_prices = true;
540
+			}
541
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
542
+			// we actually do our saves ahead of doing any add_relations to
543
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
544
+			// but DID have it's items modified.
545
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
546
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
547
+			if (absint($TKT_values['TKT_ID'])) {
548
+				$ticket = EE_Registry::instance()
549
+									 ->load_model('Ticket', array($timezone))
550
+									 ->get_one_by_ID($tkt['TKT_ID']);
551
+				if ($ticket instanceof EE_Ticket) {
552
+					$ticket = $this->_update_ticket_datetimes(
553
+						$ticket,
554
+						$saved_datetimes,
555
+						$datetimes_added,
556
+						$datetimes_removed
557
+					);
558
+					// are there any registrations using this ticket ?
559
+					$tickets_sold = $ticket->count_related(
560
+						'Registration',
561
+						array(
562
+							array(
563
+								'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
564
+							),
565
+						)
566
+					);
567
+					// set ticket formats
568
+					$ticket->set_date_format($this->_date_format_strings['date']);
569
+					$ticket->set_time_format($this->_date_format_strings['time']);
570
+					// let's just check the total price for the existing ticket
571
+					// and determine if it matches the new total price.
572
+					// if they are different then we create a new ticket (if tickets sold)
573
+					// if they aren't different then we go ahead and modify existing ticket.
574
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
575
+					// set new values
576
+					foreach ($TKT_values as $field => $value) {
577
+						if ($field === 'TKT_qty') {
578
+							$ticket->set_qty($value);
579
+						} else {
580
+							$ticket->set($field, $value);
581
+						}
582
+					}
583
+					// if $create_new_TKT is false then we can safely update the existing ticket.
584
+					// Otherwise we have to create a new ticket.
585
+					if ($create_new_TKT) {
586
+						$new_tkt = $this->_duplicate_ticket(
587
+							$ticket,
588
+							$price_rows,
589
+							$ticket_price,
590
+							$base_price,
591
+							$base_price_id
592
+						);
593
+					}
594
+				}
595
+			} else {
596
+				// no TKT_id so a new TKT
597
+				$ticket = EE_Ticket::new_instance(
598
+					$TKT_values,
599
+					$timezone,
600
+					array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
601
+				);
602
+				if ($ticket instanceof EE_Ticket) {
603
+					// make sure ticket has an ID of setting relations won't work
604
+					$ticket->save();
605
+					$ticket = $this->_update_ticket_datetimes(
606
+						$ticket,
607
+						$saved_datetimes,
608
+						$datetimes_added,
609
+						$datetimes_removed
610
+					);
611
+					$update_prices = true;
612
+				}
613
+			}
614
+			// make sure any current values have been saved.
615
+			// $ticket->save();
616
+			// before going any further make sure our dates are setup correctly
617
+			// so that the end date is always equal or greater than the start date.
618
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
619
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
620
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
621
+			}
622
+			// let's make sure the base price is handled
623
+			$ticket = ! $create_new_TKT
624
+				? $this->_add_prices_to_ticket(
625
+					array(),
626
+					$ticket,
627
+					$update_prices,
628
+					$base_price,
629
+					$base_price_id
630
+				)
631
+				: $ticket;
632
+			// add/update price_modifiers
633
+			$ticket = ! $create_new_TKT
634
+				? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
635
+				: $ticket;
636
+			// need to make sue that the TKT_price is accurate after saving the prices.
637
+			$ticket->ensure_TKT_Price_correct();
638
+			// handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
639
+			if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
640
+				$update_prices = true;
641
+				$new_default = clone $ticket;
642
+				$new_default->set('TKT_ID', 0);
643
+				$new_default->set('TKT_is_default', 1);
644
+				$new_default->set('TKT_row', 1);
645
+				$new_default->set('TKT_price', $ticket_price);
646
+				// remove any dtt relations cause we DON'T want dtt relations attached
647
+				// (note this is just removing the cached relations in the object)
648
+				$new_default->_remove_relations('Datetime');
649
+				// @todo we need to add the current attached prices as new prices to the new default ticket.
650
+				$new_default = $this->_add_prices_to_ticket(
651
+					$price_rows,
652
+					$new_default,
653
+					$update_prices
654
+				);
655
+				// don't forget the base price!
656
+				$new_default = $this->_add_prices_to_ticket(
657
+					array(),
658
+					$new_default,
659
+					$update_prices,
660
+					$base_price,
661
+					$base_price_id
662
+				);
663
+				$new_default->save();
664
+				do_action(
665
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
666
+					$new_default,
667
+					$row,
668
+					$ticket,
669
+					$data
670
+				);
671
+			}
672
+			// DO ALL dtt relationships for both current tickets and any archived tickets
673
+			// for the given dtt that are related to the current ticket.
674
+			// TODO... not sure exactly how we're going to do this considering we don't know
675
+			// what current ticket the archived tickets are related to
676
+			// (and TKT_parent is used for autosaves so that's not a field we can reliably use).
677
+			// let's assign any tickets that have been setup to the saved_tickets tracker
678
+			// save existing TKT
679
+			$ticket->save();
680
+			if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
681
+				// save new TKT
682
+				$new_tkt->save();
683
+				// add new ticket to array
684
+				$saved_tickets[ $new_tkt->ID() ] = $new_tkt;
685
+				do_action(
686
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
687
+					$new_tkt,
688
+					$row,
689
+					$tkt,
690
+					$data
691
+				);
692
+			} else {
693
+				// add tkt to saved tkts
694
+				$saved_tickets[ $ticket->ID() ] = $ticket;
695
+				do_action(
696
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
697
+					$ticket,
698
+					$row,
699
+					$tkt,
700
+					$data
701
+				);
702
+			}
703
+		}
704
+		// now we need to handle tickets actually "deleted permanently".
705
+		// There are cases where we'd want this to happen
706
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
707
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
708
+		// No sense in keeping all the related data in the db!
709
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
710
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
711
+		foreach ($tickets_removed as $id) {
712
+			$id = absint($id);
713
+			// get the ticket for this id
714
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
715
+			// if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
716
+			if ($tkt_to_remove->get('TKT_is_default')) {
717
+				continue;
718
+			}
719
+			// if this tkt has any registrations attached so then we just ARCHIVE
720
+			// because we don't actually permanently delete these tickets.
721
+			if ($tkt_to_remove->count_related('Registration') > 0) {
722
+				$tkt_to_remove->delete();
723
+				continue;
724
+			}
725
+			// need to get all the related datetimes on this ticket and remove from every single one of them
726
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
727
+			$datetimes = $tkt_to_remove->get_many_related('Datetime');
728
+			foreach ($datetimes as $datetime) {
729
+				$tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
730
+			}
731
+			// need to do the same for prices (except these prices can also be deleted because again,
732
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
733
+			$tkt_to_remove->delete_related_permanently('Price');
734
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
735
+			// finally let's delete this ticket
736
+			// (which should not be blocked at this point b/c we've removed all our relationships)
737
+			$tkt_to_remove->delete_permanently();
738
+		}
739
+		return $saved_tickets;
740
+	}
741 741
 
742 742
 
743
-    /**
744
-     * @access  protected
745
-     * @param EE_Ticket      $ticket
746
-     * @param \EE_Datetime[] $saved_datetimes
747
-     * @param \EE_Datetime[] $added_datetimes
748
-     * @param \EE_Datetime[] $removed_datetimes
749
-     * @return EE_Ticket
750
-     * @throws EE_Error
751
-     */
752
-    protected function _update_ticket_datetimes(
753
-        EE_Ticket $ticket,
754
-        $saved_datetimes = array(),
755
-        $added_datetimes = array(),
756
-        $removed_datetimes = array()
757
-    ) {
758
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
759
-        // and removing the ticket from datetimes it got removed from.
760
-        // first let's add datetimes
761
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
762
-            foreach ($added_datetimes as $row_id) {
763
-                $row_id = (int) $row_id;
764
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
765
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
766
-                }
767
-            }
768
-        }
769
-        // then remove datetimes
770
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
771
-            foreach ($removed_datetimes as $row_id) {
772
-                $row_id = (int) $row_id;
773
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
774
-                // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
775
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
776
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
777
-                }
778
-            }
779
-        }
780
-        // cap ticket qty by datetime reg limits
781
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
782
-        return $ticket;
783
-    }
743
+	/**
744
+	 * @access  protected
745
+	 * @param EE_Ticket      $ticket
746
+	 * @param \EE_Datetime[] $saved_datetimes
747
+	 * @param \EE_Datetime[] $added_datetimes
748
+	 * @param \EE_Datetime[] $removed_datetimes
749
+	 * @return EE_Ticket
750
+	 * @throws EE_Error
751
+	 */
752
+	protected function _update_ticket_datetimes(
753
+		EE_Ticket $ticket,
754
+		$saved_datetimes = array(),
755
+		$added_datetimes = array(),
756
+		$removed_datetimes = array()
757
+	) {
758
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
759
+		// and removing the ticket from datetimes it got removed from.
760
+		// first let's add datetimes
761
+		if (! empty($added_datetimes) && is_array($added_datetimes)) {
762
+			foreach ($added_datetimes as $row_id) {
763
+				$row_id = (int) $row_id;
764
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
765
+					$ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
766
+				}
767
+			}
768
+		}
769
+		// then remove datetimes
770
+		if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
771
+			foreach ($removed_datetimes as $row_id) {
772
+				$row_id = (int) $row_id;
773
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
774
+				// So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
775
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
776
+					$ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
777
+				}
778
+			}
779
+		}
780
+		// cap ticket qty by datetime reg limits
781
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
782
+		return $ticket;
783
+	}
784 784
 
785 785
 
786
-    /**
787
-     * @access  protected
788
-     * @param EE_Ticket $ticket
789
-     * @param array     $price_rows
790
-     * @param int       $ticket_price
791
-     * @param int       $base_price
792
-     * @param int       $base_price_id
793
-     * @return EE_Ticket
794
-     * @throws ReflectionException
795
-     * @throws InvalidArgumentException
796
-     * @throws InvalidInterfaceException
797
-     * @throws InvalidDataTypeException
798
-     * @throws EE_Error
799
-     */
800
-    protected function _duplicate_ticket(
801
-        EE_Ticket $ticket,
802
-        $price_rows = array(),
803
-        $ticket_price = 0,
804
-        $base_price = 0,
805
-        $base_price_id = 0
806
-    ) {
807
-        // create new ticket that's a copy of the existing
808
-        // except a new id of course (and not archived)
809
-        // AND has the new TKT_price associated with it.
810
-        $new_ticket = clone $ticket;
811
-        $new_ticket->set('TKT_ID', 0);
812
-        $new_ticket->set_deleted(0);
813
-        $new_ticket->set_price($ticket_price);
814
-        $new_ticket->set_sold(0);
815
-        // let's get a new ID for this ticket
816
-        $new_ticket->save();
817
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
818
-        $datetimes_on_existing = $ticket->datetimes();
819
-        $new_ticket = $this->_update_ticket_datetimes(
820
-            $new_ticket,
821
-            $datetimes_on_existing,
822
-            array_keys($datetimes_on_existing)
823
-        );
824
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
825
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
826
-        // available.
827
-        if ($ticket->sold() > 0) {
828
-            $new_qty = $ticket->qty() - $ticket->sold();
829
-            $new_ticket->set_qty($new_qty);
830
-        }
831
-        // now we update the prices just for this ticket
832
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
833
-        // and we update the base price
834
-        $new_ticket = $this->_add_prices_to_ticket(
835
-            array(),
836
-            $new_ticket,
837
-            true,
838
-            $base_price,
839
-            $base_price_id
840
-        );
841
-        return $new_ticket;
842
-    }
786
+	/**
787
+	 * @access  protected
788
+	 * @param EE_Ticket $ticket
789
+	 * @param array     $price_rows
790
+	 * @param int       $ticket_price
791
+	 * @param int       $base_price
792
+	 * @param int       $base_price_id
793
+	 * @return EE_Ticket
794
+	 * @throws ReflectionException
795
+	 * @throws InvalidArgumentException
796
+	 * @throws InvalidInterfaceException
797
+	 * @throws InvalidDataTypeException
798
+	 * @throws EE_Error
799
+	 */
800
+	protected function _duplicate_ticket(
801
+		EE_Ticket $ticket,
802
+		$price_rows = array(),
803
+		$ticket_price = 0,
804
+		$base_price = 0,
805
+		$base_price_id = 0
806
+	) {
807
+		// create new ticket that's a copy of the existing
808
+		// except a new id of course (and not archived)
809
+		// AND has the new TKT_price associated with it.
810
+		$new_ticket = clone $ticket;
811
+		$new_ticket->set('TKT_ID', 0);
812
+		$new_ticket->set_deleted(0);
813
+		$new_ticket->set_price($ticket_price);
814
+		$new_ticket->set_sold(0);
815
+		// let's get a new ID for this ticket
816
+		$new_ticket->save();
817
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
818
+		$datetimes_on_existing = $ticket->datetimes();
819
+		$new_ticket = $this->_update_ticket_datetimes(
820
+			$new_ticket,
821
+			$datetimes_on_existing,
822
+			array_keys($datetimes_on_existing)
823
+		);
824
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
825
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
826
+		// available.
827
+		if ($ticket->sold() > 0) {
828
+			$new_qty = $ticket->qty() - $ticket->sold();
829
+			$new_ticket->set_qty($new_qty);
830
+		}
831
+		// now we update the prices just for this ticket
832
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
833
+		// and we update the base price
834
+		$new_ticket = $this->_add_prices_to_ticket(
835
+			array(),
836
+			$new_ticket,
837
+			true,
838
+			$base_price,
839
+			$base_price_id
840
+		);
841
+		return $new_ticket;
842
+	}
843 843
 
844 844
 
845
-    /**
846
-     * This attaches a list of given prices to a ticket.
847
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
848
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
849
-     * price info and prices are automatically "archived" via the ticket.
850
-     *
851
-     * @access  private
852
-     * @param array     $prices        Array of prices from the form.
853
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
854
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
855
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
856
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
857
-     * @return EE_Ticket
858
-     * @throws ReflectionException
859
-     * @throws InvalidArgumentException
860
-     * @throws InvalidInterfaceException
861
-     * @throws InvalidDataTypeException
862
-     * @throws EE_Error
863
-     */
864
-    protected function _add_prices_to_ticket(
865
-        $prices = array(),
866
-        EE_Ticket $ticket,
867
-        $new_prices = false,
868
-        $base_price = false,
869
-        $base_price_id = false
870
-    ) {
871
-        // let's just get any current prices that may exist on the given ticket
872
-        // so we can remove any prices that got trashed in this session.
873
-        $current_prices_on_ticket = $base_price !== false
874
-            ? $ticket->base_price(true)
875
-            : $ticket->price_modifiers();
876
-        $updated_prices = array();
877
-        // if $base_price ! FALSE then updating a base price.
878
-        if ($base_price !== false) {
879
-            $prices[1] = array(
880
-                'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
881
-                'PRT_ID'     => 1,
882
-                'PRC_amount' => $base_price,
883
-                'PRC_name'   => $ticket->get('TKT_name'),
884
-                'PRC_desc'   => $ticket->get('TKT_description'),
885
-            );
886
-        }
887
-        // possibly need to save tkt
888
-        if (! $ticket->ID()) {
889
-            $ticket->save();
890
-        }
891
-        foreach ($prices as $row => $prc) {
892
-            $prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
893
-            if (empty($prt_id)) {
894
-                continue;
895
-            } //prices MUST have a price type id.
896
-            $PRC_values = array(
897
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
898
-                'PRT_ID'         => $prt_id,
899
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
900
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
901
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
902
-                'PRC_is_default' => false,
903
-                // make sure we set PRC_is_default to false for all ticket saves from event_editor
904
-                'PRC_order'      => $row,
905
-            );
906
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
907
-                $PRC_values['PRC_ID'] = 0;
908
-                $price = EE_Registry::instance()->load_class(
909
-                    'Price',
910
-                    array($PRC_values),
911
-                    false,
912
-                    false
913
-                );
914
-            } else {
915
-                $price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
916
-                // update this price with new values
917
-                foreach ($PRC_values as $field => $value) {
918
-                    $price->set($field, $value);
919
-                }
920
-            }
921
-            $price->save();
922
-            $updated_prices[ $price->ID() ] = $price;
923
-            $ticket->_add_relation_to($price, 'Price');
924
-        }
925
-        // now let's remove any prices that got removed from the ticket
926
-        if (! empty($current_prices_on_ticket)) {
927
-            $current = array_keys($current_prices_on_ticket);
928
-            $updated = array_keys($updated_prices);
929
-            $prices_to_remove = array_diff($current, $updated);
930
-            if (! empty($prices_to_remove)) {
931
-                foreach ($prices_to_remove as $prc_id) {
932
-                    $p = $current_prices_on_ticket[ $prc_id ];
933
-                    $ticket->_remove_relation_to($p, 'Price');
934
-                    // delete permanently the price
935
-                    $p->delete_permanently();
936
-                }
937
-            }
938
-        }
939
-        return $ticket;
940
-    }
845
+	/**
846
+	 * This attaches a list of given prices to a ticket.
847
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
848
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
849
+	 * price info and prices are automatically "archived" via the ticket.
850
+	 *
851
+	 * @access  private
852
+	 * @param array     $prices        Array of prices from the form.
853
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
854
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
855
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
856
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
857
+	 * @return EE_Ticket
858
+	 * @throws ReflectionException
859
+	 * @throws InvalidArgumentException
860
+	 * @throws InvalidInterfaceException
861
+	 * @throws InvalidDataTypeException
862
+	 * @throws EE_Error
863
+	 */
864
+	protected function _add_prices_to_ticket(
865
+		$prices = array(),
866
+		EE_Ticket $ticket,
867
+		$new_prices = false,
868
+		$base_price = false,
869
+		$base_price_id = false
870
+	) {
871
+		// let's just get any current prices that may exist on the given ticket
872
+		// so we can remove any prices that got trashed in this session.
873
+		$current_prices_on_ticket = $base_price !== false
874
+			? $ticket->base_price(true)
875
+			: $ticket->price_modifiers();
876
+		$updated_prices = array();
877
+		// if $base_price ! FALSE then updating a base price.
878
+		if ($base_price !== false) {
879
+			$prices[1] = array(
880
+				'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
881
+				'PRT_ID'     => 1,
882
+				'PRC_amount' => $base_price,
883
+				'PRC_name'   => $ticket->get('TKT_name'),
884
+				'PRC_desc'   => $ticket->get('TKT_description'),
885
+			);
886
+		}
887
+		// possibly need to save tkt
888
+		if (! $ticket->ID()) {
889
+			$ticket->save();
890
+		}
891
+		foreach ($prices as $row => $prc) {
892
+			$prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
893
+			if (empty($prt_id)) {
894
+				continue;
895
+			} //prices MUST have a price type id.
896
+			$PRC_values = array(
897
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
898
+				'PRT_ID'         => $prt_id,
899
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
900
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
901
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
902
+				'PRC_is_default' => false,
903
+				// make sure we set PRC_is_default to false for all ticket saves from event_editor
904
+				'PRC_order'      => $row,
905
+			);
906
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
907
+				$PRC_values['PRC_ID'] = 0;
908
+				$price = EE_Registry::instance()->load_class(
909
+					'Price',
910
+					array($PRC_values),
911
+					false,
912
+					false
913
+				);
914
+			} else {
915
+				$price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
916
+				// update this price with new values
917
+				foreach ($PRC_values as $field => $value) {
918
+					$price->set($field, $value);
919
+				}
920
+			}
921
+			$price->save();
922
+			$updated_prices[ $price->ID() ] = $price;
923
+			$ticket->_add_relation_to($price, 'Price');
924
+		}
925
+		// now let's remove any prices that got removed from the ticket
926
+		if (! empty($current_prices_on_ticket)) {
927
+			$current = array_keys($current_prices_on_ticket);
928
+			$updated = array_keys($updated_prices);
929
+			$prices_to_remove = array_diff($current, $updated);
930
+			if (! empty($prices_to_remove)) {
931
+				foreach ($prices_to_remove as $prc_id) {
932
+					$p = $current_prices_on_ticket[ $prc_id ];
933
+					$ticket->_remove_relation_to($p, 'Price');
934
+					// delete permanently the price
935
+					$p->delete_permanently();
936
+				}
937
+			}
938
+		}
939
+		return $ticket;
940
+	}
941 941
 
942 942
 
943
-    /**
944
-     * @param Events_Admin_Page $event_admin_obj
945
-     * @return Events_Admin_Page
946
-     */
947
-    public function autosave_handling(Events_Admin_Page $event_admin_obj)
948
-    {
949
-        return $event_admin_obj;
950
-        // doing nothing for the moment.
951
-        // todo when I get to this remember that I need to set the template args on the $event_admin_obj
952
-        // (use the set_template_args() method)
953
-        /**
954
-         * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
955
-         * 1. TKT_is_default_selector (visible)
956
-         * 2. TKT_is_default (hidden)
957
-         * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
958
-         * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
959
-         * this ticket to be saved as a default.
960
-         * The tricky part is, on an initial display on create or edit (or after manually updating),
961
-         * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
962
-         * if this is a create.  However, after an autosave, users will want some sort of indicator that
963
-         * the TKT HAS been saved as a default..
964
-         * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
965
-         * On Autosave:
966
-         * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
967
-         * then set the TKT_is_default to false.
968
-         * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
969
-         *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
970
-         * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
971
-         */
972
-    }
943
+	/**
944
+	 * @param Events_Admin_Page $event_admin_obj
945
+	 * @return Events_Admin_Page
946
+	 */
947
+	public function autosave_handling(Events_Admin_Page $event_admin_obj)
948
+	{
949
+		return $event_admin_obj;
950
+		// doing nothing for the moment.
951
+		// todo when I get to this remember that I need to set the template args on the $event_admin_obj
952
+		// (use the set_template_args() method)
953
+		/**
954
+		 * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
955
+		 * 1. TKT_is_default_selector (visible)
956
+		 * 2. TKT_is_default (hidden)
957
+		 * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
958
+		 * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
959
+		 * this ticket to be saved as a default.
960
+		 * The tricky part is, on an initial display on create or edit (or after manually updating),
961
+		 * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
962
+		 * if this is a create.  However, after an autosave, users will want some sort of indicator that
963
+		 * the TKT HAS been saved as a default..
964
+		 * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
965
+		 * On Autosave:
966
+		 * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
967
+		 * then set the TKT_is_default to false.
968
+		 * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
969
+		 *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
970
+		 * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
971
+		 */
972
+	}
973 973
 
974 974
 
975
-    /**
976
-     * @throws ReflectionException
977
-     * @throws InvalidArgumentException
978
-     * @throws InvalidInterfaceException
979
-     * @throws InvalidDataTypeException
980
-     * @throws DomainException
981
-     * @throws EE_Error
982
-     */
983
-    public function pricing_metabox()
984
-    {
985
-        $existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
986
-        $event = $this->_adminpage_obj->get_cpt_model_obj();
987
-        // set is_creating_event property.
988
-        $EVT_ID = $event->ID();
989
-        $this->_is_creating_event = empty($this->_req_data['post']);
990
-        // default main template args
991
-        $main_template_args = array(
992
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link(
993
-                'event_editor_event_datetimes_help_tab',
994
-                $this->_adminpage_obj->page_slug,
995
-                $this->_adminpage_obj->get_req_action(),
996
-                false,
997
-                false
998
-            ),
999
-            // todo need to add a filter to the template for the help text
1000
-            // in the Events_Admin_Page core file so we can add further help
1001
-            'existing_datetime_ids'    => '',
1002
-            'total_dtt_rows'           => 1,
1003
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1004
-                'add_new_dtt_info',
1005
-                $this->_adminpage_obj->page_slug,
1006
-                $this->_adminpage_obj->get_req_action(),
1007
-                false,
1008
-                false
1009
-            ),
1010
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1011
-            'datetime_rows'            => '',
1012
-            'show_tickets_container'   => '',
1013
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1014
-            'ticket_rows'              => '',
1015
-            'existing_ticket_ids'      => '',
1016
-            'total_ticket_rows'        => 1,
1017
-            'ticket_js_structure'      => '',
1018
-            'ee_collapsible_status'    => ' ee-collapsible-open'
1019
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1020
-        );
1021
-        $timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1022
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1023
-        /**
1024
-         * 1. Start with retrieving Datetimes
1025
-         * 2. For each datetime get related tickets
1026
-         * 3. For each ticket get related prices
1027
-         */
1028
-        /** @var EEM_Datetime $datetime_model */
1029
-        $datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1030
-        $datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1031
-        $main_template_args['total_dtt_rows'] = count($datetimes);
1032
-        /**
1033
-         * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1034
-         * for why we are counting $datetime_row and then setting that on the Datetime object
1035
-         */
1036
-        $datetime_row = 1;
1037
-        foreach ($datetimes as $datetime) {
1038
-            $DTT_ID = $datetime->get('DTT_ID');
1039
-            $datetime->set('DTT_order', $datetime_row);
1040
-            $existing_datetime_ids[] = $DTT_ID;
1041
-            // tickets attached
1042
-            $related_tickets = $datetime->ID() > 0
1043
-                ? $datetime->get_many_related(
1044
-                    'Ticket',
1045
-                    array(
1046
-                        array(
1047
-                            'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1048
-                        ),
1049
-                        'default_where_conditions' => 'none',
1050
-                        'order_by'                 => array('TKT_order' => 'ASC'),
1051
-                    )
1052
-                )
1053
-                : array();
1054
-            // if there are no related tickets this is likely a new event OR autodraft
1055
-            // event so we need to generate the default tickets because datetimes
1056
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1057
-            // datetime on the event.
1058
-            if (empty($related_tickets) && count($datetimes) < 2) {
1059
-                /** @var EEM_Ticket $ticket_model */
1060
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
1061
-                $related_tickets = $ticket_model->get_all_default_tickets();
1062
-                // this should be ordered by TKT_ID, so let's grab the first default ticket
1063
-                // (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1064
-                $default_prices = EEM_Price::instance()->get_all_default_prices();
1065
-                $main_default_ticket = reset($related_tickets);
1066
-                if ($main_default_ticket instanceof EE_Ticket) {
1067
-                    foreach ($default_prices as $default_price) {
1068
-                        if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1069
-                            continue;
1070
-                        }
1071
-                        $main_default_ticket->cache('Price', $default_price);
1072
-                    }
1073
-                }
1074
-            }
1075
-            // we can't actually setup rows in this loop yet cause we don't know all
1076
-            // the unique tickets for this event yet (tickets are linked through all datetimes).
1077
-            // So we're going to temporarily cache some of that information.
1078
-            // loop through and setup the ticket rows and make sure the order is set.
1079
-            foreach ($related_tickets as $ticket) {
1080
-                $TKT_ID = $ticket->get('TKT_ID');
1081
-                $ticket_row = $ticket->get('TKT_row');
1082
-                // we only want unique tickets in our final display!!
1083
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1084
-                    $existing_ticket_ids[] = $TKT_ID;
1085
-                    $all_tickets[] = $ticket;
1086
-                }
1087
-                // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1088
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1089
-                // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1090
-                if (
1091
-                    ! isset($ticket_datetimes[ $TKT_ID ])
1092
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1093
-                ) {
1094
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1095
-                }
1096
-            }
1097
-            $datetime_row++;
1098
-        }
1099
-        $main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1100
-        $main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1101
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1102
-        // sort $all_tickets by order
1103
-        usort(
1104
-            $all_tickets,
1105
-            function (EE_Ticket $a, EE_Ticket $b) {
1106
-                $a_order = (int) $a->get('TKT_order');
1107
-                $b_order = (int) $b->get('TKT_order');
1108
-                if ($a_order === $b_order) {
1109
-                    return 0;
1110
-                }
1111
-                return ($a_order < $b_order) ? -1 : 1;
1112
-            }
1113
-        );
1114
-        // k NOW we have all the data we need for setting up the dtt rows
1115
-        // and ticket rows so we start our dtt loop again.
1116
-        $datetime_row = 1;
1117
-        foreach ($datetimes as $datetime) {
1118
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1119
-                $datetime_row,
1120
-                $datetime,
1121
-                $datetime_tickets,
1122
-                $all_tickets,
1123
-                false,
1124
-                $datetimes
1125
-            );
1126
-            $datetime_row++;
1127
-        }
1128
-        // then loop through all tickets for the ticket rows.
1129
-        $ticket_row = 1;
1130
-        foreach ($all_tickets as $ticket) {
1131
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1132
-                $ticket_row,
1133
-                $ticket,
1134
-                $ticket_datetimes,
1135
-                $datetimes,
1136
-                false,
1137
-                $all_tickets
1138
-            );
1139
-            $ticket_row++;
1140
-        }
1141
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
975
+	/**
976
+	 * @throws ReflectionException
977
+	 * @throws InvalidArgumentException
978
+	 * @throws InvalidInterfaceException
979
+	 * @throws InvalidDataTypeException
980
+	 * @throws DomainException
981
+	 * @throws EE_Error
982
+	 */
983
+	public function pricing_metabox()
984
+	{
985
+		$existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
986
+		$event = $this->_adminpage_obj->get_cpt_model_obj();
987
+		// set is_creating_event property.
988
+		$EVT_ID = $event->ID();
989
+		$this->_is_creating_event = empty($this->_req_data['post']);
990
+		// default main template args
991
+		$main_template_args = array(
992
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link(
993
+				'event_editor_event_datetimes_help_tab',
994
+				$this->_adminpage_obj->page_slug,
995
+				$this->_adminpage_obj->get_req_action(),
996
+				false,
997
+				false
998
+			),
999
+			// todo need to add a filter to the template for the help text
1000
+			// in the Events_Admin_Page core file so we can add further help
1001
+			'existing_datetime_ids'    => '',
1002
+			'total_dtt_rows'           => 1,
1003
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1004
+				'add_new_dtt_info',
1005
+				$this->_adminpage_obj->page_slug,
1006
+				$this->_adminpage_obj->get_req_action(),
1007
+				false,
1008
+				false
1009
+			),
1010
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1011
+			'datetime_rows'            => '',
1012
+			'show_tickets_container'   => '',
1013
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1014
+			'ticket_rows'              => '',
1015
+			'existing_ticket_ids'      => '',
1016
+			'total_ticket_rows'        => 1,
1017
+			'ticket_js_structure'      => '',
1018
+			'ee_collapsible_status'    => ' ee-collapsible-open'
1019
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1020
+		);
1021
+		$timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1022
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1023
+		/**
1024
+		 * 1. Start with retrieving Datetimes
1025
+		 * 2. For each datetime get related tickets
1026
+		 * 3. For each ticket get related prices
1027
+		 */
1028
+		/** @var EEM_Datetime $datetime_model */
1029
+		$datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1030
+		$datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1031
+		$main_template_args['total_dtt_rows'] = count($datetimes);
1032
+		/**
1033
+		 * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1034
+		 * for why we are counting $datetime_row and then setting that on the Datetime object
1035
+		 */
1036
+		$datetime_row = 1;
1037
+		foreach ($datetimes as $datetime) {
1038
+			$DTT_ID = $datetime->get('DTT_ID');
1039
+			$datetime->set('DTT_order', $datetime_row);
1040
+			$existing_datetime_ids[] = $DTT_ID;
1041
+			// tickets attached
1042
+			$related_tickets = $datetime->ID() > 0
1043
+				? $datetime->get_many_related(
1044
+					'Ticket',
1045
+					array(
1046
+						array(
1047
+							'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1048
+						),
1049
+						'default_where_conditions' => 'none',
1050
+						'order_by'                 => array('TKT_order' => 'ASC'),
1051
+					)
1052
+				)
1053
+				: array();
1054
+			// if there are no related tickets this is likely a new event OR autodraft
1055
+			// event so we need to generate the default tickets because datetimes
1056
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1057
+			// datetime on the event.
1058
+			if (empty($related_tickets) && count($datetimes) < 2) {
1059
+				/** @var EEM_Ticket $ticket_model */
1060
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
1061
+				$related_tickets = $ticket_model->get_all_default_tickets();
1062
+				// this should be ordered by TKT_ID, so let's grab the first default ticket
1063
+				// (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1064
+				$default_prices = EEM_Price::instance()->get_all_default_prices();
1065
+				$main_default_ticket = reset($related_tickets);
1066
+				if ($main_default_ticket instanceof EE_Ticket) {
1067
+					foreach ($default_prices as $default_price) {
1068
+						if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1069
+							continue;
1070
+						}
1071
+						$main_default_ticket->cache('Price', $default_price);
1072
+					}
1073
+				}
1074
+			}
1075
+			// we can't actually setup rows in this loop yet cause we don't know all
1076
+			// the unique tickets for this event yet (tickets are linked through all datetimes).
1077
+			// So we're going to temporarily cache some of that information.
1078
+			// loop through and setup the ticket rows and make sure the order is set.
1079
+			foreach ($related_tickets as $ticket) {
1080
+				$TKT_ID = $ticket->get('TKT_ID');
1081
+				$ticket_row = $ticket->get('TKT_row');
1082
+				// we only want unique tickets in our final display!!
1083
+				if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1084
+					$existing_ticket_ids[] = $TKT_ID;
1085
+					$all_tickets[] = $ticket;
1086
+				}
1087
+				// temporary cache of this ticket info for this datetime for later processing of datetime rows.
1088
+				$datetime_tickets[ $DTT_ID ][] = $ticket_row;
1089
+				// temporary cache of this datetime info for this ticket for later processing of ticket rows.
1090
+				if (
1091
+					! isset($ticket_datetimes[ $TKT_ID ])
1092
+					|| ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1093
+				) {
1094
+					$ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1095
+				}
1096
+			}
1097
+			$datetime_row++;
1098
+		}
1099
+		$main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1100
+		$main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1101
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1102
+		// sort $all_tickets by order
1103
+		usort(
1104
+			$all_tickets,
1105
+			function (EE_Ticket $a, EE_Ticket $b) {
1106
+				$a_order = (int) $a->get('TKT_order');
1107
+				$b_order = (int) $b->get('TKT_order');
1108
+				if ($a_order === $b_order) {
1109
+					return 0;
1110
+				}
1111
+				return ($a_order < $b_order) ? -1 : 1;
1112
+			}
1113
+		);
1114
+		// k NOW we have all the data we need for setting up the dtt rows
1115
+		// and ticket rows so we start our dtt loop again.
1116
+		$datetime_row = 1;
1117
+		foreach ($datetimes as $datetime) {
1118
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1119
+				$datetime_row,
1120
+				$datetime,
1121
+				$datetime_tickets,
1122
+				$all_tickets,
1123
+				false,
1124
+				$datetimes
1125
+			);
1126
+			$datetime_row++;
1127
+		}
1128
+		// then loop through all tickets for the ticket rows.
1129
+		$ticket_row = 1;
1130
+		foreach ($all_tickets as $ticket) {
1131
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1132
+				$ticket_row,
1133
+				$ticket,
1134
+				$ticket_datetimes,
1135
+				$datetimes,
1136
+				false,
1137
+				$all_tickets
1138
+			);
1139
+			$ticket_row++;
1140
+		}
1141
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1142 1142
 
1143
-        $status_change_notice = EventEspresso\core\services\loaders\LoaderFactory::getLoader()->getShared(
1144
-            'EventEspresso\core\admin\StatusChangeNotice'
1145
-        );
1146
-        if (! $status_change_notice->isDismissed()) {
1147
-            $main_template_args['status_change_notice'] = EEH_Template::display_template(
1148
-                EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1149
-                ['context' => '__event-editor', 'page_slug' => 'espresso-events'],
1150
-                true
1151
-            );
1152
-        }
1143
+		$status_change_notice = EventEspresso\core\services\loaders\LoaderFactory::getLoader()->getShared(
1144
+			'EventEspresso\core\admin\StatusChangeNotice'
1145
+		);
1146
+		if (! $status_change_notice->isDismissed()) {
1147
+			$main_template_args['status_change_notice'] = EEH_Template::display_template(
1148
+				EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1149
+				['context' => '__event-editor', 'page_slug' => 'espresso-events'],
1150
+				true
1151
+			);
1152
+		}
1153 1153
 
1154
-        EEH_Template::display_template(
1155
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1156
-            $main_template_args
1157
-        );
1158
-    }
1154
+		EEH_Template::display_template(
1155
+			PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1156
+			$main_template_args
1157
+		);
1158
+	}
1159 1159
 
1160 1160
 
1161
-    /**
1162
-     * @param int         $datetime_row
1163
-     * @param EE_Datetime $datetime
1164
-     * @param array       $datetime_tickets
1165
-     * @param array       $all_tickets
1166
-     * @param bool        $default
1167
-     * @param array       $all_datetimes
1168
-     * @return mixed
1169
-     * @throws DomainException
1170
-     * @throws EE_Error
1171
-     */
1172
-    protected function _get_datetime_row(
1173
-        $datetime_row,
1174
-        EE_Datetime $datetime,
1175
-        $datetime_tickets = array(),
1176
-        $all_tickets = array(),
1177
-        $default = false,
1178
-        $all_datetimes = array()
1179
-    ) {
1180
-        $dtt_display_template_args = array(
1181
-            'dtt_edit_row'             => $this->_get_dtt_edit_row(
1182
-                $datetime_row,
1183
-                $datetime,
1184
-                $default,
1185
-                $all_datetimes
1186
-            ),
1187
-            'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1188
-                $datetime_row,
1189
-                $datetime,
1190
-                $datetime_tickets,
1191
-                $all_tickets,
1192
-                $default
1193
-            ),
1194
-            'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1195
-        );
1196
-        return EEH_Template::display_template(
1197
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1198
-            $dtt_display_template_args,
1199
-            true
1200
-        );
1201
-    }
1161
+	/**
1162
+	 * @param int         $datetime_row
1163
+	 * @param EE_Datetime $datetime
1164
+	 * @param array       $datetime_tickets
1165
+	 * @param array       $all_tickets
1166
+	 * @param bool        $default
1167
+	 * @param array       $all_datetimes
1168
+	 * @return mixed
1169
+	 * @throws DomainException
1170
+	 * @throws EE_Error
1171
+	 */
1172
+	protected function _get_datetime_row(
1173
+		$datetime_row,
1174
+		EE_Datetime $datetime,
1175
+		$datetime_tickets = array(),
1176
+		$all_tickets = array(),
1177
+		$default = false,
1178
+		$all_datetimes = array()
1179
+	) {
1180
+		$dtt_display_template_args = array(
1181
+			'dtt_edit_row'             => $this->_get_dtt_edit_row(
1182
+				$datetime_row,
1183
+				$datetime,
1184
+				$default,
1185
+				$all_datetimes
1186
+			),
1187
+			'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1188
+				$datetime_row,
1189
+				$datetime,
1190
+				$datetime_tickets,
1191
+				$all_tickets,
1192
+				$default
1193
+			),
1194
+			'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1195
+		);
1196
+		return EEH_Template::display_template(
1197
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1198
+			$dtt_display_template_args,
1199
+			true
1200
+		);
1201
+	}
1202 1202
 
1203 1203
 
1204
-    /**
1205
-     * This method is used to generate a dtt fields  edit row.
1206
-     * The same row is used to generate a row with valid DTT objects
1207
-     * and the default row that is used as the skeleton by the js.
1208
-     *
1209
-     * @param int           $datetime_row  The row number for the row being generated.
1210
-     * @param EE_Datetime   $datetime
1211
-     * @param bool          $default       Whether a default row is being generated or not.
1212
-     * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1213
-     * @return string
1214
-     * @throws DomainException
1215
-     * @throws EE_Error
1216
-     */
1217
-    protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1218
-    {
1219
-        // if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1220
-        $default = ! $datetime instanceof EE_Datetime ? true : $default;
1221
-        $template_args = array(
1222
-            'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1223
-            'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1224
-            'edit_dtt_expanded'    => '',
1225
-            'DTT_ID'               => $default ? '' : $datetime->ID(),
1226
-            'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1227
-            'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1228
-            'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1229
-            'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1230
-            'DTT_reg_limit'        => $default
1231
-                ? ''
1232
-                : $datetime->get_pretty(
1233
-                    'DTT_reg_limit',
1234
-                    'input'
1235
-                ),
1236
-            'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1237
-            'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1238
-            'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1239
-            'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1240
-                ? ''
1241
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1242
-            'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1243
-                ? 'ee-lock-icon'
1244
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1245
-            'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1246
-                ? ''
1247
-                : EE_Admin_Page::add_query_args_and_nonce(
1248
-                    array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1249
-                    REG_ADMIN_URL
1250
-                ),
1251
-        );
1252
-        $template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1253
-            ? ' style="display:none"'
1254
-            : '';
1255
-        // allow filtering of template args at this point.
1256
-        $template_args = apply_filters(
1257
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1258
-            $template_args,
1259
-            $datetime_row,
1260
-            $datetime,
1261
-            $default,
1262
-            $all_datetimes,
1263
-            $this->_is_creating_event
1264
-        );
1265
-        return EEH_Template::display_template(
1266
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1267
-            $template_args,
1268
-            true
1269
-        );
1270
-    }
1204
+	/**
1205
+	 * This method is used to generate a dtt fields  edit row.
1206
+	 * The same row is used to generate a row with valid DTT objects
1207
+	 * and the default row that is used as the skeleton by the js.
1208
+	 *
1209
+	 * @param int           $datetime_row  The row number for the row being generated.
1210
+	 * @param EE_Datetime   $datetime
1211
+	 * @param bool          $default       Whether a default row is being generated or not.
1212
+	 * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1213
+	 * @return string
1214
+	 * @throws DomainException
1215
+	 * @throws EE_Error
1216
+	 */
1217
+	protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1218
+	{
1219
+		// if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1220
+		$default = ! $datetime instanceof EE_Datetime ? true : $default;
1221
+		$template_args = array(
1222
+			'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1223
+			'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1224
+			'edit_dtt_expanded'    => '',
1225
+			'DTT_ID'               => $default ? '' : $datetime->ID(),
1226
+			'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1227
+			'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1228
+			'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1229
+			'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1230
+			'DTT_reg_limit'        => $default
1231
+				? ''
1232
+				: $datetime->get_pretty(
1233
+					'DTT_reg_limit',
1234
+					'input'
1235
+				),
1236
+			'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1237
+			'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1238
+			'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1239
+			'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1240
+				? ''
1241
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1242
+			'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1243
+				? 'ee-lock-icon'
1244
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1245
+			'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1246
+				? ''
1247
+				: EE_Admin_Page::add_query_args_and_nonce(
1248
+					array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1249
+					REG_ADMIN_URL
1250
+				),
1251
+		);
1252
+		$template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1253
+			? ' style="display:none"'
1254
+			: '';
1255
+		// allow filtering of template args at this point.
1256
+		$template_args = apply_filters(
1257
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1258
+			$template_args,
1259
+			$datetime_row,
1260
+			$datetime,
1261
+			$default,
1262
+			$all_datetimes,
1263
+			$this->_is_creating_event
1264
+		);
1265
+		return EEH_Template::display_template(
1266
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1267
+			$template_args,
1268
+			true
1269
+		);
1270
+	}
1271 1271
 
1272 1272
 
1273
-    /**
1274
-     * @param int         $datetime_row
1275
-     * @param EE_Datetime $datetime
1276
-     * @param array       $datetime_tickets
1277
-     * @param array       $all_tickets
1278
-     * @param bool        $default
1279
-     * @return mixed
1280
-     * @throws DomainException
1281
-     * @throws EE_Error
1282
-     */
1283
-    protected function _get_dtt_attached_tickets_row(
1284
-        $datetime_row,
1285
-        $datetime,
1286
-        $datetime_tickets = array(),
1287
-        $all_tickets = array(),
1288
-        $default
1289
-    ) {
1290
-        $template_args = array(
1291
-            'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1292
-            'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1293
-            'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1294
-            'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1295
-            'show_tickets_row'                  => ' style="display:none;"',
1296
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1297
-                'add_new_ticket_via_datetime',
1298
-                $this->_adminpage_obj->page_slug,
1299
-                $this->_adminpage_obj->get_req_action(),
1300
-                false,
1301
-                false
1302
-            ),
1303
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1304
-            'DTT_ID'                            => $default ? '' : $datetime->ID(),
1305
-        );
1306
-        // need to setup the list items (but only if this isn't a default skeleton setup)
1307
-        if (! $default) {
1308
-            $ticket_row = 1;
1309
-            foreach ($all_tickets as $ticket) {
1310
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1311
-                    $datetime_row,
1312
-                    $ticket_row,
1313
-                    $datetime,
1314
-                    $ticket,
1315
-                    $datetime_tickets,
1316
-                    $default
1317
-                );
1318
-                $ticket_row++;
1319
-            }
1320
-        }
1321
-        // filter template args at this point
1322
-        $template_args = apply_filters(
1323
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1324
-            $template_args,
1325
-            $datetime_row,
1326
-            $datetime,
1327
-            $datetime_tickets,
1328
-            $all_tickets,
1329
-            $default,
1330
-            $this->_is_creating_event
1331
-        );
1332
-        return EEH_Template::display_template(
1333
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1334
-            $template_args,
1335
-            true
1336
-        );
1337
-    }
1273
+	/**
1274
+	 * @param int         $datetime_row
1275
+	 * @param EE_Datetime $datetime
1276
+	 * @param array       $datetime_tickets
1277
+	 * @param array       $all_tickets
1278
+	 * @param bool        $default
1279
+	 * @return mixed
1280
+	 * @throws DomainException
1281
+	 * @throws EE_Error
1282
+	 */
1283
+	protected function _get_dtt_attached_tickets_row(
1284
+		$datetime_row,
1285
+		$datetime,
1286
+		$datetime_tickets = array(),
1287
+		$all_tickets = array(),
1288
+		$default
1289
+	) {
1290
+		$template_args = array(
1291
+			'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1292
+			'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1293
+			'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1294
+			'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1295
+			'show_tickets_row'                  => ' style="display:none;"',
1296
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1297
+				'add_new_ticket_via_datetime',
1298
+				$this->_adminpage_obj->page_slug,
1299
+				$this->_adminpage_obj->get_req_action(),
1300
+				false,
1301
+				false
1302
+			),
1303
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1304
+			'DTT_ID'                            => $default ? '' : $datetime->ID(),
1305
+		);
1306
+		// need to setup the list items (but only if this isn't a default skeleton setup)
1307
+		if (! $default) {
1308
+			$ticket_row = 1;
1309
+			foreach ($all_tickets as $ticket) {
1310
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1311
+					$datetime_row,
1312
+					$ticket_row,
1313
+					$datetime,
1314
+					$ticket,
1315
+					$datetime_tickets,
1316
+					$default
1317
+				);
1318
+				$ticket_row++;
1319
+			}
1320
+		}
1321
+		// filter template args at this point
1322
+		$template_args = apply_filters(
1323
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1324
+			$template_args,
1325
+			$datetime_row,
1326
+			$datetime,
1327
+			$datetime_tickets,
1328
+			$all_tickets,
1329
+			$default,
1330
+			$this->_is_creating_event
1331
+		);
1332
+		return EEH_Template::display_template(
1333
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1334
+			$template_args,
1335
+			true
1336
+		);
1337
+	}
1338 1338
 
1339 1339
 
1340
-    /**
1341
-     * @param int         $datetime_row
1342
-     * @param int         $ticket_row
1343
-     * @param EE_Datetime $datetime
1344
-     * @param EE_Ticket   $ticket
1345
-     * @param array       $datetime_tickets
1346
-     * @param bool        $default
1347
-     * @return mixed
1348
-     * @throws DomainException
1349
-     * @throws EE_Error
1350
-     */
1351
-    protected function _get_datetime_tickets_list_item(
1352
-        $datetime_row,
1353
-        $ticket_row,
1354
-        $datetime,
1355
-        $ticket,
1356
-        $datetime_tickets = array(),
1357
-        $default
1358
-    ) {
1359
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1360
-            ? $datetime_tickets[ $datetime->ID() ]
1361
-            : array();
1362
-        $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1363
-        $no_ticket = $default && empty($ticket);
1364
-        $template_args = array(
1365
-            'dtt_row'                 => $default
1366
-                ? 'DTTNUM'
1367
-                : $datetime_row,
1368
-            'tkt_row'                 => $no_ticket
1369
-                ? 'TICKETNUM'
1370
-                : $ticket_row,
1371
-            'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1372
-                ? ' checked="checked"'
1373
-                : '',
1374
-            'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1375
-                ? ' ticket-selected'
1376
-                : '',
1377
-            'TKT_name'                => $no_ticket
1378
-                ? 'TKTNAME'
1379
-                : $ticket->get('TKT_name'),
1380
-            'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1381
-                ? ' tkt-status-' . EE_Ticket::onsale
1382
-                : ' tkt-status-' . $ticket->ticket_status(),
1383
-        );
1384
-        // filter template args
1385
-        $template_args = apply_filters(
1386
-            'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1387
-            $template_args,
1388
-            $datetime_row,
1389
-            $ticket_row,
1390
-            $datetime,
1391
-            $ticket,
1392
-            $datetime_tickets,
1393
-            $default,
1394
-            $this->_is_creating_event
1395
-        );
1396
-        return EEH_Template::display_template(
1397
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1398
-            $template_args,
1399
-            true
1400
-        );
1401
-    }
1340
+	/**
1341
+	 * @param int         $datetime_row
1342
+	 * @param int         $ticket_row
1343
+	 * @param EE_Datetime $datetime
1344
+	 * @param EE_Ticket   $ticket
1345
+	 * @param array       $datetime_tickets
1346
+	 * @param bool        $default
1347
+	 * @return mixed
1348
+	 * @throws DomainException
1349
+	 * @throws EE_Error
1350
+	 */
1351
+	protected function _get_datetime_tickets_list_item(
1352
+		$datetime_row,
1353
+		$ticket_row,
1354
+		$datetime,
1355
+		$ticket,
1356
+		$datetime_tickets = array(),
1357
+		$default
1358
+	) {
1359
+		$dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1360
+			? $datetime_tickets[ $datetime->ID() ]
1361
+			: array();
1362
+		$display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1363
+		$no_ticket = $default && empty($ticket);
1364
+		$template_args = array(
1365
+			'dtt_row'                 => $default
1366
+				? 'DTTNUM'
1367
+				: $datetime_row,
1368
+			'tkt_row'                 => $no_ticket
1369
+				? 'TICKETNUM'
1370
+				: $ticket_row,
1371
+			'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1372
+				? ' checked="checked"'
1373
+				: '',
1374
+			'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1375
+				? ' ticket-selected'
1376
+				: '',
1377
+			'TKT_name'                => $no_ticket
1378
+				? 'TKTNAME'
1379
+				: $ticket->get('TKT_name'),
1380
+			'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1381
+				? ' tkt-status-' . EE_Ticket::onsale
1382
+				: ' tkt-status-' . $ticket->ticket_status(),
1383
+		);
1384
+		// filter template args
1385
+		$template_args = apply_filters(
1386
+			'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1387
+			$template_args,
1388
+			$datetime_row,
1389
+			$ticket_row,
1390
+			$datetime,
1391
+			$ticket,
1392
+			$datetime_tickets,
1393
+			$default,
1394
+			$this->_is_creating_event
1395
+		);
1396
+		return EEH_Template::display_template(
1397
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1398
+			$template_args,
1399
+			true
1400
+		);
1401
+	}
1402 1402
 
1403 1403
 
1404
-    /**
1405
-     * This generates the ticket row for tickets.
1406
-     * This same method is used to generate both the actual rows and the js skeleton row
1407
-     * (when default === true)
1408
-     *
1409
-     * @param int           $ticket_row       Represents the row number being generated.
1410
-     * @param               $ticket
1411
-     * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1412
-     *                                        or empty for default
1413
-     * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1414
-     * @param bool          $default          Whether default row being generated or not.
1415
-     * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1416
-     *                                        (or empty in the case of defaults)
1417
-     * @return mixed
1418
-     * @throws InvalidArgumentException
1419
-     * @throws InvalidInterfaceException
1420
-     * @throws InvalidDataTypeException
1421
-     * @throws DomainException
1422
-     * @throws EE_Error
1423
-     * @throws ReflectionException
1424
-     */
1425
-    protected function _get_ticket_row(
1426
-        $ticket_row,
1427
-        $ticket,
1428
-        $ticket_datetimes,
1429
-        $all_datetimes,
1430
-        $default = false,
1431
-        $all_tickets = array()
1432
-    ) {
1433
-        // if $ticket is not an instance of EE_Ticket then force default to true.
1434
-        $default = ! $ticket instanceof EE_Ticket ? true : $default;
1435
-        $prices = ! empty($ticket) && ! $default
1436
-            ? $ticket->get_many_related(
1437
-                'Price',
1438
-                array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1439
-            )
1440
-            : array();
1441
-        // if there is only one price (which would be the base price)
1442
-        // or NO prices and this ticket is a default ticket,
1443
-        // let's just make sure there are no cached default prices on the object.
1444
-        // This is done by not including any query_params.
1445
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1446
-            $prices = $ticket->prices();
1447
-        }
1448
-        // check if we're dealing with a default ticket in which case
1449
-        // we don't want any starting_ticket_datetime_row values set
1450
-        // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1451
-        // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1452
-        $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1453
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1454
-            ? $ticket_datetimes[ $ticket->ID() ]
1455
-            : array();
1456
-        $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1457
-        $base_price = $default ? null : $ticket->base_price();
1458
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1459
-        // breaking out complicated condition for ticket_status
1460
-        if ($default) {
1461
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1462
-        } else {
1463
-            $ticket_status_class = $ticket->is_default()
1464
-                ? ' tkt-status-' . EE_Ticket::onsale
1465
-                : ' tkt-status-' . $ticket->ticket_status();
1466
-        }
1467
-        // breaking out complicated condition for TKT_taxable
1468
-        if ($default) {
1469
-            $TKT_taxable = '';
1470
-        } else {
1471
-            $TKT_taxable = $ticket->taxable()
1472
-                ? ' checked="checked"'
1473
-                : '';
1474
-        }
1475
-        if ($default) {
1476
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1477
-        } elseif ($ticket->is_default()) {
1478
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1479
-        } else {
1480
-            $TKT_status = $ticket->ticket_status(true);
1481
-        }
1482
-        if ($default) {
1483
-            $TKT_min = '';
1484
-        } else {
1485
-            $TKT_min = $ticket->min();
1486
-            if ($TKT_min === -1 || $TKT_min === 0) {
1487
-                $TKT_min = '';
1488
-            }
1489
-        }
1490
-        $template_args = array(
1491
-            'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1492
-            'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1493
-            // on initial page load this will always be the correct order.
1494
-            'tkt_status_class'              => $ticket_status_class,
1495
-            'display_edit_tkt_row'          => ' style="display:none;"',
1496
-            'edit_tkt_expanded'             => '',
1497
-            'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1498
-            'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1499
-            'TKT_start_date'                => $default
1500
-                ? ''
1501
-                : $ticket->get_date('TKT_start_date', $this->_date_time_format),
1502
-            'TKT_end_date'                  => $default
1503
-                ? ''
1504
-                : $ticket->get_date('TKT_end_date', $this->_date_time_format),
1505
-            'TKT_status'                    => $TKT_status,
1506
-            'TKT_price'                     => $default
1507
-                ? ''
1508
-                : EEH_Template::format_currency(
1509
-                    $ticket->get_ticket_total_with_taxes(),
1510
-                    false,
1511
-                    false
1512
-                ),
1513
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1514
-            'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1515
-            'TKT_qty'                       => $default
1516
-                ? ''
1517
-                : $ticket->get_pretty('TKT_qty', 'symbol'),
1518
-            'TKT_qty_for_input'             => $default
1519
-                ? ''
1520
-                : $ticket->get_pretty('TKT_qty', 'input'),
1521
-            'TKT_uses'                      => $default
1522
-                ? ''
1523
-                : $ticket->get_pretty('TKT_uses', 'input'),
1524
-            'TKT_min'                       => $TKT_min,
1525
-            'TKT_max'                       => $default
1526
-                ? ''
1527
-                : $ticket->get_pretty('TKT_max', 'input'),
1528
-            'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1529
-            'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1530
-            'TKT_registrations'             => $default
1531
-                ? 0
1532
-                : $ticket->count_registrations(
1533
-                    array(
1534
-                        array(
1535
-                            'STS_ID' => array(
1536
-                                '!=',
1537
-                                EEM_Registration::status_id_incomplete,
1538
-                            ),
1539
-                        ),
1540
-                    )
1541
-                ),
1542
-            'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1543
-            'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1544
-            'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1545
-            'TKT_required'                  => $default ? 0 : $ticket->required(),
1546
-            'TKT_is_default_selector'       => '',
1547
-            'ticket_price_rows'             => '',
1548
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1549
-                ? ''
1550
-                : $base_price->get_pretty('PRC_amount', 'localized_float'),
1551
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1552
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1553
-                ? ''
1554
-                : ' style="display:none;"',
1555
-            'show_price_mod_button'         => count($prices) > 1
1556
-                                               || ($default && $count_price_mods > 0)
1557
-                                               || (! $default && $ticket->deleted())
1558
-                ? ' style="display:none;"'
1559
-                : '',
1560
-            'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1561
-            'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1562
-            'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1563
-            'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1564
-            'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1565
-            'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1566
-            'TKT_taxable'                   => $TKT_taxable,
1567
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1568
-                ? ''
1569
-                : ' style="display:none"',
1570
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1571
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1572
-                $ticket_subtotal,
1573
-                false,
1574
-                false
1575
-            ),
1576
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1577
-            'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1578
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1579
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1580
-                ? ' ticket-archived'
1581
-                : '',
1582
-            'trash_icon'                    => $ticket instanceof EE_Ticket
1583
-                                               && $ticket->deleted()
1584
-                                               && ! $ticket->is_permanently_deleteable()
1585
-                ? 'ee-lock-icon '
1586
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1587
-            'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1588
-                ? ''
1589
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1590
-        );
1591
-        $template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1592
-            ? ' style="display:none"'
1593
-            : '';
1594
-        // handle rows that should NOT be empty
1595
-        if (empty($template_args['TKT_start_date'])) {
1596
-            // if empty then the start date will be now.
1597
-            $template_args['TKT_start_date'] = date(
1598
-                $this->_date_time_format,
1599
-                current_time('timestamp')
1600
-            );
1601
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1602
-        }
1603
-        if (empty($template_args['TKT_end_date'])) {
1604
-            // get the earliest datetime (if present);
1605
-            $earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1606
-                ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1607
-                    'Datetime',
1608
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1609
-                )
1610
-                : null;
1611
-            if (! empty($earliest_dtt)) {
1612
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1613
-                    'DTT_EVT_start',
1614
-                    $this->_date_time_format
1615
-                );
1616
-            } else {
1617
-                // default so let's just use what's been set for the default date-time which is 30 days from now.
1618
-                $template_args['TKT_end_date'] = date(
1619
-                    $this->_date_time_format,
1620
-                    mktime(
1621
-                        24,
1622
-                        0,
1623
-                        0,
1624
-                        date('m'),
1625
-                        date('d') + 29,
1626
-                        date('Y')
1627
-                    )
1628
-                );
1629
-            }
1630
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1631
-        }
1632
-        // generate ticket_datetime items
1633
-        if (! $default) {
1634
-            $datetime_row = 1;
1635
-            foreach ($all_datetimes as $datetime) {
1636
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1637
-                    $datetime_row,
1638
-                    $ticket_row,
1639
-                    $datetime,
1640
-                    $ticket,
1641
-                    $ticket_datetimes,
1642
-                    $default
1643
-                );
1644
-                $datetime_row++;
1645
-            }
1646
-        }
1647
-        $price_row = 1;
1648
-        foreach ($prices as $price) {
1649
-            if (! $price instanceof EE_Price) {
1650
-                continue;
1651
-            }
1652
-            if ($price->is_base_price()) {
1653
-                $price_row++;
1654
-                continue;
1655
-            }
1656
-            $show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1657
-            $show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1658
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1659
-                $ticket_row,
1660
-                $price_row,
1661
-                $price,
1662
-                $default,
1663
-                $ticket,
1664
-                $show_trash,
1665
-                $show_create
1666
-            );
1667
-            $price_row++;
1668
-        }
1669
-        // filter $template_args
1670
-        $template_args = apply_filters(
1671
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1672
-            $template_args,
1673
-            $ticket_row,
1674
-            $ticket,
1675
-            $ticket_datetimes,
1676
-            $all_datetimes,
1677
-            $default,
1678
-            $all_tickets,
1679
-            $this->_is_creating_event
1680
-        );
1681
-        return EEH_Template::display_template(
1682
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1683
-            $template_args,
1684
-            true
1685
-        );
1686
-    }
1404
+	/**
1405
+	 * This generates the ticket row for tickets.
1406
+	 * This same method is used to generate both the actual rows and the js skeleton row
1407
+	 * (when default === true)
1408
+	 *
1409
+	 * @param int           $ticket_row       Represents the row number being generated.
1410
+	 * @param               $ticket
1411
+	 * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1412
+	 *                                        or empty for default
1413
+	 * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1414
+	 * @param bool          $default          Whether default row being generated or not.
1415
+	 * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1416
+	 *                                        (or empty in the case of defaults)
1417
+	 * @return mixed
1418
+	 * @throws InvalidArgumentException
1419
+	 * @throws InvalidInterfaceException
1420
+	 * @throws InvalidDataTypeException
1421
+	 * @throws DomainException
1422
+	 * @throws EE_Error
1423
+	 * @throws ReflectionException
1424
+	 */
1425
+	protected function _get_ticket_row(
1426
+		$ticket_row,
1427
+		$ticket,
1428
+		$ticket_datetimes,
1429
+		$all_datetimes,
1430
+		$default = false,
1431
+		$all_tickets = array()
1432
+	) {
1433
+		// if $ticket is not an instance of EE_Ticket then force default to true.
1434
+		$default = ! $ticket instanceof EE_Ticket ? true : $default;
1435
+		$prices = ! empty($ticket) && ! $default
1436
+			? $ticket->get_many_related(
1437
+				'Price',
1438
+				array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1439
+			)
1440
+			: array();
1441
+		// if there is only one price (which would be the base price)
1442
+		// or NO prices and this ticket is a default ticket,
1443
+		// let's just make sure there are no cached default prices on the object.
1444
+		// This is done by not including any query_params.
1445
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1446
+			$prices = $ticket->prices();
1447
+		}
1448
+		// check if we're dealing with a default ticket in which case
1449
+		// we don't want any starting_ticket_datetime_row values set
1450
+		// (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1451
+		// This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1452
+		$default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1453
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1454
+			? $ticket_datetimes[ $ticket->ID() ]
1455
+			: array();
1456
+		$ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1457
+		$base_price = $default ? null : $ticket->base_price();
1458
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1459
+		// breaking out complicated condition for ticket_status
1460
+		if ($default) {
1461
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1462
+		} else {
1463
+			$ticket_status_class = $ticket->is_default()
1464
+				? ' tkt-status-' . EE_Ticket::onsale
1465
+				: ' tkt-status-' . $ticket->ticket_status();
1466
+		}
1467
+		// breaking out complicated condition for TKT_taxable
1468
+		if ($default) {
1469
+			$TKT_taxable = '';
1470
+		} else {
1471
+			$TKT_taxable = $ticket->taxable()
1472
+				? ' checked="checked"'
1473
+				: '';
1474
+		}
1475
+		if ($default) {
1476
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1477
+		} elseif ($ticket->is_default()) {
1478
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1479
+		} else {
1480
+			$TKT_status = $ticket->ticket_status(true);
1481
+		}
1482
+		if ($default) {
1483
+			$TKT_min = '';
1484
+		} else {
1485
+			$TKT_min = $ticket->min();
1486
+			if ($TKT_min === -1 || $TKT_min === 0) {
1487
+				$TKT_min = '';
1488
+			}
1489
+		}
1490
+		$template_args = array(
1491
+			'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1492
+			'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1493
+			// on initial page load this will always be the correct order.
1494
+			'tkt_status_class'              => $ticket_status_class,
1495
+			'display_edit_tkt_row'          => ' style="display:none;"',
1496
+			'edit_tkt_expanded'             => '',
1497
+			'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1498
+			'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1499
+			'TKT_start_date'                => $default
1500
+				? ''
1501
+				: $ticket->get_date('TKT_start_date', $this->_date_time_format),
1502
+			'TKT_end_date'                  => $default
1503
+				? ''
1504
+				: $ticket->get_date('TKT_end_date', $this->_date_time_format),
1505
+			'TKT_status'                    => $TKT_status,
1506
+			'TKT_price'                     => $default
1507
+				? ''
1508
+				: EEH_Template::format_currency(
1509
+					$ticket->get_ticket_total_with_taxes(),
1510
+					false,
1511
+					false
1512
+				),
1513
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1514
+			'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1515
+			'TKT_qty'                       => $default
1516
+				? ''
1517
+				: $ticket->get_pretty('TKT_qty', 'symbol'),
1518
+			'TKT_qty_for_input'             => $default
1519
+				? ''
1520
+				: $ticket->get_pretty('TKT_qty', 'input'),
1521
+			'TKT_uses'                      => $default
1522
+				? ''
1523
+				: $ticket->get_pretty('TKT_uses', 'input'),
1524
+			'TKT_min'                       => $TKT_min,
1525
+			'TKT_max'                       => $default
1526
+				? ''
1527
+				: $ticket->get_pretty('TKT_max', 'input'),
1528
+			'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1529
+			'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1530
+			'TKT_registrations'             => $default
1531
+				? 0
1532
+				: $ticket->count_registrations(
1533
+					array(
1534
+						array(
1535
+							'STS_ID' => array(
1536
+								'!=',
1537
+								EEM_Registration::status_id_incomplete,
1538
+							),
1539
+						),
1540
+					)
1541
+				),
1542
+			'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1543
+			'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1544
+			'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1545
+			'TKT_required'                  => $default ? 0 : $ticket->required(),
1546
+			'TKT_is_default_selector'       => '',
1547
+			'ticket_price_rows'             => '',
1548
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1549
+				? ''
1550
+				: $base_price->get_pretty('PRC_amount', 'localized_float'),
1551
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1552
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1553
+				? ''
1554
+				: ' style="display:none;"',
1555
+			'show_price_mod_button'         => count($prices) > 1
1556
+											   || ($default && $count_price_mods > 0)
1557
+											   || (! $default && $ticket->deleted())
1558
+				? ' style="display:none;"'
1559
+				: '',
1560
+			'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1561
+			'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1562
+			'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1563
+			'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1564
+			'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1565
+			'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1566
+			'TKT_taxable'                   => $TKT_taxable,
1567
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1568
+				? ''
1569
+				: ' style="display:none"',
1570
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1571
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1572
+				$ticket_subtotal,
1573
+				false,
1574
+				false
1575
+			),
1576
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1577
+			'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1578
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1579
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1580
+				? ' ticket-archived'
1581
+				: '',
1582
+			'trash_icon'                    => $ticket instanceof EE_Ticket
1583
+											   && $ticket->deleted()
1584
+											   && ! $ticket->is_permanently_deleteable()
1585
+				? 'ee-lock-icon '
1586
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1587
+			'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1588
+				? ''
1589
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1590
+		);
1591
+		$template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1592
+			? ' style="display:none"'
1593
+			: '';
1594
+		// handle rows that should NOT be empty
1595
+		if (empty($template_args['TKT_start_date'])) {
1596
+			// if empty then the start date will be now.
1597
+			$template_args['TKT_start_date'] = date(
1598
+				$this->_date_time_format,
1599
+				current_time('timestamp')
1600
+			);
1601
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1602
+		}
1603
+		if (empty($template_args['TKT_end_date'])) {
1604
+			// get the earliest datetime (if present);
1605
+			$earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1606
+				? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1607
+					'Datetime',
1608
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1609
+				)
1610
+				: null;
1611
+			if (! empty($earliest_dtt)) {
1612
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1613
+					'DTT_EVT_start',
1614
+					$this->_date_time_format
1615
+				);
1616
+			} else {
1617
+				// default so let's just use what's been set for the default date-time which is 30 days from now.
1618
+				$template_args['TKT_end_date'] = date(
1619
+					$this->_date_time_format,
1620
+					mktime(
1621
+						24,
1622
+						0,
1623
+						0,
1624
+						date('m'),
1625
+						date('d') + 29,
1626
+						date('Y')
1627
+					)
1628
+				);
1629
+			}
1630
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1631
+		}
1632
+		// generate ticket_datetime items
1633
+		if (! $default) {
1634
+			$datetime_row = 1;
1635
+			foreach ($all_datetimes as $datetime) {
1636
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1637
+					$datetime_row,
1638
+					$ticket_row,
1639
+					$datetime,
1640
+					$ticket,
1641
+					$ticket_datetimes,
1642
+					$default
1643
+				);
1644
+				$datetime_row++;
1645
+			}
1646
+		}
1647
+		$price_row = 1;
1648
+		foreach ($prices as $price) {
1649
+			if (! $price instanceof EE_Price) {
1650
+				continue;
1651
+			}
1652
+			if ($price->is_base_price()) {
1653
+				$price_row++;
1654
+				continue;
1655
+			}
1656
+			$show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1657
+			$show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1658
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1659
+				$ticket_row,
1660
+				$price_row,
1661
+				$price,
1662
+				$default,
1663
+				$ticket,
1664
+				$show_trash,
1665
+				$show_create
1666
+			);
1667
+			$price_row++;
1668
+		}
1669
+		// filter $template_args
1670
+		$template_args = apply_filters(
1671
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1672
+			$template_args,
1673
+			$ticket_row,
1674
+			$ticket,
1675
+			$ticket_datetimes,
1676
+			$all_datetimes,
1677
+			$default,
1678
+			$all_tickets,
1679
+			$this->_is_creating_event
1680
+		);
1681
+		return EEH_Template::display_template(
1682
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1683
+			$template_args,
1684
+			true
1685
+		);
1686
+	}
1687 1687
 
1688 1688
 
1689
-    /**
1690
-     * @param int            $ticket_row
1691
-     * @param EE_Ticket|null $ticket
1692
-     * @return string
1693
-     * @throws DomainException
1694
-     * @throws EE_Error
1695
-     */
1696
-    protected function _get_tax_rows($ticket_row, $ticket)
1697
-    {
1698
-        $tax_rows = '';
1699
-        /** @var EE_Price[] $taxes */
1700
-        $taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1701
-        foreach ($taxes as $tax) {
1702
-            $tax_added = $this->_get_tax_added($tax, $ticket);
1703
-            $template_args = array(
1704
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1705
-                    ? ''
1706
-                    : ' style="display:none;"',
1707
-                'tax_id'            => $tax->ID(),
1708
-                'tkt_row'           => $ticket_row,
1709
-                'tax_label'         => $tax->get('PRC_name'),
1710
-                'tax_added'         => $tax_added,
1711
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1712
-                'tax_amount'        => $tax->get('PRC_amount'),
1713
-            );
1714
-            $template_args = apply_filters(
1715
-                'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1716
-                $template_args,
1717
-                $ticket_row,
1718
-                $ticket,
1719
-                $this->_is_creating_event
1720
-            );
1721
-            $tax_rows .= EEH_Template::display_template(
1722
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1723
-                $template_args,
1724
-                true
1725
-            );
1726
-        }
1727
-        return $tax_rows;
1728
-    }
1689
+	/**
1690
+	 * @param int            $ticket_row
1691
+	 * @param EE_Ticket|null $ticket
1692
+	 * @return string
1693
+	 * @throws DomainException
1694
+	 * @throws EE_Error
1695
+	 */
1696
+	protected function _get_tax_rows($ticket_row, $ticket)
1697
+	{
1698
+		$tax_rows = '';
1699
+		/** @var EE_Price[] $taxes */
1700
+		$taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1701
+		foreach ($taxes as $tax) {
1702
+			$tax_added = $this->_get_tax_added($tax, $ticket);
1703
+			$template_args = array(
1704
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1705
+					? ''
1706
+					: ' style="display:none;"',
1707
+				'tax_id'            => $tax->ID(),
1708
+				'tkt_row'           => $ticket_row,
1709
+				'tax_label'         => $tax->get('PRC_name'),
1710
+				'tax_added'         => $tax_added,
1711
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1712
+				'tax_amount'        => $tax->get('PRC_amount'),
1713
+			);
1714
+			$template_args = apply_filters(
1715
+				'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1716
+				$template_args,
1717
+				$ticket_row,
1718
+				$ticket,
1719
+				$this->_is_creating_event
1720
+			);
1721
+			$tax_rows .= EEH_Template::display_template(
1722
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1723
+				$template_args,
1724
+				true
1725
+			);
1726
+		}
1727
+		return $tax_rows;
1728
+	}
1729 1729
 
1730 1730
 
1731
-    /**
1732
-     * @param EE_Price       $tax
1733
-     * @param EE_Ticket|null $ticket
1734
-     * @return float|int
1735
-     * @throws EE_Error
1736
-     */
1737
-    protected function _get_tax_added(EE_Price $tax, $ticket)
1738
-    {
1739
-        $subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1740
-        return $subtotal * $tax->get('PRC_amount') / 100;
1741
-    }
1731
+	/**
1732
+	 * @param EE_Price       $tax
1733
+	 * @param EE_Ticket|null $ticket
1734
+	 * @return float|int
1735
+	 * @throws EE_Error
1736
+	 */
1737
+	protected function _get_tax_added(EE_Price $tax, $ticket)
1738
+	{
1739
+		$subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1740
+		return $subtotal * $tax->get('PRC_amount') / 100;
1741
+	}
1742 1742
 
1743 1743
 
1744
-    /**
1745
-     * @param int            $ticket_row
1746
-     * @param int            $price_row
1747
-     * @param EE_Price|null  $price
1748
-     * @param bool           $default
1749
-     * @param EE_Ticket|null $ticket
1750
-     * @param bool           $show_trash
1751
-     * @param bool           $show_create
1752
-     * @return mixed
1753
-     * @throws InvalidArgumentException
1754
-     * @throws InvalidInterfaceException
1755
-     * @throws InvalidDataTypeException
1756
-     * @throws DomainException
1757
-     * @throws EE_Error
1758
-     * @throws ReflectionException
1759
-     */
1760
-    protected function _get_ticket_price_row(
1761
-        $ticket_row,
1762
-        $price_row,
1763
-        $price,
1764
-        $default,
1765
-        $ticket,
1766
-        $show_trash = true,
1767
-        $show_create = true
1768
-    ) {
1769
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1770
-        $template_args = array(
1771
-            'tkt_row'               => $default && empty($ticket)
1772
-                ? 'TICKETNUM'
1773
-                : $ticket_row,
1774
-            'PRC_order'             => $default && empty($price)
1775
-                ? 'PRICENUM'
1776
-                : $price_row,
1777
-            'edit_prices_name'      => $default && empty($price)
1778
-                ? 'PRICENAMEATTR'
1779
-                : 'edit_prices',
1780
-            'price_type_selector'   => $default && empty($price)
1781
-                ? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1782
-                : $this->_get_price_type_selector(
1783
-                    $ticket_row,
1784
-                    $price_row,
1785
-                    $price,
1786
-                    $default,
1787
-                    $send_disabled
1788
-                ),
1789
-            'PRC_ID'                => $default && empty($price)
1790
-                ? 0
1791
-                : $price->ID(),
1792
-            'PRC_is_default'        => $default && empty($price)
1793
-                ? 0
1794
-                : $price->get('PRC_is_default'),
1795
-            'PRC_name'              => $default && empty($price)
1796
-                ? ''
1797
-                : $price->get('PRC_name'),
1798
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1799
-            'show_plus_or_minus'    => $default && empty($price)
1800
-                ? ''
1801
-                : ' style="display:none;"',
1802
-            'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1803
-                ? ' style="display:none;"'
1804
-                : '',
1805
-            'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1806
-                ? ' style="display:none;"'
1807
-                : '',
1808
-            'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1809
-                ? ' style="display:none"'
1810
-                : '',
1811
-            'PRC_amount'            => $default && empty($price)
1812
-                ? 0
1813
-                : $price->get_pretty('PRC_amount', 'localized_float'),
1814
-            'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1815
-                ? ' style="display:none;"'
1816
-                : '',
1817
-            'show_trash_icon'       => $show_trash
1818
-                ? ''
1819
-                : ' style="display:none;"',
1820
-            'show_create_button'    => $show_create
1821
-                ? ''
1822
-                : ' style="display:none;"',
1823
-            'PRC_desc'              => $default && empty($price)
1824
-                ? ''
1825
-                : $price->get('PRC_desc'),
1826
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1827
-        );
1828
-        $template_args = apply_filters(
1829
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1830
-            $template_args,
1831
-            $ticket_row,
1832
-            $price_row,
1833
-            $price,
1834
-            $default,
1835
-            $ticket,
1836
-            $show_trash,
1837
-            $show_create,
1838
-            $this->_is_creating_event
1839
-        );
1840
-        return EEH_Template::display_template(
1841
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1842
-            $template_args,
1843
-            true
1844
-        );
1845
-    }
1744
+	/**
1745
+	 * @param int            $ticket_row
1746
+	 * @param int            $price_row
1747
+	 * @param EE_Price|null  $price
1748
+	 * @param bool           $default
1749
+	 * @param EE_Ticket|null $ticket
1750
+	 * @param bool           $show_trash
1751
+	 * @param bool           $show_create
1752
+	 * @return mixed
1753
+	 * @throws InvalidArgumentException
1754
+	 * @throws InvalidInterfaceException
1755
+	 * @throws InvalidDataTypeException
1756
+	 * @throws DomainException
1757
+	 * @throws EE_Error
1758
+	 * @throws ReflectionException
1759
+	 */
1760
+	protected function _get_ticket_price_row(
1761
+		$ticket_row,
1762
+		$price_row,
1763
+		$price,
1764
+		$default,
1765
+		$ticket,
1766
+		$show_trash = true,
1767
+		$show_create = true
1768
+	) {
1769
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1770
+		$template_args = array(
1771
+			'tkt_row'               => $default && empty($ticket)
1772
+				? 'TICKETNUM'
1773
+				: $ticket_row,
1774
+			'PRC_order'             => $default && empty($price)
1775
+				? 'PRICENUM'
1776
+				: $price_row,
1777
+			'edit_prices_name'      => $default && empty($price)
1778
+				? 'PRICENAMEATTR'
1779
+				: 'edit_prices',
1780
+			'price_type_selector'   => $default && empty($price)
1781
+				? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1782
+				: $this->_get_price_type_selector(
1783
+					$ticket_row,
1784
+					$price_row,
1785
+					$price,
1786
+					$default,
1787
+					$send_disabled
1788
+				),
1789
+			'PRC_ID'                => $default && empty($price)
1790
+				? 0
1791
+				: $price->ID(),
1792
+			'PRC_is_default'        => $default && empty($price)
1793
+				? 0
1794
+				: $price->get('PRC_is_default'),
1795
+			'PRC_name'              => $default && empty($price)
1796
+				? ''
1797
+				: $price->get('PRC_name'),
1798
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1799
+			'show_plus_or_minus'    => $default && empty($price)
1800
+				? ''
1801
+				: ' style="display:none;"',
1802
+			'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1803
+				? ' style="display:none;"'
1804
+				: '',
1805
+			'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1806
+				? ' style="display:none;"'
1807
+				: '',
1808
+			'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1809
+				? ' style="display:none"'
1810
+				: '',
1811
+			'PRC_amount'            => $default && empty($price)
1812
+				? 0
1813
+				: $price->get_pretty('PRC_amount', 'localized_float'),
1814
+			'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1815
+				? ' style="display:none;"'
1816
+				: '',
1817
+			'show_trash_icon'       => $show_trash
1818
+				? ''
1819
+				: ' style="display:none;"',
1820
+			'show_create_button'    => $show_create
1821
+				? ''
1822
+				: ' style="display:none;"',
1823
+			'PRC_desc'              => $default && empty($price)
1824
+				? ''
1825
+				: $price->get('PRC_desc'),
1826
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1827
+		);
1828
+		$template_args = apply_filters(
1829
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1830
+			$template_args,
1831
+			$ticket_row,
1832
+			$price_row,
1833
+			$price,
1834
+			$default,
1835
+			$ticket,
1836
+			$show_trash,
1837
+			$show_create,
1838
+			$this->_is_creating_event
1839
+		);
1840
+		return EEH_Template::display_template(
1841
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1842
+			$template_args,
1843
+			true
1844
+		);
1845
+	}
1846 1846
 
1847 1847
 
1848
-    /**
1849
-     * @param int      $ticket_row
1850
-     * @param int      $price_row
1851
-     * @param EE_Price $price
1852
-     * @param bool     $default
1853
-     * @param bool     $disabled
1854
-     * @return mixed
1855
-     * @throws ReflectionException
1856
-     * @throws InvalidArgumentException
1857
-     * @throws InvalidInterfaceException
1858
-     * @throws InvalidDataTypeException
1859
-     * @throws DomainException
1860
-     * @throws EE_Error
1861
-     */
1862
-    protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1863
-    {
1864
-        if ($price->is_base_price()) {
1865
-            return $this->_get_base_price_template(
1866
-                $ticket_row,
1867
-                $price_row,
1868
-                $price,
1869
-                $default
1870
-            );
1871
-        }
1872
-        return $this->_get_price_modifier_template(
1873
-            $ticket_row,
1874
-            $price_row,
1875
-            $price,
1876
-            $default,
1877
-            $disabled
1878
-        );
1879
-    }
1848
+	/**
1849
+	 * @param int      $ticket_row
1850
+	 * @param int      $price_row
1851
+	 * @param EE_Price $price
1852
+	 * @param bool     $default
1853
+	 * @param bool     $disabled
1854
+	 * @return mixed
1855
+	 * @throws ReflectionException
1856
+	 * @throws InvalidArgumentException
1857
+	 * @throws InvalidInterfaceException
1858
+	 * @throws InvalidDataTypeException
1859
+	 * @throws DomainException
1860
+	 * @throws EE_Error
1861
+	 */
1862
+	protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1863
+	{
1864
+		if ($price->is_base_price()) {
1865
+			return $this->_get_base_price_template(
1866
+				$ticket_row,
1867
+				$price_row,
1868
+				$price,
1869
+				$default
1870
+			);
1871
+		}
1872
+		return $this->_get_price_modifier_template(
1873
+			$ticket_row,
1874
+			$price_row,
1875
+			$price,
1876
+			$default,
1877
+			$disabled
1878
+		);
1879
+	}
1880 1880
 
1881 1881
 
1882
-    /**
1883
-     * @param int      $ticket_row
1884
-     * @param int      $price_row
1885
-     * @param EE_Price $price
1886
-     * @param bool     $default
1887
-     * @return mixed
1888
-     * @throws DomainException
1889
-     * @throws EE_Error
1890
-     */
1891
-    protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1892
-    {
1893
-        $template_args = array(
1894
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1895
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1896
-            'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1897
-            'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1898
-            'price_selected_operator'   => '+',
1899
-            'price_selected_is_percent' => 0,
1900
-        );
1901
-        $template_args = apply_filters(
1902
-            'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1903
-            $template_args,
1904
-            $ticket_row,
1905
-            $price_row,
1906
-            $price,
1907
-            $default,
1908
-            $this->_is_creating_event
1909
-        );
1910
-        return EEH_Template::display_template(
1911
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1912
-            $template_args,
1913
-            true
1914
-        );
1915
-    }
1882
+	/**
1883
+	 * @param int      $ticket_row
1884
+	 * @param int      $price_row
1885
+	 * @param EE_Price $price
1886
+	 * @param bool     $default
1887
+	 * @return mixed
1888
+	 * @throws DomainException
1889
+	 * @throws EE_Error
1890
+	 */
1891
+	protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1892
+	{
1893
+		$template_args = array(
1894
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1895
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1896
+			'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1897
+			'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1898
+			'price_selected_operator'   => '+',
1899
+			'price_selected_is_percent' => 0,
1900
+		);
1901
+		$template_args = apply_filters(
1902
+			'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1903
+			$template_args,
1904
+			$ticket_row,
1905
+			$price_row,
1906
+			$price,
1907
+			$default,
1908
+			$this->_is_creating_event
1909
+		);
1910
+		return EEH_Template::display_template(
1911
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1912
+			$template_args,
1913
+			true
1914
+		);
1915
+	}
1916 1916
 
1917 1917
 
1918
-    /**
1919
-     * @param int      $ticket_row
1920
-     * @param int      $price_row
1921
-     * @param EE_Price $price
1922
-     * @param bool     $default
1923
-     * @param bool     $disabled
1924
-     * @return mixed
1925
-     * @throws ReflectionException
1926
-     * @throws InvalidArgumentException
1927
-     * @throws InvalidInterfaceException
1928
-     * @throws InvalidDataTypeException
1929
-     * @throws DomainException
1930
-     * @throws EE_Error
1931
-     */
1932
-    protected function _get_price_modifier_template(
1933
-        $ticket_row,
1934
-        $price_row,
1935
-        $price,
1936
-        $default,
1937
-        $disabled = false
1938
-    ) {
1939
-        $select_name = $default && ! $price instanceof EE_Price
1940
-            ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1941
-            : 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1942
-        /** @var EEM_Price_Type $price_type_model */
1943
-        $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1944
-        $price_types = $price_type_model->get_all(array(
1945
-            array(
1946
-                'OR' => array(
1947
-                    'PBT_ID'  => '2',
1948
-                    'PBT_ID*' => '3',
1949
-                ),
1950
-            ),
1951
-        ));
1952
-        $all_price_types = $default && ! $price instanceof EE_Price
1953
-            ? array(esc_html__('Select Modifier', 'event_espresso'))
1954
-            : array();
1955
-        $selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1956
-        $price_option_spans = '';
1957
-        // setup price types for selector
1958
-        foreach ($price_types as $price_type) {
1959
-            if (! $price_type instanceof EE_Price_Type) {
1960
-                continue;
1961
-            }
1962
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1963
-            // while we're in the loop let's setup the option spans used by js
1964
-            $span_args = array(
1965
-                'PRT_ID'         => $price_type->ID(),
1966
-                'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1967
-                'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1968
-            );
1969
-            $price_option_spans .= EEH_Template::display_template(
1970
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1971
-                $span_args,
1972
-                true
1973
-            );
1974
-        }
1975
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1976
-            : $select_name;
1977
-        $select_input = new EE_Select_Input(
1978
-            $all_price_types,
1979
-            array(
1980
-                'default'               => $selected_price_type_id,
1981
-                'html_name'             => $select_name,
1982
-                'html_class'            => 'edit-price-PRT_ID',
1983
-                'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1984
-            )
1985
-        );
1986
-        $price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1987
-        $price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1988
-        $price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1989
-        $price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1990
-        $template_args = array(
1991
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1992
-            'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1993
-            'price_modifier_selector'   => $select_input->get_html_for_input(),
1994
-            'main_name'                 => $select_name,
1995
-            'selected_price_type_id'    => $selected_price_type_id,
1996
-            'price_option_spans'        => $price_option_spans,
1997
-            'price_selected_operator'   => $price_selected_operator,
1998
-            'price_selected_is_percent' => $price_selected_is_percent,
1999
-            'disabled'                  => $disabled,
2000
-        );
2001
-        $template_args = apply_filters(
2002
-            'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2003
-            $template_args,
2004
-            $ticket_row,
2005
-            $price_row,
2006
-            $price,
2007
-            $default,
2008
-            $disabled,
2009
-            $this->_is_creating_event
2010
-        );
2011
-        return EEH_Template::display_template(
2012
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2013
-            $template_args,
2014
-            true
2015
-        );
2016
-    }
1918
+	/**
1919
+	 * @param int      $ticket_row
1920
+	 * @param int      $price_row
1921
+	 * @param EE_Price $price
1922
+	 * @param bool     $default
1923
+	 * @param bool     $disabled
1924
+	 * @return mixed
1925
+	 * @throws ReflectionException
1926
+	 * @throws InvalidArgumentException
1927
+	 * @throws InvalidInterfaceException
1928
+	 * @throws InvalidDataTypeException
1929
+	 * @throws DomainException
1930
+	 * @throws EE_Error
1931
+	 */
1932
+	protected function _get_price_modifier_template(
1933
+		$ticket_row,
1934
+		$price_row,
1935
+		$price,
1936
+		$default,
1937
+		$disabled = false
1938
+	) {
1939
+		$select_name = $default && ! $price instanceof EE_Price
1940
+			? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1941
+			: 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1942
+		/** @var EEM_Price_Type $price_type_model */
1943
+		$price_type_model = EE_Registry::instance()->load_model('Price_Type');
1944
+		$price_types = $price_type_model->get_all(array(
1945
+			array(
1946
+				'OR' => array(
1947
+					'PBT_ID'  => '2',
1948
+					'PBT_ID*' => '3',
1949
+				),
1950
+			),
1951
+		));
1952
+		$all_price_types = $default && ! $price instanceof EE_Price
1953
+			? array(esc_html__('Select Modifier', 'event_espresso'))
1954
+			: array();
1955
+		$selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1956
+		$price_option_spans = '';
1957
+		// setup price types for selector
1958
+		foreach ($price_types as $price_type) {
1959
+			if (! $price_type instanceof EE_Price_Type) {
1960
+				continue;
1961
+			}
1962
+			$all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1963
+			// while we're in the loop let's setup the option spans used by js
1964
+			$span_args = array(
1965
+				'PRT_ID'         => $price_type->ID(),
1966
+				'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1967
+				'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1968
+			);
1969
+			$price_option_spans .= EEH_Template::display_template(
1970
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1971
+				$span_args,
1972
+				true
1973
+			);
1974
+		}
1975
+		$select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1976
+			: $select_name;
1977
+		$select_input = new EE_Select_Input(
1978
+			$all_price_types,
1979
+			array(
1980
+				'default'               => $selected_price_type_id,
1981
+				'html_name'             => $select_name,
1982
+				'html_class'            => 'edit-price-PRT_ID',
1983
+				'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1984
+			)
1985
+		);
1986
+		$price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1987
+		$price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1988
+		$price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1989
+		$price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1990
+		$template_args = array(
1991
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1992
+			'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1993
+			'price_modifier_selector'   => $select_input->get_html_for_input(),
1994
+			'main_name'                 => $select_name,
1995
+			'selected_price_type_id'    => $selected_price_type_id,
1996
+			'price_option_spans'        => $price_option_spans,
1997
+			'price_selected_operator'   => $price_selected_operator,
1998
+			'price_selected_is_percent' => $price_selected_is_percent,
1999
+			'disabled'                  => $disabled,
2000
+		);
2001
+		$template_args = apply_filters(
2002
+			'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
2003
+			$template_args,
2004
+			$ticket_row,
2005
+			$price_row,
2006
+			$price,
2007
+			$default,
2008
+			$disabled,
2009
+			$this->_is_creating_event
2010
+		);
2011
+		return EEH_Template::display_template(
2012
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2013
+			$template_args,
2014
+			true
2015
+		);
2016
+	}
2017 2017
 
2018 2018
 
2019
-    /**
2020
-     * @param int              $datetime_row
2021
-     * @param int              $ticket_row
2022
-     * @param EE_Datetime|null $datetime
2023
-     * @param EE_Ticket|null   $ticket
2024
-     * @param array            $ticket_datetimes
2025
-     * @param bool             $default
2026
-     * @return mixed
2027
-     * @throws DomainException
2028
-     * @throws EE_Error
2029
-     */
2030
-    protected function _get_ticket_datetime_list_item(
2031
-        $datetime_row,
2032
-        $ticket_row,
2033
-        $datetime,
2034
-        $ticket,
2035
-        $ticket_datetimes = array(),
2036
-        $default
2037
-    ) {
2038
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2039
-            ? $ticket_datetimes[ $ticket->ID() ]
2040
-            : array();
2041
-        $template_args = array(
2042
-            'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2043
-                ? 'DTTNUM'
2044
-                : $datetime_row,
2045
-            'tkt_row'                  => $default
2046
-                ? 'TICKETNUM'
2047
-                : $ticket_row,
2048
-            'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2049
-                ? ' ticket-selected'
2050
-                : '',
2051
-            'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2052
-                ? ' checked="checked"'
2053
-                : '',
2054
-            'DTT_name'                 => $default && empty($datetime)
2055
-                ? 'DTTNAME'
2056
-                : $datetime->get_dtt_display_name(true),
2057
-            'tkt_status_class'         => '',
2058
-        );
2059
-        $template_args = apply_filters(
2060
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2061
-            $template_args,
2062
-            $datetime_row,
2063
-            $ticket_row,
2064
-            $datetime,
2065
-            $ticket,
2066
-            $ticket_datetimes,
2067
-            $default,
2068
-            $this->_is_creating_event
2069
-        );
2070
-        return EEH_Template::display_template(
2071
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2072
-            $template_args,
2073
-            true
2074
-        );
2075
-    }
2019
+	/**
2020
+	 * @param int              $datetime_row
2021
+	 * @param int              $ticket_row
2022
+	 * @param EE_Datetime|null $datetime
2023
+	 * @param EE_Ticket|null   $ticket
2024
+	 * @param array            $ticket_datetimes
2025
+	 * @param bool             $default
2026
+	 * @return mixed
2027
+	 * @throws DomainException
2028
+	 * @throws EE_Error
2029
+	 */
2030
+	protected function _get_ticket_datetime_list_item(
2031
+		$datetime_row,
2032
+		$ticket_row,
2033
+		$datetime,
2034
+		$ticket,
2035
+		$ticket_datetimes = array(),
2036
+		$default
2037
+	) {
2038
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2039
+			? $ticket_datetimes[ $ticket->ID() ]
2040
+			: array();
2041
+		$template_args = array(
2042
+			'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2043
+				? 'DTTNUM'
2044
+				: $datetime_row,
2045
+			'tkt_row'                  => $default
2046
+				? 'TICKETNUM'
2047
+				: $ticket_row,
2048
+			'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2049
+				? ' ticket-selected'
2050
+				: '',
2051
+			'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2052
+				? ' checked="checked"'
2053
+				: '',
2054
+			'DTT_name'                 => $default && empty($datetime)
2055
+				? 'DTTNAME'
2056
+				: $datetime->get_dtt_display_name(true),
2057
+			'tkt_status_class'         => '',
2058
+		);
2059
+		$template_args = apply_filters(
2060
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2061
+			$template_args,
2062
+			$datetime_row,
2063
+			$ticket_row,
2064
+			$datetime,
2065
+			$ticket,
2066
+			$ticket_datetimes,
2067
+			$default,
2068
+			$this->_is_creating_event
2069
+		);
2070
+		return EEH_Template::display_template(
2071
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2072
+			$template_args,
2073
+			true
2074
+		);
2075
+	}
2076 2076
 
2077 2077
 
2078
-    /**
2079
-     * @param array $all_datetimes
2080
-     * @param array $all_tickets
2081
-     * @return mixed
2082
-     * @throws ReflectionException
2083
-     * @throws InvalidArgumentException
2084
-     * @throws InvalidInterfaceException
2085
-     * @throws InvalidDataTypeException
2086
-     * @throws DomainException
2087
-     * @throws EE_Error
2088
-     */
2089
-    protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2090
-    {
2091
-        $template_args = array(
2092
-            'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2093
-                'DTTNUM',
2094
-                null,
2095
-                true,
2096
-                $all_datetimes
2097
-            ),
2098
-            'default_ticket_row'                       => $this->_get_ticket_row(
2099
-                'TICKETNUM',
2100
-                null,
2101
-                array(),
2102
-                array(),
2103
-                true
2104
-            ),
2105
-            'default_price_row'                        => $this->_get_ticket_price_row(
2106
-                'TICKETNUM',
2107
-                'PRICENUM',
2108
-                null,
2109
-                true,
2110
-                null
2111
-            ),
2112
-            'default_price_rows'                       => '',
2113
-            'default_base_price_amount'                => 0,
2114
-            'default_base_price_name'                  => '',
2115
-            'default_base_price_description'           => '',
2116
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2117
-                'TICKETNUM',
2118
-                'PRICENUM',
2119
-                null,
2120
-                true
2121
-            ),
2122
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2123
-                'DTTNUM',
2124
-                null,
2125
-                array(),
2126
-                array(),
2127
-                true
2128
-            ),
2129
-            'existing_available_datetime_tickets_list' => '',
2130
-            'existing_available_ticket_datetimes_list' => '',
2131
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2132
-                'DTTNUM',
2133
-                'TICKETNUM',
2134
-                null,
2135
-                null,
2136
-                array(),
2137
-                true
2138
-            ),
2139
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2140
-                'DTTNUM',
2141
-                'TICKETNUM',
2142
-                null,
2143
-                null,
2144
-                array(),
2145
-                true
2146
-            ),
2147
-        );
2148
-        $ticket_row = 1;
2149
-        foreach ($all_tickets as $ticket) {
2150
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2151
-                'DTTNUM',
2152
-                $ticket_row,
2153
-                null,
2154
-                $ticket,
2155
-                array(),
2156
-                true
2157
-            );
2158
-            $ticket_row++;
2159
-        }
2160
-        $datetime_row = 1;
2161
-        foreach ($all_datetimes as $datetime) {
2162
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2163
-                $datetime_row,
2164
-                'TICKETNUM',
2165
-                $datetime,
2166
-                null,
2167
-                array(),
2168
-                true
2169
-            );
2170
-            $datetime_row++;
2171
-        }
2172
-        /** @var EEM_Price $price_model */
2173
-        $price_model = EE_Registry::instance()->load_model('Price');
2174
-        $default_prices = $price_model->get_all_default_prices();
2175
-        $price_row = 1;
2176
-        foreach ($default_prices as $price) {
2177
-            if (! $price instanceof EE_Price) {
2178
-                continue;
2179
-            }
2180
-            if ($price->is_base_price()) {
2181
-                $template_args['default_base_price_amount'] = $price->get_pretty(
2182
-                    'PRC_amount',
2183
-                    'localized_float'
2184
-                );
2185
-                $template_args['default_base_price_name'] = $price->get('PRC_name');
2186
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
2187
-                $price_row++;
2188
-                continue;
2189
-            }
2190
-            $show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2191
-                             || count($default_prices) === 1);
2192
-            $show_create = ! (count($default_prices) > 1
2193
-                              && count($default_prices)
2194
-                                 !== $price_row);
2195
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2196
-                'TICKETNUM',
2197
-                $price_row,
2198
-                $price,
2199
-                true,
2200
-                null,
2201
-                $show_trash,
2202
-                $show_create
2203
-            );
2204
-            $price_row++;
2205
-        }
2206
-        $template_args = apply_filters(
2207
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2208
-            $template_args,
2209
-            $all_datetimes,
2210
-            $all_tickets,
2211
-            $this->_is_creating_event
2212
-        );
2213
-        return EEH_Template::display_template(
2214
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2215
-            $template_args,
2216
-            true
2217
-        );
2218
-    }
2078
+	/**
2079
+	 * @param array $all_datetimes
2080
+	 * @param array $all_tickets
2081
+	 * @return mixed
2082
+	 * @throws ReflectionException
2083
+	 * @throws InvalidArgumentException
2084
+	 * @throws InvalidInterfaceException
2085
+	 * @throws InvalidDataTypeException
2086
+	 * @throws DomainException
2087
+	 * @throws EE_Error
2088
+	 */
2089
+	protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2090
+	{
2091
+		$template_args = array(
2092
+			'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2093
+				'DTTNUM',
2094
+				null,
2095
+				true,
2096
+				$all_datetimes
2097
+			),
2098
+			'default_ticket_row'                       => $this->_get_ticket_row(
2099
+				'TICKETNUM',
2100
+				null,
2101
+				array(),
2102
+				array(),
2103
+				true
2104
+			),
2105
+			'default_price_row'                        => $this->_get_ticket_price_row(
2106
+				'TICKETNUM',
2107
+				'PRICENUM',
2108
+				null,
2109
+				true,
2110
+				null
2111
+			),
2112
+			'default_price_rows'                       => '',
2113
+			'default_base_price_amount'                => 0,
2114
+			'default_base_price_name'                  => '',
2115
+			'default_base_price_description'           => '',
2116
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2117
+				'TICKETNUM',
2118
+				'PRICENUM',
2119
+				null,
2120
+				true
2121
+			),
2122
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2123
+				'DTTNUM',
2124
+				null,
2125
+				array(),
2126
+				array(),
2127
+				true
2128
+			),
2129
+			'existing_available_datetime_tickets_list' => '',
2130
+			'existing_available_ticket_datetimes_list' => '',
2131
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2132
+				'DTTNUM',
2133
+				'TICKETNUM',
2134
+				null,
2135
+				null,
2136
+				array(),
2137
+				true
2138
+			),
2139
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2140
+				'DTTNUM',
2141
+				'TICKETNUM',
2142
+				null,
2143
+				null,
2144
+				array(),
2145
+				true
2146
+			),
2147
+		);
2148
+		$ticket_row = 1;
2149
+		foreach ($all_tickets as $ticket) {
2150
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2151
+				'DTTNUM',
2152
+				$ticket_row,
2153
+				null,
2154
+				$ticket,
2155
+				array(),
2156
+				true
2157
+			);
2158
+			$ticket_row++;
2159
+		}
2160
+		$datetime_row = 1;
2161
+		foreach ($all_datetimes as $datetime) {
2162
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2163
+				$datetime_row,
2164
+				'TICKETNUM',
2165
+				$datetime,
2166
+				null,
2167
+				array(),
2168
+				true
2169
+			);
2170
+			$datetime_row++;
2171
+		}
2172
+		/** @var EEM_Price $price_model */
2173
+		$price_model = EE_Registry::instance()->load_model('Price');
2174
+		$default_prices = $price_model->get_all_default_prices();
2175
+		$price_row = 1;
2176
+		foreach ($default_prices as $price) {
2177
+			if (! $price instanceof EE_Price) {
2178
+				continue;
2179
+			}
2180
+			if ($price->is_base_price()) {
2181
+				$template_args['default_base_price_amount'] = $price->get_pretty(
2182
+					'PRC_amount',
2183
+					'localized_float'
2184
+				);
2185
+				$template_args['default_base_price_name'] = $price->get('PRC_name');
2186
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
2187
+				$price_row++;
2188
+				continue;
2189
+			}
2190
+			$show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2191
+							 || count($default_prices) === 1);
2192
+			$show_create = ! (count($default_prices) > 1
2193
+							  && count($default_prices)
2194
+								 !== $price_row);
2195
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2196
+				'TICKETNUM',
2197
+				$price_row,
2198
+				$price,
2199
+				true,
2200
+				null,
2201
+				$show_trash,
2202
+				$show_create
2203
+			);
2204
+			$price_row++;
2205
+		}
2206
+		$template_args = apply_filters(
2207
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2208
+			$template_args,
2209
+			$all_datetimes,
2210
+			$all_tickets,
2211
+			$this->_is_creating_event
2212
+		);
2213
+		return EEH_Template::display_template(
2214
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2215
+			$template_args,
2216
+			true
2217
+		);
2218
+	}
2219 2219
 }
Please login to merge, or discard this patch.
Spacing   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
             );
154 154
             $msg .= '</p><ul>';
155 155
             foreach ($format_validation as $error) {
156
-                $msg .= '<li>' . $error . '</li>';
156
+                $msg .= '<li>'.$error.'</li>';
157 157
             }
158 158
             $msg .= '</ul><p>';
159 159
             $msg .= sprintf(
@@ -182,11 +182,11 @@  discard block
 block discarded – undo
182 182
         $this->_scripts_styles = array(
183 183
             'registers'   => array(
184 184
                 'ee-tickets-datetimes-css' => array(
185
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
185
+                    'url'  => PRICING_ASSETS_URL.'event-tickets-datetimes.css',
186 186
                     'type' => 'css',
187 187
                 ),
188 188
                 'ee-dtt-ticket-metabox'    => array(
189
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
189
+                    'url'     => PRICING_ASSETS_URL.'ee-datetime-ticket-metabox.js',
190 190
                     'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
191 191
                 ),
192 192
             ),
@@ -210,9 +210,9 @@  discard block
 block discarded – undo
210 210
                             'event_espresso'
211 211
                         ),
212 212
                         'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
213
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
213
+                                                     . esc_html__('Cancel', 'event_espresso').'</button>',
214 214
                         'close_button'            => '<button class="button-secondary ee-modal-cancel">'
215
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
215
+                                                     . esc_html__('Close', 'event_espresso').'</button>',
216 216
                         'single_warning_from_tkt' => esc_html__(
217 217
                             '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.',
218 218
                             'event_espresso'
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
                             'event_espresso'
223 223
                         ),
224 224
                         'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
225
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
225
+                                                     . esc_html__('Dismiss', 'event_espresso').'</button>',
226 226
                     ),
227 227
                     'DTT_ERROR_MSG'         => array(
228 228
                         'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
         foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
315 315
             // trim all values to ensure any excess whitespace is removed.
316 316
             $datetime_data = array_map(
317
-                function ($datetime_data) {
317
+                function($datetime_data) {
318 318
                     return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
319 319
                 },
320 320
                 $datetime_data
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
             );
345 345
             // if we have an id then let's get existing object first and then set the new values.
346 346
             // Otherwise we instantiate a new object for save.
347
-            if (! empty($datetime_data['DTT_ID'])) {
347
+            if ( ! empty($datetime_data['DTT_ID'])) {
348 348
                 $datetime = EE_Registry::instance()
349 349
                                        ->load_model('Datetime', array($timezone))
350 350
                                        ->get_one_by_ID($datetime_data['DTT_ID']);
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
                 // after the add_relation_to() the autosave replaces it.
359 359
                 // We need to do this so we dont' TRASH the parent DTT.
360 360
                 // (save the ID for both key and value to avoid duplications)
361
-                $saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
361
+                $saved_dtt_ids[$datetime->ID()] = $datetime->ID();
362 362
             } else {
363 363
                 $datetime = EE_Registry::instance()->load_class(
364 364
                     'Datetime',
@@ -394,8 +394,8 @@  discard block
 block discarded – undo
394 394
             // because it is possible there was a new one created for the autosave.
395 395
             // (save the ID for both key and value to avoid duplications)
396 396
             $DTT_ID = $datetime->ID();
397
-            $saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
398
-            $saved_dtt_objs[ $row ] = $datetime;
397
+            $saved_dtt_ids[$DTT_ID] = $DTT_ID;
398
+            $saved_dtt_objs[$row] = $datetime;
399 399
             // @todo if ANY of these updates fail then we want the appropriate global error message.
400 400
         }
401 401
         $event->save();
@@ -460,13 +460,13 @@  discard block
 block discarded – undo
460 460
             $update_prices = $create_new_TKT = false;
461 461
             // figure out what datetimes were added to the ticket
462 462
             // and what datetimes were removed from the ticket in the session.
463
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
464
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
463
+            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
464
+            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
465 465
             $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
466 466
             $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
467 467
             // trim inputs to ensure any excess whitespace is removed.
468 468
             $tkt = array_map(
469
-                function ($ticket_data) {
469
+                function($ticket_data) {
470 470
                     return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
471 471
                 },
472 472
                 $tkt
@@ -488,8 +488,8 @@  discard block
 block discarded – undo
488 488
             $base_price_id = isset($tkt['TKT_base_price_ID'])
489 489
                 ? $tkt['TKT_base_price_ID']
490 490
                 : 0;
491
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
492
-                ? $data['edit_prices'][ $row ]
491
+            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row])
492
+                ? $data['edit_prices'][$row]
493 493
                 : array();
494 494
             $now = null;
495 495
             if (empty($tkt['TKT_start_date'])) {
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
                 /**
502 502
                  * set the TKT_end_date to the first datetime attached to the ticket.
503 503
                  */
504
-                $first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
504
+                $first_dtt = $saved_datetimes[reset($tkt_dtt_rows)];
505 505
                 $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
506 506
             }
507 507
             $TKT_values = array(
@@ -636,7 +636,7 @@  discard block
 block discarded – undo
636 636
             // need to make sue that the TKT_price is accurate after saving the prices.
637 637
             $ticket->ensure_TKT_Price_correct();
638 638
             // handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
639
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
639
+            if ( ! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
640 640
                 $update_prices = true;
641 641
                 $new_default = clone $ticket;
642 642
                 $new_default->set('TKT_ID', 0);
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
                 // save new TKT
682 682
                 $new_tkt->save();
683 683
                 // add new ticket to array
684
-                $saved_tickets[ $new_tkt->ID() ] = $new_tkt;
684
+                $saved_tickets[$new_tkt->ID()] = $new_tkt;
685 685
                 do_action(
686 686
                     'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
687 687
                     $new_tkt,
@@ -691,7 +691,7 @@  discard block
 block discarded – undo
691 691
                 );
692 692
             } else {
693 693
                 // add tkt to saved tkts
694
-                $saved_tickets[ $ticket->ID() ] = $ticket;
694
+                $saved_tickets[$ticket->ID()] = $ticket;
695 695
                 do_action(
696 696
                     'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
697 697
                     $ticket,
@@ -758,22 +758,22 @@  discard block
 block discarded – undo
758 758
         // to start we have to add the ticket to all the datetimes its supposed to be with,
759 759
         // and removing the ticket from datetimes it got removed from.
760 760
         // first let's add datetimes
761
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
761
+        if ( ! empty($added_datetimes) && is_array($added_datetimes)) {
762 762
             foreach ($added_datetimes as $row_id) {
763 763
                 $row_id = (int) $row_id;
764
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
765
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
764
+                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
765
+                    $ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
766 766
                 }
767 767
             }
768 768
         }
769 769
         // then remove datetimes
770
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
770
+        if ( ! empty($removed_datetimes) && is_array($removed_datetimes)) {
771 771
             foreach ($removed_datetimes as $row_id) {
772 772
                 $row_id = (int) $row_id;
773 773
                 // its entirely possible that a datetime got deleted (instead of just removed from relationship.
774 774
                 // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
775
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
776
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
775
+                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
776
+                    $ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
777 777
                 }
778 778
             }
779 779
         }
@@ -885,7 +885,7 @@  discard block
 block discarded – undo
885 885
             );
886 886
         }
887 887
         // possibly need to save tkt
888
-        if (! $ticket->ID()) {
888
+        if ( ! $ticket->ID()) {
889 889
             $ticket->save();
890 890
         }
891 891
         foreach ($prices as $row => $prc) {
@@ -919,17 +919,17 @@  discard block
 block discarded – undo
919 919
                 }
920 920
             }
921 921
             $price->save();
922
-            $updated_prices[ $price->ID() ] = $price;
922
+            $updated_prices[$price->ID()] = $price;
923 923
             $ticket->_add_relation_to($price, 'Price');
924 924
         }
925 925
         // now let's remove any prices that got removed from the ticket
926
-        if (! empty($current_prices_on_ticket)) {
926
+        if ( ! empty($current_prices_on_ticket)) {
927 927
             $current = array_keys($current_prices_on_ticket);
928 928
             $updated = array_keys($updated_prices);
929 929
             $prices_to_remove = array_diff($current, $updated);
930
-            if (! empty($prices_to_remove)) {
930
+            if ( ! empty($prices_to_remove)) {
931 931
                 foreach ($prices_to_remove as $prc_id) {
932
-                    $p = $current_prices_on_ticket[ $prc_id ];
932
+                    $p = $current_prices_on_ticket[$prc_id];
933 933
                     $ticket->_remove_relation_to($p, 'Price');
934 934
                     // delete permanently the price
935 935
                     $p->delete_permanently();
@@ -1080,18 +1080,18 @@  discard block
 block discarded – undo
1080 1080
                 $TKT_ID = $ticket->get('TKT_ID');
1081 1081
                 $ticket_row = $ticket->get('TKT_row');
1082 1082
                 // we only want unique tickets in our final display!!
1083
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1083
+                if ( ! in_array($TKT_ID, $existing_ticket_ids, true)) {
1084 1084
                     $existing_ticket_ids[] = $TKT_ID;
1085 1085
                     $all_tickets[] = $ticket;
1086 1086
                 }
1087 1087
                 // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1088
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1088
+                $datetime_tickets[$DTT_ID][] = $ticket_row;
1089 1089
                 // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1090 1090
                 if (
1091
-                    ! isset($ticket_datetimes[ $TKT_ID ])
1092
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1091
+                    ! isset($ticket_datetimes[$TKT_ID])
1092
+                    || ! in_array($datetime_row, $ticket_datetimes[$TKT_ID], true)
1093 1093
                 ) {
1094
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1094
+                    $ticket_datetimes[$TKT_ID][] = $datetime_row;
1095 1095
                 }
1096 1096
             }
1097 1097
             $datetime_row++;
@@ -1102,7 +1102,7 @@  discard block
 block discarded – undo
1102 1102
         // sort $all_tickets by order
1103 1103
         usort(
1104 1104
             $all_tickets,
1105
-            function (EE_Ticket $a, EE_Ticket $b) {
1105
+            function(EE_Ticket $a, EE_Ticket $b) {
1106 1106
                 $a_order = (int) $a->get('TKT_order');
1107 1107
                 $b_order = (int) $b->get('TKT_order');
1108 1108
                 if ($a_order === $b_order) {
@@ -1143,16 +1143,16 @@  discard block
 block discarded – undo
1143 1143
         $status_change_notice = EventEspresso\core\services\loaders\LoaderFactory::getLoader()->getShared(
1144 1144
             'EventEspresso\core\admin\StatusChangeNotice'
1145 1145
         );
1146
-        if (! $status_change_notice->isDismissed()) {
1146
+        if ( ! $status_change_notice->isDismissed()) {
1147 1147
             $main_template_args['status_change_notice'] = EEH_Template::display_template(
1148
-                EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1148
+                EE_ADMIN_TEMPLATE.'status_change_notice.template.php',
1149 1149
                 ['context' => '__event-editor', 'page_slug' => 'espresso-events'],
1150 1150
                 true
1151 1151
             );
1152 1152
         }
1153 1153
 
1154 1154
         EEH_Template::display_template(
1155
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1155
+            PRICING_TEMPLATE_PATH.'event_tickets_metabox_main.template.php',
1156 1156
             $main_template_args
1157 1157
         );
1158 1158
     }
@@ -1194,7 +1194,7 @@  discard block
 block discarded – undo
1194 1194
             'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1195 1195
         );
1196 1196
         return EEH_Template::display_template(
1197
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1197
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_row_wrapper.template.php',
1198 1198
             $dtt_display_template_args,
1199 1199
             true
1200 1200
         );
@@ -1263,7 +1263,7 @@  discard block
 block discarded – undo
1263 1263
             $this->_is_creating_event
1264 1264
         );
1265 1265
         return EEH_Template::display_template(
1266
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1266
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_edit_row.template.php',
1267 1267
             $template_args,
1268 1268
             true
1269 1269
         );
@@ -1304,7 +1304,7 @@  discard block
 block discarded – undo
1304 1304
             'DTT_ID'                            => $default ? '' : $datetime->ID(),
1305 1305
         );
1306 1306
         // need to setup the list items (but only if this isn't a default skeleton setup)
1307
-        if (! $default) {
1307
+        if ( ! $default) {
1308 1308
             $ticket_row = 1;
1309 1309
             foreach ($all_tickets as $ticket) {
1310 1310
                 $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
@@ -1330,7 +1330,7 @@  discard block
 block discarded – undo
1330 1330
             $this->_is_creating_event
1331 1331
         );
1332 1332
         return EEH_Template::display_template(
1333
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1333
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_attached_tickets_row.template.php',
1334 1334
             $template_args,
1335 1335
             true
1336 1336
         );
@@ -1356,8 +1356,8 @@  discard block
 block discarded – undo
1356 1356
         $datetime_tickets = array(),
1357 1357
         $default
1358 1358
     ) {
1359
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1360
-            ? $datetime_tickets[ $datetime->ID() ]
1359
+        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[$datetime->ID()])
1360
+            ? $datetime_tickets[$datetime->ID()]
1361 1361
             : array();
1362 1362
         $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1363 1363
         $no_ticket = $default && empty($ticket);
@@ -1378,8 +1378,8 @@  discard block
 block discarded – undo
1378 1378
                 ? 'TKTNAME'
1379 1379
                 : $ticket->get('TKT_name'),
1380 1380
             'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1381
-                ? ' tkt-status-' . EE_Ticket::onsale
1382
-                : ' tkt-status-' . $ticket->ticket_status(),
1381
+                ? ' tkt-status-'.EE_Ticket::onsale
1382
+                : ' tkt-status-'.$ticket->ticket_status(),
1383 1383
         );
1384 1384
         // filter template args
1385 1385
         $template_args = apply_filters(
@@ -1394,7 +1394,7 @@  discard block
 block discarded – undo
1394 1394
             $this->_is_creating_event
1395 1395
         );
1396 1396
         return EEH_Template::display_template(
1397
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1397
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_dtt_tickets_list.template.php',
1398 1398
             $template_args,
1399 1399
             true
1400 1400
         );
@@ -1450,19 +1450,19 @@  discard block
 block discarded – undo
1450 1450
         // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1451 1451
         // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1452 1452
         $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1453
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1454
-            ? $ticket_datetimes[ $ticket->ID() ]
1453
+        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1454
+            ? $ticket_datetimes[$ticket->ID()]
1455 1455
             : array();
1456 1456
         $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1457 1457
         $base_price = $default ? null : $ticket->base_price();
1458 1458
         $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1459 1459
         // breaking out complicated condition for ticket_status
1460 1460
         if ($default) {
1461
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1461
+            $ticket_status_class = ' tkt-status-'.EE_Ticket::onsale;
1462 1462
         } else {
1463 1463
             $ticket_status_class = $ticket->is_default()
1464
-                ? ' tkt-status-' . EE_Ticket::onsale
1465
-                : ' tkt-status-' . $ticket->ticket_status();
1464
+                ? ' tkt-status-'.EE_Ticket::onsale
1465
+                : ' tkt-status-'.$ticket->ticket_status();
1466 1466
         }
1467 1467
         // breaking out complicated condition for TKT_taxable
1468 1468
         if ($default) {
@@ -1554,7 +1554,7 @@  discard block
 block discarded – undo
1554 1554
                 : ' style="display:none;"',
1555 1555
             'show_price_mod_button'         => count($prices) > 1
1556 1556
                                                || ($default && $count_price_mods > 0)
1557
-                                               || (! $default && $ticket->deleted())
1557
+                                               || ( ! $default && $ticket->deleted())
1558 1558
                 ? ' style="display:none;"'
1559 1559
                 : '',
1560 1560
             'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
@@ -1598,7 +1598,7 @@  discard block
 block discarded – undo
1598 1598
                 $this->_date_time_format,
1599 1599
                 current_time('timestamp')
1600 1600
             );
1601
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1601
+            $template_args['tkt_status_class'] = ' tkt-status-'.EE_Ticket::onsale;
1602 1602
         }
1603 1603
         if (empty($template_args['TKT_end_date'])) {
1604 1604
             // get the earliest datetime (if present);
@@ -1608,7 +1608,7 @@  discard block
 block discarded – undo
1608 1608
                     array('order_by' => array('DTT_EVT_start' => 'ASC'))
1609 1609
                 )
1610 1610
                 : null;
1611
-            if (! empty($earliest_dtt)) {
1611
+            if ( ! empty($earliest_dtt)) {
1612 1612
                 $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1613 1613
                     'DTT_EVT_start',
1614 1614
                     $this->_date_time_format
@@ -1627,10 +1627,10 @@  discard block
 block discarded – undo
1627 1627
                     )
1628 1628
                 );
1629 1629
             }
1630
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1630
+            $template_args['tkt_status_class'] = ' tkt-status-'.EE_Ticket::onsale;
1631 1631
         }
1632 1632
         // generate ticket_datetime items
1633
-        if (! $default) {
1633
+        if ( ! $default) {
1634 1634
             $datetime_row = 1;
1635 1635
             foreach ($all_datetimes as $datetime) {
1636 1636
                 $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
@@ -1646,7 +1646,7 @@  discard block
 block discarded – undo
1646 1646
         }
1647 1647
         $price_row = 1;
1648 1648
         foreach ($prices as $price) {
1649
-            if (! $price instanceof EE_Price) {
1649
+            if ( ! $price instanceof EE_Price) {
1650 1650
                 continue;
1651 1651
             }
1652 1652
             if ($price->is_base_price()) {
@@ -1679,7 +1679,7 @@  discard block
 block discarded – undo
1679 1679
             $this->_is_creating_event
1680 1680
         );
1681 1681
         return EEH_Template::display_template(
1682
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1682
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_row.template.php',
1683 1683
             $template_args,
1684 1684
             true
1685 1685
         );
@@ -1719,7 +1719,7 @@  discard block
 block discarded – undo
1719 1719
                 $this->_is_creating_event
1720 1720
             );
1721 1721
             $tax_rows .= EEH_Template::display_template(
1722
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1722
+                PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_tax_row.template.php',
1723 1723
                 $template_args,
1724 1724
                 true
1725 1725
             );
@@ -1838,7 +1838,7 @@  discard block
 block discarded – undo
1838 1838
             $this->_is_creating_event
1839 1839
         );
1840 1840
         return EEH_Template::display_template(
1841
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1841
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_price_row.template.php',
1842 1842
             $template_args,
1843 1843
             true
1844 1844
         );
@@ -1908,7 +1908,7 @@  discard block
 block discarded – undo
1908 1908
             $this->_is_creating_event
1909 1909
         );
1910 1910
         return EEH_Template::display_template(
1911
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1911
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_type_base.template.php',
1912 1912
             $template_args,
1913 1913
             true
1914 1914
         );
@@ -1938,7 +1938,7 @@  discard block
 block discarded – undo
1938 1938
     ) {
1939 1939
         $select_name = $default && ! $price instanceof EE_Price
1940 1940
             ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1941
-            : 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1941
+            : 'edit_prices['.$ticket_row.']['.$price_row.'][PRT_ID]';
1942 1942
         /** @var EEM_Price_Type $price_type_model */
1943 1943
         $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1944 1944
         $price_types = $price_type_model->get_all(array(
@@ -1956,10 +1956,10 @@  discard block
 block discarded – undo
1956 1956
         $price_option_spans = '';
1957 1957
         // setup price types for selector
1958 1958
         foreach ($price_types as $price_type) {
1959
-            if (! $price_type instanceof EE_Price_Type) {
1959
+            if ( ! $price_type instanceof EE_Price_Type) {
1960 1960
                 continue;
1961 1961
             }
1962
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1962
+            $all_price_types[$price_type->ID()] = $price_type->get('PRT_name');
1963 1963
             // while we're in the loop let's setup the option spans used by js
1964 1964
             $span_args = array(
1965 1965
                 'PRT_ID'         => $price_type->ID(),
@@ -1967,12 +1967,12 @@  discard block
 block discarded – undo
1967 1967
                 'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1968 1968
             );
1969 1969
             $price_option_spans .= EEH_Template::display_template(
1970
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1970
+                PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_option_span.template.php',
1971 1971
                 $span_args,
1972 1972
                 true
1973 1973
             );
1974 1974
         }
1975
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1975
+        $select_name = $disabled ? 'archive_price['.$ticket_row.']['.$price_row.'][PRT_ID]'
1976 1976
             : $select_name;
1977 1977
         $select_input = new EE_Select_Input(
1978 1978
             $all_price_types,
@@ -2009,7 +2009,7 @@  discard block
 block discarded – undo
2009 2009
             $this->_is_creating_event
2010 2010
         );
2011 2011
         return EEH_Template::display_template(
2012
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2012
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_modifier_selector.template.php',
2013 2013
             $template_args,
2014 2014
             true
2015 2015
         );
@@ -2035,8 +2035,8 @@  discard block
 block discarded – undo
2035 2035
         $ticket_datetimes = array(),
2036 2036
         $default
2037 2037
     ) {
2038
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2039
-            ? $ticket_datetimes[ $ticket->ID() ]
2038
+        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
2039
+            ? $ticket_datetimes[$ticket->ID()]
2040 2040
             : array();
2041 2041
         $template_args = array(
2042 2042
             'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
@@ -2068,7 +2068,7 @@  discard block
 block discarded – undo
2068 2068
             $this->_is_creating_event
2069 2069
         );
2070 2070
         return EEH_Template::display_template(
2071
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2071
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2072 2072
             $template_args,
2073 2073
             true
2074 2074
         );
@@ -2174,7 +2174,7 @@  discard block
 block discarded – undo
2174 2174
         $default_prices = $price_model->get_all_default_prices();
2175 2175
         $price_row = 1;
2176 2176
         foreach ($default_prices as $price) {
2177
-            if (! $price instanceof EE_Price) {
2177
+            if ( ! $price instanceof EE_Price) {
2178 2178
                 continue;
2179 2179
             }
2180 2180
             if ($price->is_base_price()) {
@@ -2211,7 +2211,7 @@  discard block
 block discarded – undo
2211 2211
             $this->_is_creating_event
2212 2212
         );
2213 2213
         return EEH_Template::display_template(
2214
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2214
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_js_structure.template.php',
2215 2215
             $template_args,
2216 2216
             true
2217 2217
         );
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +699 added lines, -699 removed lines patch added patch discarded remove patch
@@ -2,137 +2,137 @@  discard block
 block discarded – undo
2 2
 /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3 3
 $generated_i18n_strings = array(
4 4
 	// Reference: packages/ui-components/src/Pagination/constants.ts:6
5
-	__( '2', 'event_espresso' ),
5
+	__('2', 'event_espresso'),
6 6
 
7 7
 	// Reference: packages/ui-components/src/Pagination/constants.ts:7
8
-	__( '6', 'event_espresso' ),
8
+	__('6', 'event_espresso'),
9 9
 
10 10
 	// Reference: packages/ui-components/src/Pagination/constants.ts:8
11
-	__( '12', 'event_espresso' ),
11
+	__('12', 'event_espresso'),
12 12
 
13 13
 	// Reference: packages/ui-components/src/Pagination/constants.ts:9
14
-	__( '24', 'event_espresso' ),
14
+	__('24', 'event_espresso'),
15 15
 
16 16
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
17
-	__( '48', 'event_espresso' ),
17
+	__('48', 'event_espresso'),
18 18
 
19 19
 	// Reference: domains/core/admin/blocks/src/components/AvatarImage.tsx:27
20
-	__( 'contact avatar', 'event_espresso' ),
20
+	__('contact avatar', 'event_espresso'),
21 21
 
22 22
 	// Reference: domains/core/admin/blocks/src/components/OrderByControl.tsx:12
23
-	__( 'Order by', 'event_espresso' ),
23
+	__('Order by', 'event_espresso'),
24 24
 
25 25
 	// Reference: domains/core/admin/blocks/src/components/RegStatusControl.tsx:17
26 26
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectStatus.tsx:13
27
-	__( 'Select Registration Status', 'event_espresso' ),
27
+	__('Select Registration Status', 'event_espresso'),
28 28
 
29 29
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:14
30
-	__( 'Ascending', 'event_espresso' ),
30
+	__('Ascending', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:18
33
-	__( 'Descending', 'event_espresso' ),
33
+	__('Descending', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:24
36
-	__( 'Sort order:', 'event_espresso' ),
36
+	__('Sort order:', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:41
39
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
39
+	__('There was some error fetching attendees list', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:47
42
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
42
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:53
45
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
45
+	__('There are no attendees for selected options.', 'event_espresso'),
46 46
 
47 47
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:12
48
-	__( 'Display on Archives', 'event_espresso' ),
48
+	__('Display on Archives', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
51
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
51
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:18
54
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
54
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:29
57
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
57
+	__('Number of Attendees to Display:', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:34
60 60
 	/* translators: %d attendees count */
61
-	_n_noop( 'Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso' ),
61
+	_n_noop('Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso'),
62 62
 
63 63
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:27
64
-	__( 'Display Gravatar', 'event_espresso' ),
64
+	__('Display Gravatar', 'event_espresso'),
65 65
 
66 66
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
67
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
67
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
68 68
 
69 69
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:33
70
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
70
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
71 71
 
72 72
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:38
73
-	__( 'Size of Gravatar', 'event_espresso' ),
73
+	__('Size of Gravatar', 'event_espresso'),
74 74
 
75 75
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectDatetime.tsx:22
76
-	__( 'Select Datetime', 'event_espresso' ),
76
+	__('Select Datetime', 'event_espresso'),
77 77
 
78 78
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectEvent.tsx:22
79 79
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectEvent.tsx:22
80
-	__( 'Select Event', 'event_espresso' ),
80
+	__('Select Event', 'event_espresso'),
81 81
 
82 82
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:11
83
-	__( 'Attendee id', 'event_espresso' ),
83
+	__('Attendee id', 'event_espresso'),
84 84
 
85 85
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:15
86
-	__( 'Last name only', 'event_espresso' ),
86
+	__('Last name only', 'event_espresso'),
87 87
 
88 88
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:19
89
-	__( 'First name only', 'event_espresso' ),
89
+	__('First name only', 'event_espresso'),
90 90
 
91 91
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:23
92
-	__( 'First, then Last name', 'event_espresso' ),
92
+	__('First, then Last name', 'event_espresso'),
93 93
 
94 94
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:27
95
-	__( 'Last, then First name', 'event_espresso' ),
95
+	__('Last, then First name', 'event_espresso'),
96 96
 
97 97
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:41
98
-	__( 'Order Attendees by:', 'event_espresso' ),
98
+	__('Order Attendees by:', 'event_espresso'),
99 99
 
100 100
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectTicket.tsx:22
101
-	__( 'Select Ticket', 'event_espresso' ),
101
+	__('Select Ticket', 'event_espresso'),
102 102
 
103 103
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:21
104
-	__( 'Filter By Settings', 'event_espresso' ),
104
+	__('Filter By Settings', 'event_espresso'),
105 105
 
106 106
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:36
107
-	__( 'Gravatar Setttings', 'event_espresso' ),
107
+	__('Gravatar Setttings', 'event_espresso'),
108 108
 
109 109
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:39
110
-	__( 'Archive Settings', 'event_espresso' ),
110
+	__('Archive Settings', 'event_espresso'),
111 111
 
112 112
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:10
113
-	__( 'Event Attendees', 'event_espresso' ),
113
+	__('Event Attendees', 'event_espresso'),
114 114
 
115 115
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:11
116
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
116
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
117 117
 
118 118
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
119 119
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
120 120
 	// Reference: packages/edtr-services/src/constants.ts:25
121
-	__( 'event', 'event_espresso' ),
121
+	__('event', 'event_espresso'),
122 122
 
123 123
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
124
-	__( 'attendees', 'event_espresso' ),
124
+	__('attendees', 'event_espresso'),
125 125
 
126 126
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
127
-	__( 'list', 'event_espresso' ),
127
+	__('list', 'event_espresso'),
128 128
 
129 129
 	// Reference: domains/core/admin/blocks/src/event/DisplayField.tsx:41
130
-	__( 'An unknown error occurred while fetching event details.', 'event_espresso' ),
130
+	__('An unknown error occurred while fetching event details.', 'event_espresso'),
131 131
 
132 132
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:10
133 133
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:24
134 134
 	// Reference: packages/utils/src/list/index.ts:14
135
-	__( 'Select…', 'event_espresso' ),
135
+	__('Select…', 'event_espresso'),
136 136
 
137 137
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:15
138 138
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:75
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:97
142 142
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:49
143 143
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:40
144
-	__( 'Name', 'event_espresso' ),
144
+	__('Name', 'event_espresso'),
145 145
 
146 146
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:19
147 147
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:80
@@ -149,401 +149,401 @@  discard block
 block discarded – undo
149 149
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:102
150 150
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:55
151 151
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
152
-	__( 'Description', 'event_espresso' ),
152
+	__('Description', 'event_espresso'),
153 153
 
154 154
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:23
155
-	__( 'Short description', 'event_espresso' ),
155
+	__('Short description', 'event_espresso'),
156 156
 
157 157
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:35
158
-	__( 'Select Field', 'event_espresso' ),
158
+	__('Select Field', 'event_espresso'),
159 159
 
160 160
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:27
161
-	__( 'Text Color', 'event_espresso' ),
161
+	__('Text Color', 'event_espresso'),
162 162
 
163 163
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:32
164
-	__( 'Background Color', 'event_espresso' ),
164
+	__('Background Color', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:41
167 167
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:22
168 168
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:21
169
-	__( 'Settings', 'event_espresso' ),
169
+	__('Settings', 'event_espresso'),
170 170
 
171 171
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:45
172
-	__( 'Typography', 'event_espresso' ),
172
+	__('Typography', 'event_espresso'),
173 173
 
174 174
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:48
175
-	__( 'Color', 'event_espresso' ),
175
+	__('Color', 'event_espresso'),
176 176
 
177 177
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
178
-	__( 'field', 'event_espresso' ),
178
+	__('field', 'event_espresso'),
179 179
 
180 180
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:8
181
-	__( 'Event Field', 'event_espresso' ),
181
+	__('Event Field', 'event_espresso'),
182 182
 
183 183
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:9
184
-	__( 'Displays the selected field of an event', 'event_espresso' ),
184
+	__('Displays the selected field of an event', 'event_espresso'),
185 185
 
186 186
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:17
187
-	__( 'Error', 'event_espresso' ),
187
+	__('Error', 'event_espresso'),
188 188
 
189 189
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:9
190
-	__( 'Loading…', 'event_espresso' ),
190
+	__('Loading…', 'event_espresso'),
191 191
 
192 192
 	// Reference: domains/core/admin/eventEditor/src/ui/EventDescription.tsx:33
193
-	__( 'Event Description', 'event_espresso' ),
193
+	__('Event Description', 'event_espresso'),
194 194
 
195 195
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/ActiveStatus.tsx:29
196
-	__( 'Active status', 'event_espresso' ),
196
+	__('Active status', 'event_espresso'),
197 197
 
198 198
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/AltRegPage.tsx:12
199
-	__( 'Alternative Registration Page', 'event_espresso' ),
199
+	__('Alternative Registration Page', 'event_espresso'),
200 200
 
201 201
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/DefaultRegistrationStatus.tsx:26
202
-	__( 'Default Registration Status', 'event_espresso' ),
202
+	__('Default Registration Status', 'event_espresso'),
203 203
 
204 204
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
205
-	__( 'Donations Enabled', 'event_espresso' ),
205
+	__('Donations Enabled', 'event_espresso'),
206 206
 
207 207
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
208
-	__( 'Donations Disabled', 'event_espresso' ),
208
+	__('Donations Disabled', 'event_espresso'),
209 209
 
210 210
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventManager.tsx:16
211
-	__( 'Event Manager', 'event_espresso' ),
211
+	__('Event Manager', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventPhoneNumber.tsx:15
214
-	__( 'Event Phone Number', 'event_espresso' ),
214
+	__('Event Phone Number', 'event_espresso'),
215 215
 
216 216
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/MaxRegistrations.tsx:13
217
-	__( 'Max Registrations per Transaction', 'event_espresso' ),
217
+	__('Max Registrations per Transaction', 'event_espresso'),
218 218
 
219 219
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
220
-	__( 'Ticket Selector Enabled', 'event_espresso' ),
220
+	__('Ticket Selector Enabled', 'event_espresso'),
221 221
 
222 222
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
223
-	__( 'Ticket Selector Disabled', 'event_espresso' ),
223
+	__('Ticket Selector Disabled', 'event_espresso'),
224 224
 
225 225
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:41
226
-	__( 'Event Details', 'event_espresso' ),
226
+	__('Event Details', 'event_espresso'),
227 227
 
228 228
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:47
229
-	__( 'Registration Options', 'event_espresso' ),
229
+	__('Registration Options', 'event_espresso'),
230 230
 
231 231
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
232
-	__( 'primary information about the date', 'event_espresso' ),
232
+	__('primary information about the date', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
235
-	__( 'Date Details', 'event_espresso' ),
235
+	__('Date Details', 'event_espresso'),
236 236
 
237 237
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
238 238
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
239 239
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
240
-	__( 'relations between tickets and dates', 'event_espresso' ),
240
+	__('relations between tickets and dates', 'event_espresso'),
241 241
 
242 242
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
243
-	__( 'Assign Tickets', 'event_espresso' ),
243
+	__('Assign Tickets', 'event_espresso'),
244 244
 
245 245
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/FooterButtons.tsx:22
246
-	__( 'Save and assign tickets', 'event_espresso' ),
246
+	__('Save and assign tickets', 'event_espresso'),
247 247
 
248 248
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:27
249 249
 	/* translators: %s datetime id */
250
-	__( 'Edit datetime %s', 'event_espresso' ),
250
+	__('Edit datetime %s', 'event_espresso'),
251 251
 
252 252
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:30
253
-	__( 'New Datetime', 'event_espresso' ),
253
+	__('New Datetime', 'event_espresso'),
254 254
 
255 255
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:110
256 256
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:108
257 257
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:132
258 258
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:108
259
-	__( 'Details', 'event_espresso' ),
259
+	__('Details', 'event_espresso'),
260 260
 
261 261
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:114
262 262
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:112
263 263
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:81
264
-	__( 'Capacity', 'event_espresso' ),
264
+	__('Capacity', 'event_espresso'),
265 265
 
266 266
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:119
267
-	__( 'The maximum number of registrants that can attend the event at this particular date.', 'event_espresso' ),
267
+	__('The maximum number of registrants that can attend the event at this particular date.', 'event_espresso'),
268 268
 
269 269
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:123
270
-	__( 'Set to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
270
+	__('Set to 0 to close registration or leave blank for no limit.', 'event_espresso'),
271 271
 
272 272
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:129
273 273
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:209
274
-	__( 'Trash', 'event_espresso' ),
274
+	__('Trash', 'event_espresso'),
275 275
 
276 276
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:71
277 277
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:45
278 278
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:93
279 279
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:45
280
-	__( 'Basics', 'event_espresso' ),
280
+	__('Basics', 'event_espresso'),
281 281
 
282 282
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:88
283 283
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:63
284 284
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:63
285
-	__( 'Dates', 'event_espresso' ),
285
+	__('Dates', 'event_espresso'),
286 286
 
287 287
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
288 288
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:51
289 289
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:114
290
-	__( 'Start Date', 'event_espresso' ),
290
+	__('Start Date', 'event_espresso'),
291 291
 
292 292
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:99
293 293
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:65
294 294
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:121
295
-	__( 'End Date', 'event_espresso' ),
295
+	__('End Date', 'event_espresso'),
296 296
 
297 297
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateRegistrationsLink.tsx:13
298
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
298
+	__('view ALL registrations for this date.', 'event_espresso'),
299 299
 
300 300
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateSoldLink.tsx:13
301
-	__( 'view approved registrations for this date.', 'event_espresso' ),
301
+	__('view approved registrations for this date.', 'event_espresso'),
302 302
 
303 303
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:35
304 304
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:33
305
-	__( 'Event Dates', 'event_espresso' ),
305
+	__('Event Dates', 'event_espresso'),
306 306
 
307 307
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:38
308
-	__( 'loading event dates…', 'event_espresso' ),
308
+	__('loading event dates…', 'event_espresso'),
309 309
 
310 310
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:20
311
-	__( 'Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso' ),
311
+	__('Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso'),
312 312
 
313 313
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:30
314
-	__( 'Ticket Assignments', 'event_espresso' ),
314
+	__('Ticket Assignments', 'event_espresso'),
315 315
 
316 316
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:25
317
-	__( 'Number of related tickets', 'event_espresso' ),
317
+	__('Number of related tickets', 'event_espresso'),
318 318
 
319 319
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:26
320
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
320
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
321 321
 
322 322
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:34
323
-	__( 'assign tickets', 'event_espresso' ),
323
+	__('assign tickets', 'event_espresso'),
324 324
 
325 325
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
326
-	__( 'Permanently delete Datetime?', 'event_espresso' ),
326
+	__('Permanently delete Datetime?', 'event_espresso'),
327 327
 
328 328
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
329
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
329
+	__('Move Datetime to Trash?', 'event_espresso'),
330 330
 
331 331
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:27
332
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
332
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
333 333
 
334 334
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:30
335
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
335
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
336 336
 
337 337
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
338 338
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
339
-	__( 'delete permanently', 'event_espresso' ),
339
+	__('delete permanently', 'event_espresso'),
340 340
 
341 341
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
342
-	__( 'trash datetime', 'event_espresso' ),
342
+	__('trash datetime', 'event_espresso'),
343 343
 
344 344
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:45
345
-	__( 'event date main menu', 'event_espresso' ),
345
+	__('event date main menu', 'event_espresso'),
346 346
 
347 347
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:59
348
-	__( 'edit datetime', 'event_espresso' ),
348
+	__('edit datetime', 'event_espresso'),
349 349
 
350 350
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:60
351
-	__( 'copy datetime', 'event_espresso' ),
351
+	__('copy datetime', 'event_espresso'),
352 352
 
353 353
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:36
354 354
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:39
355 355
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:43
356
-	__( 'bulk actions', 'event_espresso' ),
356
+	__('bulk actions', 'event_espresso'),
357 357
 
358 358
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:40
359
-	__( 'edit datetime details', 'event_espresso' ),
359
+	__('edit datetime details', 'event_espresso'),
360 360
 
361 361
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
362
-	__( 'delete datetimes', 'event_espresso' ),
362
+	__('delete datetimes', 'event_espresso'),
363 363
 
364 364
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
365
-	__( 'trash datetimes', 'event_espresso' ),
365
+	__('trash datetimes', 'event_espresso'),
366 366
 
367 367
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
368
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
368
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
369 369
 
370 370
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
371
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
371
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
372 372
 
373 373
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
374
-	__( 'Delete datetimes permanently', 'event_espresso' ),
374
+	__('Delete datetimes permanently', 'event_espresso'),
375 375
 
376 376
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
377
-	__( 'Trash datetimes', 'event_espresso' ),
377
+	__('Trash datetimes', 'event_espresso'),
378 378
 
379 379
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:21
380
-	__( 'Bulk edit date details', 'event_espresso' ),
380
+	__('Bulk edit date details', 'event_espresso'),
381 381
 
382 382
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
383
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
383
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
384 384
 
385 385
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
386 386
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
387
-	__( 'Name must be at least three characters', 'event_espresso' ),
387
+	__('Name must be at least three characters', 'event_espresso'),
388 388
 
389 389
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:67
390 390
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:67
391
-	__( 'Shift dates', 'event_espresso' ),
391
+	__('Shift dates', 'event_espresso'),
392 392
 
393 393
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:92
394 394
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:92
395
-	__( 'earlier', 'event_espresso' ),
395
+	__('earlier', 'event_espresso'),
396 396
 
397 397
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:96
398 398
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:96
399
-	__( 'later', 'event_espresso' ),
399
+	__('later', 'event_espresso'),
400 400
 
401 401
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:31
402 402
 	/* translators: click to edit capacity<linebreak>(registration limit)… */
403
-	__( 'click to edit capacity%s(registration limit)…', 'event_espresso' ),
403
+	__('click to edit capacity%s(registration limit)…', 'event_espresso'),
404 404
 
405 405
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:31
406 406
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:27
407 407
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:34
408
-	__( 'starts', 'event_espresso' ),
408
+	__('starts', 'event_espresso'),
409 409
 
410 410
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
411 411
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:34
412 412
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:47
413
-	__( 'ends', 'event_espresso' ),
413
+	__('ends', 'event_espresso'),
414 414
 
415 415
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
416
-	__( 'started', 'event_espresso' ),
416
+	__('started', 'event_espresso'),
417 417
 
418 418
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
419
-	__( 'ended', 'event_espresso' ),
419
+	__('ended', 'event_espresso'),
420 420
 
421 421
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:46
422
-	__( 'Edit Event Date', 'event_espresso' ),
422
+	__('Edit Event Date', 'event_espresso'),
423 423
 
424 424
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:50
425
-	__( 'edit start and end dates', 'event_espresso' ),
425
+	__('edit start and end dates', 'event_espresso'),
426 426
 
427 427
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:16
428 428
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:16
429
-	__( 'sold', 'event_espresso' ),
429
+	__('sold', 'event_espresso'),
430 430
 
431 431
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:21
432
-	__( 'capacity', 'event_espresso' ),
432
+	__('capacity', 'event_espresso'),
433 433
 
434 434
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:27
435 435
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:26
436
-	__( 'reg list', 'event_espresso' ),
436
+	__('reg list', 'event_espresso'),
437 437
 
438 438
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:43
439 439
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:35
440
-	__( 'add description…', 'event_espresso' ),
440
+	__('add description…', 'event_espresso'),
441 441
 
442 442
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:44
443 443
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:36
444
-	__( 'Edit description', 'event_espresso' ),
444
+	__('Edit description', 'event_espresso'),
445 445
 
446 446
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:45
447 447
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:37
448
-	__( 'click to edit description…', 'event_espresso' ),
448
+	__('click to edit description…', 'event_espresso'),
449 449
 
450 450
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:10
451
-	__( 'Move Date to Trash', 'event_espresso' ),
451
+	__('Move Date to Trash', 'event_espresso'),
452 452
 
453 453
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:13
454 454
 	// Reference: packages/constants/src/datetime.ts:6
455
-	__( 'Active', 'event_espresso' ),
455
+	__('Active', 'event_espresso'),
456 456
 
457 457
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:14
458 458
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:13
459
-	__( 'Trashed', 'event_espresso' ),
459
+	__('Trashed', 'event_espresso'),
460 460
 
461 461
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:15
462 462
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:14
463 463
 	// Reference: packages/constants/src/datetime.ts:8
464
-	__( 'Expired', 'event_espresso' ),
464
+	__('Expired', 'event_espresso'),
465 465
 
466 466
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:16
467 467
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:16
468
-	__( 'Sold Out', 'event_espresso' ),
468
+	__('Sold Out', 'event_espresso'),
469 469
 
470 470
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:17
471 471
 	// Reference: packages/constants/src/datetime.ts:12
472
-	__( 'Upcoming', 'event_espresso' ),
472
+	__('Upcoming', 'event_espresso'),
473 473
 
474 474
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:7
475
-	__( 'Edit Event Date Details', 'event_espresso' ),
475
+	__('Edit Event Date Details', 'event_espresso'),
476 476
 
477 477
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:8
478
-	__( 'View Registrations for this Date', 'event_espresso' ),
478
+	__('View Registrations for this Date', 'event_espresso'),
479 479
 
480 480
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:9
481
-	__( 'Manage Ticket Assignments', 'event_espresso' ),
481
+	__('Manage Ticket Assignments', 'event_espresso'),
482 482
 
483 483
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:41
484 484
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:41
485
-	__( 'click to edit title…', 'event_espresso' ),
485
+	__('click to edit title…', 'event_espresso'),
486 486
 
487 487
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:42
488 488
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:42
489
-	__( 'add title…', 'event_espresso' ),
489
+	__('add title…', 'event_espresso'),
490 490
 
491 491
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:17
492 492
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:17
493
-	__( 'ON', 'event_espresso' ),
493
+	__('ON', 'event_espresso'),
494 494
 
495 495
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
496
-	__( 'end dates only', 'event_espresso' ),
496
+	__('end dates only', 'event_espresso'),
497 497
 
498 498
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:11
499
-	__( 'start and end dates', 'event_espresso' ),
499
+	__('start and end dates', 'event_espresso'),
500 500
 
501 501
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
502
-	__( 'dates above 90% capacity', 'event_espresso' ),
502
+	__('dates above 90% capacity', 'event_espresso'),
503 503
 
504 504
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
505
-	__( 'dates above 75% capacity', 'event_espresso' ),
505
+	__('dates above 75% capacity', 'event_espresso'),
506 506
 
507 507
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
508
-	__( 'dates above 50% capacity', 'event_espresso' ),
508
+	__('dates above 50% capacity', 'event_espresso'),
509 509
 
510 510
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:19
511
-	__( 'dates below 50% capacity', 'event_espresso' ),
511
+	__('dates below 50% capacity', 'event_espresso'),
512 512
 
513 513
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
514
-	__( 'all dates', 'event_espresso' ),
514
+	__('all dates', 'event_espresso'),
515 515
 
516 516
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
517
-	__( 'all active and upcoming', 'event_espresso' ),
517
+	__('all active and upcoming', 'event_espresso'),
518 518
 
519 519
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
520
-	__( 'active dates only', 'event_espresso' ),
520
+	__('active dates only', 'event_espresso'),
521 521
 
522 522
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
523
-	__( 'upcoming dates only', 'event_espresso' ),
523
+	__('upcoming dates only', 'event_espresso'),
524 524
 
525 525
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
526
-	__( 'next active or upcoming only', 'event_espresso' ),
526
+	__('next active or upcoming only', 'event_espresso'),
527 527
 
528 528
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
529
-	__( 'sold out dates only', 'event_espresso' ),
529
+	__('sold out dates only', 'event_espresso'),
530 530
 
531 531
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
532
-	__( 'recently expired dates', 'event_espresso' ),
532
+	__('recently expired dates', 'event_espresso'),
533 533
 
534 534
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
535
-	__( 'all expired dates', 'event_espresso' ),
535
+	__('all expired dates', 'event_espresso'),
536 536
 
537 537
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:31
538
-	__( 'trashed dates only', 'event_espresso' ),
538
+	__('trashed dates only', 'event_espresso'),
539 539
 
540 540
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
541 541
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:9
542 542
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:61
543
-	__( 'start date', 'event_espresso' ),
543
+	__('start date', 'event_espresso'),
544 544
 
545 545
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
546
-	__( 'name', 'event_espresso' ),
546
+	__('name', 'event_espresso'),
547 547
 
548 548
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
549 549
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:31
@@ -551,182 +551,182 @@  discard block
 block discarded – undo
551 551
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:27
552 552
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:31
553 553
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
554
-	__( 'ID', 'event_espresso' ),
554
+	__('ID', 'event_espresso'),
555 555
 
556 556
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:38
557 557
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:47
558
-	__( 'custom order', 'event_espresso' ),
558
+	__('custom order', 'event_espresso'),
559 559
 
560 560
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
561 561
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:51
562
-	__( 'display', 'event_espresso' ),
562
+	__('display', 'event_espresso'),
563 563
 
564 564
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
565
-	__( 'recurrence', 'event_espresso' ),
565
+	__('recurrence', 'event_espresso'),
566 566
 
567 567
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
568 568
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
569
-	__( 'sales', 'event_espresso' ),
569
+	__('sales', 'event_espresso'),
570 570
 
571 571
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
572 572
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
573
-	__( 'sort by', 'event_espresso' ),
573
+	__('sort by', 'event_espresso'),
574 574
 
575 575
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
576 576
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
577 577
 	// Reference: packages/ee-components/src/EntityList/EntityListFilterBar.tsx:46
578
-	__( 'search', 'event_espresso' ),
578
+	__('search', 'event_espresso'),
579 579
 
580 580
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:47
581 581
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
582
-	__( 'status', 'event_espresso' ),
582
+	__('status', 'event_espresso'),
583 583
 
584 584
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
585
-	__( 'start dates only', 'event_espresso' ),
585
+	__('start dates only', 'event_espresso'),
586 586
 
587 587
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
588 588
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/NewDateModal.tsx:12
589 589
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsModalButton.tsx:16
590
-	__( 'Add New Date', 'event_espresso' ),
590
+	__('Add New Date', 'event_espresso'),
591 591
 
592 592
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
593
-	__( 'Add Single Date', 'event_espresso' ),
593
+	__('Add Single Date', 'event_espresso'),
594 594
 
595 595
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:44
596
-	__( 'Add a single date that only occurs once', 'event_espresso' ),
596
+	__('Add a single date that only occurs once', 'event_espresso'),
597 597
 
598 598
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:46
599
-	__( 'Single Date', 'event_espresso' ),
599
+	__('Single Date', 'event_espresso'),
600 600
 
601 601
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:106
602
-	__( 'Reg list', 'event_espresso' ),
602
+	__('Reg list', 'event_espresso'),
603 603
 
604 604
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:107
605 605
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:111
606
-	__( 'Regs', 'event_espresso' ),
606
+	__('Regs', 'event_espresso'),
607 607
 
608 608
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:122
609 609
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:126
610 610
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:59
611
-	__( 'Actions', 'event_espresso' ),
611
+	__('Actions', 'event_espresso'),
612 612
 
613 613
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:52
614
-	__( 'Start', 'event_espresso' ),
614
+	__('Start', 'event_espresso'),
615 615
 
616 616
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:66
617
-	__( 'End', 'event_espresso' ),
617
+	__('End', 'event_espresso'),
618 618
 
619 619
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:82
620
-	__( 'Cap', 'event_espresso' ),
620
+	__('Cap', 'event_espresso'),
621 621
 
622 622
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:94
623 623
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:98
624
-	__( 'Sold', 'event_espresso' ),
624
+	__('Sold', 'event_espresso'),
625 625
 
626 626
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:33
627 627
 	// Reference: packages/form-builder/src/constants.ts:67
628
-	__( 'Text Input', 'event_espresso' ),
628
+	__('Text Input', 'event_espresso'),
629 629
 
630 630
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:34
631 631
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:32
632
-	__( 'Attendee First Name', 'event_espresso' ),
632
+	__('Attendee First Name', 'event_espresso'),
633 633
 
634 634
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:39
635 635
 	/* translators: field name */
636
-	__( 'Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso' ),
636
+	__('Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso'),
637 637
 
638 638
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:40
639 639
 	// Reference: packages/form-builder/src/constants.ts:82
640
-	__( 'Email Address', 'event_espresso' ),
640
+	__('Email Address', 'event_espresso'),
641 641
 
642 642
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:41
643 643
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:40
644
-	__( 'Attendee Email Address', 'event_espresso' ),
644
+	__('Attendee Email Address', 'event_espresso'),
645 645
 
646 646
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:49
647
-	__( 'Please add the required fields', 'event_espresso' ),
647
+	__('Please add the required fields', 'event_espresso'),
648 648
 
649 649
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/RegistrationForm.tsx:12
650
-	__( 'Registration Form', 'event_espresso' ),
650
+	__('Registration Form', 'event_espresso'),
651 651
 
652 652
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:13
653
-	__( 'primary registrant', 'event_espresso' ),
653
+	__('primary registrant', 'event_espresso'),
654 654
 
655 655
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:17
656
-	__( 'purchaser', 'event_espresso' ),
656
+	__('purchaser', 'event_espresso'),
657 657
 
658 658
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:21
659
-	__( 'registrants', 'event_espresso' ),
659
+	__('registrants', 'event_espresso'),
660 660
 
661 661
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:36
662
-	__( 'Attendee Last Name', 'event_espresso' ),
662
+	__('Attendee Last Name', 'event_espresso'),
663 663
 
664 664
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:44
665
-	__( 'Attendee Address', 'event_espresso' ),
665
+	__('Attendee Address', 'event_espresso'),
666 666
 
667 667
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:9
668
-	__( 'all', 'event_espresso' ),
668
+	__('all', 'event_espresso'),
669 669
 
670 670
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
671
-	__( 'Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
672
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
671
+	__('Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
672
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
673 673
 
674 674
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
675
-	__( 'Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
676
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
675
+	__('Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
676
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
677 677
 
678 678
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
679
-	__( 'Please Update Assignments', 'event_espresso' ),
679
+	__('Please Update Assignments', 'event_espresso'),
680 680
 
681 681
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:26
682
-	__( 'There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso' ),
682
+	__('There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso'),
683 683
 
684 684
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:29
685 685
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:74
686 686
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:21
687
-	__( 'Alert!', 'event_espresso' ),
687
+	__('Alert!', 'event_espresso'),
688 688
 
689 689
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:42
690 690
 	/* translators: 1 entity id, 2 entity name */
691
-	__( 'Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso' ),
691
+	__('Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso'),
692 692
 
693 693
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:49
694 694
 	/* translators: 1 entity id, 2 entity name */
695
-	__( 'Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso' ),
695
+	__('Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso'),
696 696
 
697 697
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal.tsx:28
698 698
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:13
699
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
699
+	__('Ticket Assignment Manager', 'event_espresso'),
700 700
 
701 701
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:10
702
-	__( 'existing relation', 'event_espresso' ),
702
+	__('existing relation', 'event_espresso'),
703 703
 
704 704
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:15
705
-	__( 'remove existing relation', 'event_espresso' ),
705
+	__('remove existing relation', 'event_espresso'),
706 706
 
707 707
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:20
708
-	__( 'add new relation', 'event_espresso' ),
708
+	__('add new relation', 'event_espresso'),
709 709
 
710 710
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:25
711
-	__( 'invalid relation', 'event_espresso' ),
711
+	__('invalid relation', 'event_espresso'),
712 712
 
713 713
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:29
714
-	__( 'no relation', 'event_espresso' ),
714
+	__('no relation', 'event_espresso'),
715 715
 
716 716
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/BodyCell.tsx:23
717
-	__( 'assign ticket', 'event_espresso' ),
717
+	__('assign ticket', 'event_espresso'),
718 718
 
719 719
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:15
720
-	__( 'Assignments', 'event_espresso' ),
720
+	__('Assignments', 'event_espresso'),
721 721
 
722 722
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:16
723
-	__( 'Event Dates are listed below', 'event_espresso' ),
723
+	__('Event Dates are listed below', 'event_espresso'),
724 724
 
725 725
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:17
726
-	__( 'Tickets are listed along the top', 'event_espresso' ),
726
+	__('Tickets are listed along the top', 'event_espresso'),
727 727
 
728 728
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:18
729
-	__( 'Click the cell buttons to toggle assigments', 'event_espresso' ),
729
+	__('Click the cell buttons to toggle assigments', 'event_espresso'),
730 730
 
731 731
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/useSubmitButtonProps.ts:29
732 732
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
@@ -735,1530 +735,1530 @@  discard block
 block discarded – undo
735 735
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:29
736 736
 	// Reference: packages/ui-components/src/Modal/useSubmitButtonProps.tsx:13
737 737
 	// Reference: packages/ui-components/src/Stepper/buttons/Submit.tsx:7
738
-	__( 'Submit', 'event_espresso' ),
738
+	__('Submit', 'event_espresso'),
739 739
 
740 740
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:20
741
-	__( 'All Dates', 'event_espresso' ),
741
+	__('All Dates', 'event_espresso'),
742 742
 
743 743
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:27
744
-	__( 'dates by month', 'event_espresso' ),
744
+	__('dates by month', 'event_espresso'),
745 745
 
746 746
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:16
747
-	__( 'show expired tickets', 'event_espresso' ),
747
+	__('show expired tickets', 'event_espresso'),
748 748
 
749 749
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:13
750
-	__( 'show trashed dates', 'event_espresso' ),
750
+	__('show trashed dates', 'event_espresso'),
751 751
 
752 752
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:16
753
-	__( 'show trashed tickets', 'event_espresso' ),
753
+	__('show trashed tickets', 'event_espresso'),
754 754
 
755 755
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/Container.tsx:38
756 756
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actions/Actions.tsx:21
757
-	__( 'Default tickets', 'event_espresso' ),
757
+	__('Default tickets', 'event_espresso'),
758 758
 
759 759
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/ModalBody.tsx:63
760 760
 	// Reference: packages/edtr-services/src/constants.ts:26
761
-	__( 'ticket', 'event_espresso' ),
761
+	__('ticket', 'event_espresso'),
762 762
 
763 763
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:26
764 764
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:33
765
-	__( 'Set ticket prices', 'event_espresso' ),
765
+	__('Set ticket prices', 'event_espresso'),
766 766
 
767 767
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:31
768
-	__( 'Skip prices - Save', 'event_espresso' ),
768
+	__('Skip prices - Save', 'event_espresso'),
769 769
 
770 770
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:37
771 771
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:57
772
-	__( 'Ticket details', 'event_espresso' ),
772
+	__('Ticket details', 'event_espresso'),
773 773
 
774 774
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:38
775
-	__( 'Save', 'event_espresso' ),
775
+	__('Save', 'event_espresso'),
776 776
 
777 777
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:22
778 778
 	/* translators: %s ticket id */
779
-	__( 'Edit ticket %s', 'event_espresso' ),
779
+	__('Edit ticket %s', 'event_espresso'),
780 780
 
781 781
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:25
782 782
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:30
783
-	__( 'New Ticket Details', 'event_espresso' ),
783
+	__('New Ticket Details', 'event_espresso'),
784 784
 
785 785
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
786 786
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
787
-	__( 'primary information about the ticket', 'event_espresso' ),
787
+	__('primary information about the ticket', 'event_espresso'),
788 788
 
789 789
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
790 790
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
791
-	__( 'Ticket Details', 'event_espresso' ),
791
+	__('Ticket Details', 'event_espresso'),
792 792
 
793 793
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:12
794 794
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:12
795
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
795
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
796 796
 
797 797
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:14
798 798
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:14
799
-	__( 'Price Calculator', 'event_espresso' ),
799
+	__('Price Calculator', 'event_espresso'),
800 800
 
801 801
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
802 802
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
803
-	__( 'Assign Dates', 'event_espresso' ),
803
+	__('Assign Dates', 'event_espresso'),
804 804
 
805 805
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:39
806
-	__( 'Skip prices - assign dates', 'event_espresso' ),
806
+	__('Skip prices - assign dates', 'event_espresso'),
807 807
 
808 808
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:50
809
-	__( 'Save and assign dates', 'event_espresso' ),
809
+	__('Save and assign dates', 'event_espresso'),
810 810
 
811 811
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:26
812 812
 	/* translators: 1 ticket name, 2 ticket id */
813
-	__( 'Edit ticket "%1$s" - %2$s', 'event_espresso' ),
813
+	__('Edit ticket "%1$s" - %2$s', 'event_espresso'),
814 814
 
815 815
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:110
816
-	__( 'Ticket Sales', 'event_espresso' ),
816
+	__('Ticket Sales', 'event_espresso'),
817 817
 
818 818
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:136
819 819
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:112
820
-	__( 'Quantity For Sale', 'event_espresso' ),
820
+	__('Quantity For Sale', 'event_espresso'),
821 821
 
822 822
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:142
823
-	__( 'The maximum number of this ticket available for sale.', 'event_espresso' ),
823
+	__('The maximum number of this ticket available for sale.', 'event_espresso'),
824 824
 
825 825
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:144
826
-	__( 'Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
826
+	__('Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
827 827
 
828 828
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:150
829 829
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:121
830
-	__( 'Number of Uses', 'event_espresso' ),
830
+	__('Number of Uses', 'event_espresso'),
831 831
 
832 832
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:156
833
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso' ),
833
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso'),
834 834
 
835 835
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:160
836
-	__( 'Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso' ),
836
+	__('Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso'),
837 837
 
838 838
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:168
839 839
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:129
840
-	__( 'Minimum Quantity', 'event_espresso' ),
840
+	__('Minimum Quantity', 'event_espresso'),
841 841
 
842 842
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:173
843
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
843
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
844 844
 
845 845
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:177
846
-	__( 'Leave blank for no minimum.', 'event_espresso' ),
846
+	__('Leave blank for no minimum.', 'event_espresso'),
847 847
 
848 848
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:183
849 849
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:137
850
-	__( 'Maximum Quantity', 'event_espresso' ),
850
+	__('Maximum Quantity', 'event_espresso'),
851 851
 
852 852
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:189
853
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
853
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
854 854
 
855 855
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:193
856
-	__( 'Leave blank for no maximum.', 'event_espresso' ),
856
+	__('Leave blank for no maximum.', 'event_espresso'),
857 857
 
858 858
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:199
859 859
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:146
860
-	__( 'Required Ticket', 'event_espresso' ),
860
+	__('Required Ticket', 'event_espresso'),
861 861
 
862 862
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:201
863
-	__( 'If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso' ),
863
+	__('If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso'),
864 864
 
865 865
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:215
866
-	__( 'Visibility', 'event_espresso' ),
866
+	__('Visibility', 'event_espresso'),
867 867
 
868 868
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:217
869
-	__( 'Where the ticket can be viewed throughout the UI.', 'event_espresso' ),
869
+	__('Where the ticket can be viewed throughout the UI.', 'event_espresso'),
870 870
 
871 871
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:13
872
-	__( 'total registrations.', 'event_espresso' ),
872
+	__('total registrations.', 'event_espresso'),
873 873
 
874 874
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:14
875
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
875
+	__('view ALL registrations for this ticket.', 'event_espresso'),
876 876
 
877 877
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketSoldLink.tsx:13
878
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
878
+	__('view approved registrations for this ticket.', 'event_espresso'),
879 879
 
880 880
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:36
881
-	__( 'Available Tickets', 'event_espresso' ),
881
+	__('Available Tickets', 'event_espresso'),
882 882
 
883 883
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:39
884
-	__( 'loading tickets…', 'event_espresso' ),
884
+	__('loading tickets…', 'event_espresso'),
885 885
 
886 886
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:26
887
-	__( 'Number of related dates', 'event_espresso' ),
887
+	__('Number of related dates', 'event_espresso'),
888 888
 
889 889
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
890
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
890
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
891 891
 
892 892
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:37
893
-	__( 'assign dates', 'event_espresso' ),
893
+	__('assign dates', 'event_espresso'),
894 894
 
895 895
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
896
-	__( 'Permanently delete Ticket?', 'event_espresso' ),
896
+	__('Permanently delete Ticket?', 'event_espresso'),
897 897
 
898 898
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
899
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
899
+	__('Move Ticket to Trash?', 'event_espresso'),
900 900
 
901 901
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:21
902
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
902
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
903 903
 
904 904
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:22
905
-	__( 'Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso' ),
905
+	__('Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso'),
906 906
 
907 907
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
908 908
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Trash.tsx:6
909
-	__( 'trash ticket', 'event_espresso' ),
909
+	__('trash ticket', 'event_espresso'),
910 910
 
911 911
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:25
912
-	__( 'ticket main menu', 'event_espresso' ),
912
+	__('ticket main menu', 'event_espresso'),
913 913
 
914 914
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:38
915 915
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Edit.tsx:15
916
-	__( 'edit ticket', 'event_espresso' ),
916
+	__('edit ticket', 'event_espresso'),
917 917
 
918 918
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:39
919
-	__( 'copy ticket', 'event_espresso' ),
919
+	__('copy ticket', 'event_espresso'),
920 920
 
921 921
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:43
922
-	__( 'edit ticket details', 'event_espresso' ),
922
+	__('edit ticket details', 'event_espresso'),
923 923
 
924 924
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
925
-	__( 'delete tickets', 'event_espresso' ),
925
+	__('delete tickets', 'event_espresso'),
926 926
 
927 927
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
928
-	__( 'trash tickets', 'event_espresso' ),
928
+	__('trash tickets', 'event_espresso'),
929 929
 
930 930
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:51
931
-	__( 'edit ticket prices', 'event_espresso' ),
931
+	__('edit ticket prices', 'event_espresso'),
932 932
 
933 933
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
934
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
934
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
935 935
 
936 936
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
937
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
937
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
938 938
 
939 939
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
940
-	__( 'Delete tickets permanently', 'event_espresso' ),
940
+	__('Delete tickets permanently', 'event_espresso'),
941 941
 
942 942
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
943
-	__( 'Trash tickets', 'event_espresso' ),
943
+	__('Trash tickets', 'event_espresso'),
944 944
 
945 945
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:21
946
-	__( 'Bulk edit ticket details', 'event_espresso' ),
946
+	__('Bulk edit ticket details', 'event_espresso'),
947 947
 
948 948
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
949
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
949
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
950 950
 
951 951
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:19
952
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
952
+	__('Bulk edit ticket prices', 'event_espresso'),
953 953
 
954 954
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:20
955
-	__( 'Edit all prices together', 'event_espresso' ),
955
+	__('Edit all prices together', 'event_espresso'),
956 956
 
957 957
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:21
958
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
958
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
959 959
 
960 960
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:25
961
-	__( 'Edit prices individually', 'event_espresso' ),
961
+	__('Edit prices individually', 'event_espresso'),
962 962
 
963 963
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:26
964
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
964
+	__('Edit prices for each ticket individually', 'event_espresso'),
965 965
 
966 966
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:14
967 967
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:34
968 968
 	// Reference: packages/form/src/ResetButton.tsx:18
969 969
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
970
-	__( 'Reset', 'event_espresso' ),
970
+	__('Reset', 'event_espresso'),
971 971
 
972 972
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
973 973
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:76
974 974
 	// Reference: packages/ui-components/src/Modal/useCancelButtonProps.tsx:10
975
-	__( 'Cancel', 'event_espresso' ),
975
+	__('Cancel', 'event_espresso'),
976 976
 
977 977
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:26
978 978
 	/* translators: %s ticket name */
979
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
979
+	__('Edit prices for Ticket: %s', 'event_espresso'),
980 980
 
981 981
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:30
982
-	__( 'sales start', 'event_espresso' ),
982
+	__('sales start', 'event_espresso'),
983 983
 
984 984
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:33
985
-	__( 'sales began', 'event_espresso' ),
985
+	__('sales began', 'event_espresso'),
986 986
 
987 987
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:35
988
-	__( 'sales ended', 'event_espresso' ),
988
+	__('sales ended', 'event_espresso'),
989 989
 
990 990
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:36
991
-	__( 'sales end', 'event_espresso' ),
991
+	__('sales end', 'event_espresso'),
992 992
 
993 993
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:50
994
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
994
+	__('Edit Ticket Sale Dates', 'event_espresso'),
995 995
 
996 996
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:54
997
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
997
+	__('edit ticket sales start and end dates', 'event_espresso'),
998 998
 
999 999
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:21
1000
-	__( 'quantity', 'event_espresso' ),
1000
+	__('quantity', 'event_espresso'),
1001 1001
 
1002 1002
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:28
1003 1003
 	// Reference: packages/edtr-services/src/apollo/mutations/tickets/useUpdateTicketQtyByCapacity.ts:78
1004
-	__( 'Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso' ),
1004
+	__('Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso'),
1005 1005
 
1006 1006
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:51
1007
-	__( 'edit quantity of tickets available…', 'event_espresso' ),
1007
+	__('edit quantity of tickets available…', 'event_espresso'),
1008 1008
 
1009 1009
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:10
1010
-	__( 'Move Ticket to Trash', 'event_espresso' ),
1010
+	__('Move Ticket to Trash', 'event_espresso'),
1011 1011
 
1012 1012
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:15
1013 1013
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:52
1014
-	__( 'On Sale', 'event_espresso' ),
1014
+	__('On Sale', 'event_espresso'),
1015 1015
 
1016 1016
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:17
1017
-	__( 'Pending', 'event_espresso' ),
1017
+	__('Pending', 'event_espresso'),
1018 1018
 
1019 1019
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:7
1020
-	__( 'Edit Ticket Details', 'event_espresso' ),
1020
+	__('Edit Ticket Details', 'event_espresso'),
1021 1021
 
1022 1022
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:8
1023
-	__( 'Manage Date Assignments', 'event_espresso' ),
1023
+	__('Manage Date Assignments', 'event_espresso'),
1024 1024
 
1025 1025
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:9
1026 1026
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
1027
-	__( 'Ticket Price Calculator', 'event_espresso' ),
1027
+	__('Ticket Price Calculator', 'event_espresso'),
1028 1028
 
1029 1029
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:39
1030
-	__( 'edit ticket total…', 'event_espresso' ),
1030
+	__('edit ticket total…', 'event_espresso'),
1031 1031
 
1032 1032
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:53
1033
-	__( 'set price…', 'event_espresso' ),
1033
+	__('set price…', 'event_espresso'),
1034 1034
 
1035 1035
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:23
1036
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
1036
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
1037 1037
 
1038 1038
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
1039
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
1039
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
1040 1040
 
1041 1041
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
1042
-	__( 'ticket sales start and end dates', 'event_espresso' ),
1042
+	__('ticket sales start and end dates', 'event_espresso'),
1043 1043
 
1044 1044
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
1045
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
1045
+	__('tickets with 90% or more sold', 'event_espresso'),
1046 1046
 
1047 1047
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
1048
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
1048
+	__('tickets with 75% or more sold', 'event_espresso'),
1049 1049
 
1050 1050
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
1051
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
1051
+	__('tickets with 50% or more sold', 'event_espresso'),
1052 1052
 
1053 1053
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:19
1054
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
1054
+	__('tickets with less than 50% sold', 'event_espresso'),
1055 1055
 
1056 1056
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
1057
-	__( 'all tickets for all dates', 'event_espresso' ),
1057
+	__('all tickets for all dates', 'event_espresso'),
1058 1058
 
1059 1059
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
1060
-	__( 'all on sale and sale pending', 'event_espresso' ),
1060
+	__('all on sale and sale pending', 'event_espresso'),
1061 1061
 
1062 1062
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
1063
-	__( 'on sale tickets only', 'event_espresso' ),
1063
+	__('on sale tickets only', 'event_espresso'),
1064 1064
 
1065 1065
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
1066
-	__( 'sale pending tickets only', 'event_espresso' ),
1066
+	__('sale pending tickets only', 'event_espresso'),
1067 1067
 
1068 1068
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
1069
-	__( 'next on sale or sale pending only', 'event_espresso' ),
1069
+	__('next on sale or sale pending only', 'event_espresso'),
1070 1070
 
1071 1071
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
1072
-	__( 'sold out tickets only', 'event_espresso' ),
1072
+	__('sold out tickets only', 'event_espresso'),
1073 1073
 
1074 1074
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
1075
-	__( 'expired tickets only', 'event_espresso' ),
1075
+	__('expired tickets only', 'event_espresso'),
1076 1076
 
1077 1077
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:35
1078
-	__( 'trashed tickets only', 'event_espresso' ),
1078
+	__('trashed tickets only', 'event_espresso'),
1079 1079
 
1080 1080
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:40
1081
-	__( 'all tickets for above dates', 'event_espresso' ),
1081
+	__('all tickets for above dates', 'event_espresso'),
1082 1082
 
1083 1083
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
1084
-	__( 'ticket sale date', 'event_espresso' ),
1084
+	__('ticket sale date', 'event_espresso'),
1085 1085
 
1086 1086
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
1087
-	__( 'ticket name', 'event_espresso' ),
1087
+	__('ticket name', 'event_espresso'),
1088 1088
 
1089 1089
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
1090
-	__( 'ticket ID', 'event_espresso' ),
1090
+	__('ticket ID', 'event_espresso'),
1091 1091
 
1092 1092
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
1093
-	__( 'link', 'event_espresso' ),
1093
+	__('link', 'event_espresso'),
1094 1094
 
1095 1095
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
1096
-	__( 'ticket sales start date only', 'event_espresso' ),
1096
+	__('ticket sales start date only', 'event_espresso'),
1097 1097
 
1098 1098
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
1099
-	__( 'ticket sales end date only', 'event_espresso' ),
1099
+	__('ticket sales end date only', 'event_espresso'),
1100 1100
 
1101 1101
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:18
1102
-	__( 'Add New Ticket', 'event_espresso' ),
1102
+	__('Add New Ticket', 'event_espresso'),
1103 1103
 
1104 1104
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:32
1105
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
1105
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
1106 1106
 
1107 1107
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:34
1108
-	__( 'Single Ticket', 'event_espresso' ),
1108
+	__('Single Ticket', 'event_espresso'),
1109 1109
 
1110 1110
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:39
1111
-	__( 'Tickets', 'event_espresso' ),
1111
+	__('Tickets', 'event_espresso'),
1112 1112
 
1113 1113
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:110
1114
-	__( 'Registrations', 'event_espresso' ),
1114
+	__('Registrations', 'event_espresso'),
1115 1115
 
1116 1116
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:51
1117
-	__( 'Goes on Sale', 'event_espresso' ),
1117
+	__('Goes on Sale', 'event_espresso'),
1118 1118
 
1119 1119
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:65
1120
-	__( 'Sale Ends', 'event_espresso' ),
1120
+	__('Sale Ends', 'event_espresso'),
1121 1121
 
1122 1122
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:66
1123
-	__( 'Ends', 'event_espresso' ),
1123
+	__('Ends', 'event_espresso'),
1124 1124
 
1125 1125
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:78
1126
-	__( 'Price', 'event_espresso' ),
1126
+	__('Price', 'event_espresso'),
1127 1127
 
1128 1128
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:88
1129
-	__( 'Quantity', 'event_espresso' ),
1129
+	__('Quantity', 'event_espresso'),
1130 1130
 
1131 1131
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:105
1132
-	__( 'Select a Venue for the Event', 'event_espresso' ),
1132
+	__('Select a Venue for the Event', 'event_espresso'),
1133 1133
 
1134 1134
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:21
1135
-	__( 'Venue Details', 'event_espresso' ),
1135
+	__('Venue Details', 'event_espresso'),
1136 1136
 
1137 1137
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:38
1138
-	__( 'unlimited space', 'event_espresso' ),
1138
+	__('unlimited space', 'event_espresso'),
1139 1139
 
1140 1140
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:41
1141 1141
 	/* translators: %d venue capacity */
1142
-	__( 'Space for up to %d people', 'event_espresso' ),
1142
+	__('Space for up to %d people', 'event_espresso'),
1143 1143
 
1144 1144
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:60
1145
-	__( 'no image', 'event_espresso' ),
1145
+	__('no image', 'event_espresso'),
1146 1146
 
1147 1147
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:96
1148
-	__( 'Edit this Venue', 'event_espresso' ),
1148
+	__('Edit this Venue', 'event_espresso'),
1149 1149
 
1150 1150
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:29
1151
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
1151
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
1152 1152
 
1153 1153
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:40
1154
-	__( 'Skip', 'event_espresso' ),
1154
+	__('Skip', 'event_espresso'),
1155 1155
 
1156 1156
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:42
1157
-	__( 'Sure I\'ll help', 'event_espresso' ),
1157
+	__('Sure I\'ll help', 'event_espresso'),
1158 1158
 
1159 1159
 	// Reference: packages/adapters/src/Pagination/Pagination.tsx:23
1160
-	__( 'pagination', 'event_espresso' ),
1160
+	__('pagination', 'event_espresso'),
1161 1161
 
1162 1162
 	// Reference: packages/adapters/src/TagSelector/TagSelector.tsx:112
1163
-	__( 'toggle menu', 'event_espresso' ),
1163
+	__('toggle menu', 'event_espresso'),
1164 1164
 
1165 1165
 	// Reference: packages/constants/src/datetime.ts:10
1166
-	__( 'Postponed', 'event_espresso' ),
1166
+	__('Postponed', 'event_espresso'),
1167 1167
 
1168 1168
 	// Reference: packages/constants/src/datetime.ts:11
1169
-	__( 'SoldOut', 'event_espresso' ),
1169
+	__('SoldOut', 'event_espresso'),
1170 1170
 
1171 1171
 	// Reference: packages/constants/src/datetime.ts:7
1172 1172
 	// Reference: packages/predicates/src/registration/statusOptions.ts:11
1173
-	__( 'Cancelled', 'event_espresso' ),
1173
+	__('Cancelled', 'event_espresso'),
1174 1174
 
1175 1175
 	// Reference: packages/constants/src/datetime.ts:9
1176
-	__( 'Inactive', 'event_espresso' ),
1176
+	__('Inactive', 'event_espresso'),
1177 1177
 
1178 1178
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:25
1179
-	__( 'error creating %s', 'event_espresso' ),
1179
+	__('error creating %s', 'event_espresso'),
1180 1180
 
1181 1181
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:26
1182
-	__( 'error deleting %s', 'event_espresso' ),
1182
+	__('error deleting %s', 'event_espresso'),
1183 1183
 
1184 1184
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:27
1185
-	__( 'error updating %s', 'event_espresso' ),
1185
+	__('error updating %s', 'event_espresso'),
1186 1186
 
1187 1187
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:28
1188
-	__( 'creating %s', 'event_espresso' ),
1188
+	__('creating %s', 'event_espresso'),
1189 1189
 
1190 1190
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:29
1191
-	__( 'deleting %s', 'event_espresso' ),
1191
+	__('deleting %s', 'event_espresso'),
1192 1192
 
1193 1193
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:30
1194
-	__( 'updating %s', 'event_espresso' ),
1194
+	__('updating %s', 'event_espresso'),
1195 1195
 
1196 1196
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:31
1197
-	__( 'successfully created %s', 'event_espresso' ),
1197
+	__('successfully created %s', 'event_espresso'),
1198 1198
 
1199 1199
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:32
1200
-	__( 'successfully deleted %s', 'event_espresso' ),
1200
+	__('successfully deleted %s', 'event_espresso'),
1201 1201
 
1202 1202
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:33
1203
-	__( 'successfully updated %s', 'event_espresso' ),
1203
+	__('successfully updated %s', 'event_espresso'),
1204 1204
 
1205 1205
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:13
1206
-	__( 'day in range', 'event_espresso' ),
1206
+	__('day in range', 'event_espresso'),
1207 1207
 
1208 1208
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:17
1209 1209
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:79
1210
-	__( 'end date', 'event_espresso' ),
1210
+	__('end date', 'event_espresso'),
1211 1211
 
1212 1212
 	// Reference: packages/dates/src/components/DateTimePicker.tsx:13
1213 1213
 	// Reference: packages/dates/src/components/TimePicker.tsx:14
1214 1214
 	// Reference: packages/form-builder/src/state/utils.ts:433
1215
-	__( 'time', 'event_espresso' ),
1215
+	__('time', 'event_espresso'),
1216 1216
 
1217 1217
 	// Reference: packages/dates/src/constants.ts:5
1218
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1218
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1219 1219
 
1220 1220
 	// Reference: packages/dates/src/constants.ts:7
1221
-	__( 'Start Date & Time must be set before the End Date & Time', 'event_espresso' ),
1221
+	__('Start Date & Time must be set before the End Date & Time', 'event_espresso'),
1222 1222
 
1223 1223
 	// Reference: packages/dates/src/utils/misc.ts:16
1224
-	__( 'month(s)', 'event_espresso' ),
1224
+	__('month(s)', 'event_espresso'),
1225 1225
 
1226 1226
 	// Reference: packages/dates/src/utils/misc.ts:17
1227
-	__( 'week(s)', 'event_espresso' ),
1227
+	__('week(s)', 'event_espresso'),
1228 1228
 
1229 1229
 	// Reference: packages/dates/src/utils/misc.ts:18
1230
-	__( 'day(s)', 'event_espresso' ),
1230
+	__('day(s)', 'event_espresso'),
1231 1231
 
1232 1232
 	// Reference: packages/dates/src/utils/misc.ts:19
1233
-	__( 'hour(s)', 'event_espresso' ),
1233
+	__('hour(s)', 'event_espresso'),
1234 1234
 
1235 1235
 	// Reference: packages/dates/src/utils/misc.ts:20
1236
-	__( 'minute(s)', 'event_espresso' ),
1236
+	__('minute(s)', 'event_espresso'),
1237 1237
 
1238 1238
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:107
1239
-	__( 'price types initialized', 'event_espresso' ),
1239
+	__('price types initialized', 'event_espresso'),
1240 1240
 
1241 1241
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:117
1242
-	__( 'datetimes initialized', 'event_espresso' ),
1242
+	__('datetimes initialized', 'event_espresso'),
1243 1243
 
1244 1244
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:127
1245
-	__( 'tickets initialized', 'event_espresso' ),
1245
+	__('tickets initialized', 'event_espresso'),
1246 1246
 
1247 1247
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:137
1248
-	__( 'prices initialized', 'event_espresso' ),
1248
+	__('prices initialized', 'event_espresso'),
1249 1249
 
1250 1250
 	// Reference: packages/edtr-services/src/apollo/mutations/useReorderEntities.ts:72
1251
-	__( 'reordering has been applied', 'event_espresso' ),
1251
+	__('reordering has been applied', 'event_espresso'),
1252 1252
 
1253 1253
 	// Reference: packages/edtr-services/src/constants.ts:24
1254
-	__( 'datetime', 'event_espresso' ),
1254
+	__('datetime', 'event_espresso'),
1255 1255
 
1256 1256
 	// Reference: packages/edtr-services/src/constants.ts:27
1257
-	__( 'price', 'event_espresso' ),
1257
+	__('price', 'event_espresso'),
1258 1258
 
1259 1259
 	// Reference: packages/edtr-services/src/constants.ts:28
1260 1260
 	// Reference: packages/tpc/src/inputs/PriceTypeInput.tsx:19
1261
-	__( 'price type', 'event_espresso' ),
1261
+	__('price type', 'event_espresso'),
1262 1262
 
1263 1263
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:38
1264 1264
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:39
1265
-	__( 'End date has been adjusted', 'event_espresso' ),
1265
+	__('End date has been adjusted', 'event_espresso'),
1266 1266
 
1267 1267
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:59
1268
-	__( 'Required', 'event_espresso' ),
1268
+	__('Required', 'event_espresso'),
1269 1269
 
1270 1270
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:64
1271
-	__( 'Start Date is required', 'event_espresso' ),
1271
+	__('Start Date is required', 'event_espresso'),
1272 1272
 
1273 1273
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:68
1274
-	__( 'End Date is required', 'event_espresso' ),
1274
+	__('End Date is required', 'event_espresso'),
1275 1275
 
1276 1276
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:31
1277
-	__( 'no results found', 'event_espresso' ),
1277
+	__('no results found', 'event_espresso'),
1278 1278
 
1279 1279
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:32
1280
-	__( 'try changing filter settings', 'event_espresso' ),
1280
+	__('try changing filter settings', 'event_espresso'),
1281 1281
 
1282 1282
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:38
1283 1283
 	/* translators: %d entity id */
1284
-	__( 'select entity with id %d', 'event_espresso' ),
1284
+	__('select entity with id %d', 'event_espresso'),
1285 1285
 
1286 1286
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:41
1287
-	__( 'select all entities', 'event_espresso' ),
1287
+	__('select all entities', 'event_espresso'),
1288 1288
 
1289 1289
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1290
-	__( 'Note: ', 'event_espresso' ),
1290
+	__('Note: ', 'event_espresso'),
1291 1291
 
1292 1292
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1293
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
1293
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
1294 1294
 
1295 1295
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:27
1296
-	__( 'Bulk edit details', 'event_espresso' ),
1296
+	__('Bulk edit details', 'event_espresso'),
1297 1297
 
1298 1298
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:17
1299
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
1299
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
1300 1300
 
1301 1301
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:18
1302
-	__( 'Bulk update details', 'event_espresso' ),
1302
+	__('Bulk update details', 'event_espresso'),
1303 1303
 
1304 1304
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:27
1305
-	__( 'reorder dates', 'event_espresso' ),
1305
+	__('reorder dates', 'event_espresso'),
1306 1306
 
1307 1307
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:27
1308
-	__( 'reorder tickets', 'event_espresso' ),
1308
+	__('reorder tickets', 'event_espresso'),
1309 1309
 
1310 1310
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:32
1311
-	__( 'delete form element', 'event_espresso' ),
1311
+	__('delete form element', 'event_espresso'),
1312 1312
 
1313 1313
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:49
1314
-	__( 'form element settings', 'event_espresso' ),
1314
+	__('form element settings', 'event_espresso'),
1315 1315
 
1316 1316
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:59
1317
-	__( 'copy form element', 'event_espresso' ),
1317
+	__('copy form element', 'event_espresso'),
1318 1318
 
1319 1319
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:69
1320
-	__( 'click, hold, and drag to reorder form element', 'event_espresso' ),
1320
+	__('click, hold, and drag to reorder form element', 'event_espresso'),
1321 1321
 
1322 1322
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:20
1323
-	__( 'remove option', 'event_espresso' ),
1323
+	__('remove option', 'event_espresso'),
1324 1324
 
1325 1325
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:42
1326
-	__( 'value', 'event_espresso' ),
1326
+	__('value', 'event_espresso'),
1327 1327
 
1328 1328
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:52
1329
-	__( 'label', 'event_espresso' ),
1329
+	__('label', 'event_espresso'),
1330 1330
 
1331 1331
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:63
1332
-	__( 'click, hold, and drag to reorder field option', 'event_espresso' ),
1332
+	__('click, hold, and drag to reorder field option', 'event_espresso'),
1333 1333
 
1334 1334
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:61
1335
-	__( 'Options are the choices you give people to select from.', 'event_espresso' ),
1335
+	__('Options are the choices you give people to select from.', 'event_espresso'),
1336 1336
 
1337 1337
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:63
1338
-	__( 'The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso' ),
1338
+	__('The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso'),
1339 1339
 
1340 1340
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:96
1341
-	__( 'add new option', 'event_espresso' ),
1341
+	__('add new option', 'event_espresso'),
1342 1342
 
1343 1343
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:26
1344 1344
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:25
1345
-	__( 'Styles', 'event_espresso' ),
1345
+	__('Styles', 'event_espresso'),
1346 1346
 
1347 1347
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:30
1348
-	__( 'Validation', 'event_espresso' ),
1348
+	__('Validation', 'event_espresso'),
1349 1349
 
1350 1350
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:18
1351
-	__( 'Change input type', 'event_espresso' ),
1351
+	__('Change input type', 'event_espresso'),
1352 1352
 
1353 1353
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:19
1354
-	__( 'Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso' ),
1354
+	__('Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso'),
1355 1355
 
1356 1356
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:40
1357
-	__( 'type', 'event_espresso' ),
1357
+	__('type', 'event_espresso'),
1358 1358
 
1359 1359
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:26
1360 1360
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:17
1361
-	__( 'public label', 'event_espresso' ),
1361
+	__('public label', 'event_espresso'),
1362 1362
 
1363 1363
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:33
1364 1364
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:22
1365
-	__( 'admin label', 'event_espresso' ),
1365
+	__('admin label', 'event_espresso'),
1366 1366
 
1367 1367
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:40
1368
-	__( 'content', 'event_espresso' ),
1368
+	__('content', 'event_espresso'),
1369 1369
 
1370 1370
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:48
1371
-	__( 'options', 'event_espresso' ),
1371
+	__('options', 'event_espresso'),
1372 1372
 
1373 1373
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:51
1374
-	__( 'placeholder', 'event_espresso' ),
1374
+	__('placeholder', 'event_espresso'),
1375 1375
 
1376 1376
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:57
1377
-	__( 'admin only', 'event_espresso' ),
1377
+	__('admin only', 'event_espresso'),
1378 1378
 
1379 1379
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:62
1380
-	__( 'help text', 'event_espresso' ),
1380
+	__('help text', 'event_espresso'),
1381 1381
 
1382 1382
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:71
1383
-	__( 'maps to', 'event_espresso' ),
1383
+	__('maps to', 'event_espresso'),
1384 1384
 
1385 1385
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:15
1386 1386
 	// Reference: packages/form-builder/src/FormSection/Tabs/Styles.tsx:13
1387
-	__( 'css class', 'event_espresso' ),
1387
+	__('css class', 'event_espresso'),
1388 1388
 
1389 1389
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:20
1390
-	__( 'help text css class', 'event_espresso' ),
1390
+	__('help text css class', 'event_espresso'),
1391 1391
 
1392 1392
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:27
1393
-	__( 'size', 'event_espresso' ),
1393
+	__('size', 'event_espresso'),
1394 1394
 
1395 1395
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:35
1396
-	__( 'step', 'event_espresso' ),
1396
+	__('step', 'event_espresso'),
1397 1397
 
1398 1398
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:41
1399
-	__( 'maxlength', 'event_espresso' ),
1399
+	__('maxlength', 'event_espresso'),
1400 1400
 
1401 1401
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:123
1402
-	__( 'min', 'event_espresso' ),
1402
+	__('min', 'event_espresso'),
1403 1403
 
1404 1404
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:128
1405
-	__( 'max', 'event_espresso' ),
1405
+	__('max', 'event_espresso'),
1406 1406
 
1407 1407
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:28
1408
-	__( 'Germany', 'event_espresso' ),
1408
+	__('Germany', 'event_espresso'),
1409 1409
 
1410 1410
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:32
1411
-	__( 'France', 'event_espresso' ),
1411
+	__('France', 'event_espresso'),
1412 1412
 
1413 1413
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:36
1414
-	__( 'United Kingdom', 'event_espresso' ),
1414
+	__('United Kingdom', 'event_espresso'),
1415 1415
 
1416 1416
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:40
1417
-	__( 'United States', 'event_espresso' ),
1417
+	__('United States', 'event_espresso'),
1418 1418
 
1419 1419
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:44
1420
-	__( 'Custom', 'event_espresso' ),
1420
+	__('Custom', 'event_espresso'),
1421 1421
 
1422 1422
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:54
1423
-	__( 'required', 'event_espresso' ),
1423
+	__('required', 'event_espresso'),
1424 1424
 
1425 1425
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:59
1426
-	__( 'required text', 'event_espresso' ),
1426
+	__('required text', 'event_espresso'),
1427 1427
 
1428 1428
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:66
1429
-	__( 'autocomplete', 'event_espresso' ),
1429
+	__('autocomplete', 'event_espresso'),
1430 1430
 
1431 1431
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:74
1432
-	__( 'custom format', 'event_espresso' ),
1432
+	__('custom format', 'event_espresso'),
1433 1433
 
1434 1434
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:75
1435
-	__( 'format', 'event_espresso' ),
1435
+	__('format', 'event_espresso'),
1436 1436
 
1437 1437
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:83
1438
-	__( 'pattern', 'event_espresso' ),
1438
+	__('pattern', 'event_espresso'),
1439 1439
 
1440 1440
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:110
1441
-	__( 'add new form element', 'event_espresso' ),
1441
+	__('add new form element', 'event_espresso'),
1442 1442
 
1443 1443
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:117
1444 1444
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:52
1445
-	__( 'Add', 'event_espresso' ),
1445
+	__('Add', 'event_espresso'),
1446 1446
 
1447 1447
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:76
1448
-	__( 'Add Form Element', 'event_espresso' ),
1448
+	__('Add Form Element', 'event_espresso'),
1449 1449
 
1450 1450
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:85
1451
-	__( 'form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso' ),
1451
+	__('form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso'),
1452 1452
 
1453 1453
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:92
1454
-	__( 'load existing form section', 'event_espresso' ),
1454
+	__('load existing form section', 'event_espresso'),
1455 1455
 
1456 1456
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:32
1457
-	__( 'delete form section', 'event_espresso' ),
1457
+	__('delete form section', 'event_espresso'),
1458 1458
 
1459 1459
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:47
1460
-	__( 'form section settings', 'event_espresso' ),
1460
+	__('form section settings', 'event_espresso'),
1461 1461
 
1462 1462
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:57
1463
-	__( 'copy form section', 'event_espresso' ),
1463
+	__('copy form section', 'event_espresso'),
1464 1464
 
1465 1465
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:74
1466
-	__( 'click, hold, and drag to reorder form section', 'event_espresso' ),
1466
+	__('click, hold, and drag to reorder form section', 'event_espresso'),
1467 1467
 
1468 1468
 	// Reference: packages/form-builder/src/FormSection/FormSections.tsx:26
1469
-	__( 'Add Form Section', 'event_espresso' ),
1469
+	__('Add Form Section', 'event_espresso'),
1470 1470
 
1471 1471
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:47
1472
-	__( 'save form section for use in other forms', 'event_espresso' ),
1472
+	__('save form section for use in other forms', 'event_espresso'),
1473 1473
 
1474 1474
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:51
1475
-	__( 'save as', 'event_espresso' ),
1475
+	__('save as', 'event_espresso'),
1476 1476
 
1477 1477
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:55
1478
-	__( 'default', 'event_espresso' ),
1478
+	__('default', 'event_espresso'),
1479 1479
 
1480 1480
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:58
1481
-	__( ' a copy of this form section will be automatically added to ALL new events', 'event_espresso' ),
1481
+	__(' a copy of this form section will be automatically added to ALL new events', 'event_espresso'),
1482 1482
 
1483 1483
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:61
1484
-	__( 'shared', 'event_espresso' ),
1484
+	__('shared', 'event_espresso'),
1485 1485
 
1486 1486
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:64
1487
-	__( 'a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso' ),
1487
+	__('a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso'),
1488 1488
 
1489 1489
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:27
1490
-	__( 'show label', 'event_espresso' ),
1490
+	__('show label', 'event_espresso'),
1491 1491
 
1492 1492
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:33
1493
-	__( 'applies to', 'event_espresso' ),
1493
+	__('applies to', 'event_espresso'),
1494 1494
 
1495 1495
 	// Reference: packages/form-builder/src/constants.ts:102
1496 1496
 	// Reference: packages/form-builder/src/state/utils.ts:436
1497
-	__( 'URL', 'event_espresso' ),
1497
+	__('URL', 'event_espresso'),
1498 1498
 
1499 1499
 	// Reference: packages/form-builder/src/constants.ts:104
1500
-	__( 'adds a text input for entering a URL address', 'event_espresso' ),
1500
+	__('adds a text input for entering a URL address', 'event_espresso'),
1501 1501
 
1502 1502
 	// Reference: packages/form-builder/src/constants.ts:107
1503
-	__( 'Date', 'event_espresso' ),
1503
+	__('Date', 'event_espresso'),
1504 1504
 
1505 1505
 	// Reference: packages/form-builder/src/constants.ts:109
1506
-	__( 'adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso' ),
1506
+	__('adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso'),
1507 1507
 
1508 1508
 	// Reference: packages/form-builder/src/constants.ts:112
1509 1509
 	// Reference: packages/form-builder/src/state/utils.ts:369
1510
-	__( 'Local Date', 'event_espresso' ),
1510
+	__('Local Date', 'event_espresso'),
1511 1511
 
1512 1512
 	// Reference: packages/form-builder/src/constants.ts:117
1513
-	__( 'Month', 'event_espresso' ),
1513
+	__('Month', 'event_espresso'),
1514 1514
 
1515 1515
 	// Reference: packages/form-builder/src/constants.ts:119
1516
-	__( 'adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso' ),
1516
+	__('adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso'),
1517 1517
 
1518 1518
 	// Reference: packages/form-builder/src/constants.ts:122
1519
-	__( 'Time', 'event_espresso' ),
1519
+	__('Time', 'event_espresso'),
1520 1520
 
1521 1521
 	// Reference: packages/form-builder/src/constants.ts:124
1522
-	__( 'adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso' ),
1522
+	__('adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso'),
1523 1523
 
1524 1524
 	// Reference: packages/form-builder/src/constants.ts:127
1525
-	__( 'Week', 'event_espresso' ),
1525
+	__('Week', 'event_espresso'),
1526 1526
 
1527 1527
 	// Reference: packages/form-builder/src/constants.ts:129
1528
-	__( 'adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso' ),
1528
+	__('adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso'),
1529 1529
 
1530 1530
 	// Reference: packages/form-builder/src/constants.ts:132
1531
-	__( 'Day Selector', 'event_espresso' ),
1531
+	__('Day Selector', 'event_espresso'),
1532 1532
 
1533 1533
 	// Reference: packages/form-builder/src/constants.ts:134
1534
-	__( 'adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso' ),
1534
+	__('adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso'),
1535 1535
 
1536 1536
 	// Reference: packages/form-builder/src/constants.ts:137
1537
-	__( 'Month Selector', 'event_espresso' ),
1537
+	__('Month Selector', 'event_espresso'),
1538 1538
 
1539 1539
 	// Reference: packages/form-builder/src/constants.ts:139
1540
-	__( 'adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso' ),
1540
+	__('adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso'),
1541 1541
 
1542 1542
 	// Reference: packages/form-builder/src/constants.ts:142
1543
-	__( 'Year Selector', 'event_espresso' ),
1543
+	__('Year Selector', 'event_espresso'),
1544 1544
 
1545 1545
 	// Reference: packages/form-builder/src/constants.ts:144
1546
-	__( 'adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso' ),
1546
+	__('adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso'),
1547 1547
 
1548 1548
 	// Reference: packages/form-builder/src/constants.ts:147
1549
-	__( 'Radio Buttons', 'event_espresso' ),
1549
+	__('Radio Buttons', 'event_espresso'),
1550 1550
 
1551 1551
 	// Reference: packages/form-builder/src/constants.ts:149
1552
-	__( 'adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso' ),
1552
+	__('adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso'),
1553 1553
 
1554 1554
 	// Reference: packages/form-builder/src/constants.ts:152
1555 1555
 	// Reference: packages/form-builder/src/state/utils.ts:375
1556
-	__( 'Decimal Number', 'event_espresso' ),
1556
+	__('Decimal Number', 'event_espresso'),
1557 1557
 
1558 1558
 	// Reference: packages/form-builder/src/constants.ts:154
1559
-	__( 'adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso' ),
1559
+	__('adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso'),
1560 1560
 
1561 1561
 	// Reference: packages/form-builder/src/constants.ts:157
1562 1562
 	// Reference: packages/form-builder/src/state/utils.ts:378
1563
-	__( 'Whole Number', 'event_espresso' ),
1563
+	__('Whole Number', 'event_espresso'),
1564 1564
 
1565 1565
 	// Reference: packages/form-builder/src/constants.ts:159
1566
-	__( 'adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso' ),
1566
+	__('adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso'),
1567 1567
 
1568 1568
 	// Reference: packages/form-builder/src/constants.ts:162
1569
-	__( 'Number Range', 'event_espresso' ),
1569
+	__('Number Range', 'event_espresso'),
1570 1570
 
1571 1571
 	// Reference: packages/form-builder/src/constants.ts:167
1572
-	__( 'Phone Number', 'event_espresso' ),
1572
+	__('Phone Number', 'event_espresso'),
1573 1573
 
1574 1574
 	// Reference: packages/form-builder/src/constants.ts:172
1575
-	__( 'Dropdown', 'event_espresso' ),
1575
+	__('Dropdown', 'event_espresso'),
1576 1576
 
1577 1577
 	// Reference: packages/form-builder/src/constants.ts:174
1578
-	__( 'adds a dropdown selector that accepts a single value', 'event_espresso' ),
1578
+	__('adds a dropdown selector that accepts a single value', 'event_espresso'),
1579 1579
 
1580 1580
 	// Reference: packages/form-builder/src/constants.ts:177
1581
-	__( 'Multi Select', 'event_espresso' ),
1581
+	__('Multi Select', 'event_espresso'),
1582 1582
 
1583 1583
 	// Reference: packages/form-builder/src/constants.ts:179
1584
-	__( 'adds a dropdown selector that accepts multiple values', 'event_espresso' ),
1584
+	__('adds a dropdown selector that accepts multiple values', 'event_espresso'),
1585 1585
 
1586 1586
 	// Reference: packages/form-builder/src/constants.ts:182
1587
-	__( 'Toggle/Switch', 'event_espresso' ),
1587
+	__('Toggle/Switch', 'event_espresso'),
1588 1588
 
1589 1589
 	// Reference: packages/form-builder/src/constants.ts:184
1590
-	__( 'adds a toggle or a switch to accept true or false value', 'event_espresso' ),
1590
+	__('adds a toggle or a switch to accept true or false value', 'event_espresso'),
1591 1591
 
1592 1592
 	// Reference: packages/form-builder/src/constants.ts:187
1593
-	__( 'Multi Checkbox', 'event_espresso' ),
1593
+	__('Multi Checkbox', 'event_espresso'),
1594 1594
 
1595 1595
 	// Reference: packages/form-builder/src/constants.ts:189
1596
-	__( 'adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso' ),
1596
+	__('adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso'),
1597 1597
 
1598 1598
 	// Reference: packages/form-builder/src/constants.ts:192
1599
-	__( 'Country Selector', 'event_espresso' ),
1599
+	__('Country Selector', 'event_espresso'),
1600 1600
 
1601 1601
 	// Reference: packages/form-builder/src/constants.ts:194
1602
-	__( 'adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso' ),
1602
+	__('adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso'),
1603 1603
 
1604 1604
 	// Reference: packages/form-builder/src/constants.ts:197
1605
-	__( 'State Selector', 'event_espresso' ),
1605
+	__('State Selector', 'event_espresso'),
1606 1606
 
1607 1607
 	// Reference: packages/form-builder/src/constants.ts:202
1608
-	__( 'Button', 'event_espresso' ),
1608
+	__('Button', 'event_espresso'),
1609 1609
 
1610 1610
 	// Reference: packages/form-builder/src/constants.ts:204
1611
-	__( 'adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso' ),
1611
+	__('adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso'),
1612 1612
 
1613 1613
 	// Reference: packages/form-builder/src/constants.ts:207
1614
-	__( 'Reset Button', 'event_espresso' ),
1614
+	__('Reset Button', 'event_espresso'),
1615 1615
 
1616 1616
 	// Reference: packages/form-builder/src/constants.ts:209
1617
-	__( 'adds a button that will reset the form back to its original state.', 'event_espresso' ),
1617
+	__('adds a button that will reset the form back to its original state.', 'event_espresso'),
1618 1618
 
1619 1619
 	// Reference: packages/form-builder/src/constants.ts:55
1620
-	__( 'Form Section', 'event_espresso' ),
1620
+	__('Form Section', 'event_espresso'),
1621 1621
 
1622 1622
 	// Reference: packages/form-builder/src/constants.ts:57
1623
-	__( 'Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso' ),
1623
+	__('Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso'),
1624 1624
 
1625 1625
 	// Reference: packages/form-builder/src/constants.ts:62
1626
-	__( 'HTML Block', 'event_espresso' ),
1626
+	__('HTML Block', 'event_espresso'),
1627 1627
 
1628 1628
 	// Reference: packages/form-builder/src/constants.ts:64
1629
-	__( 'allows you to add HTML like headings or text paragraphs to your form', 'event_espresso' ),
1629
+	__('allows you to add HTML like headings or text paragraphs to your form', 'event_espresso'),
1630 1630
 
1631 1631
 	// Reference: packages/form-builder/src/constants.ts:69
1632
-	__( 'adds a text input that only accepts plain text', 'event_espresso' ),
1632
+	__('adds a text input that only accepts plain text', 'event_espresso'),
1633 1633
 
1634 1634
 	// Reference: packages/form-builder/src/constants.ts:72
1635
-	__( 'Plain Text Area', 'event_espresso' ),
1635
+	__('Plain Text Area', 'event_espresso'),
1636 1636
 
1637 1637
 	// Reference: packages/form-builder/src/constants.ts:74
1638
-	__( 'adds a textarea block that only accepts plain text', 'event_espresso' ),
1638
+	__('adds a textarea block that only accepts plain text', 'event_espresso'),
1639 1639
 
1640 1640
 	// Reference: packages/form-builder/src/constants.ts:77
1641
-	__( 'HTML Text Area', 'event_espresso' ),
1641
+	__('HTML Text Area', 'event_espresso'),
1642 1642
 
1643 1643
 	// Reference: packages/form-builder/src/constants.ts:79
1644
-	__( 'adds a textarea block that accepts text including simple HTML markup', 'event_espresso' ),
1644
+	__('adds a textarea block that accepts text including simple HTML markup', 'event_espresso'),
1645 1645
 
1646 1646
 	// Reference: packages/form-builder/src/constants.ts:84
1647
-	__( 'adds a text input that only accepts a valid email address', 'event_espresso' ),
1647
+	__('adds a text input that only accepts a valid email address', 'event_espresso'),
1648 1648
 
1649 1649
 	// Reference: packages/form-builder/src/constants.ts:87
1650
-	__( 'Email Confirmation', 'event_espresso' ),
1650
+	__('Email Confirmation', 'event_espresso'),
1651 1651
 
1652 1652
 	// Reference: packages/form-builder/src/constants.ts:92
1653
-	__( 'Password', 'event_espresso' ),
1653
+	__('Password', 'event_espresso'),
1654 1654
 
1655 1655
 	// Reference: packages/form-builder/src/constants.ts:94
1656
-	__( 'adds a text input that accepts text but masks what the user enters', 'event_espresso' ),
1656
+	__('adds a text input that accepts text but masks what the user enters', 'event_espresso'),
1657 1657
 
1658 1658
 	// Reference: packages/form-builder/src/constants.ts:97
1659
-	__( 'Password Confirmation', 'event_espresso' ),
1659
+	__('Password Confirmation', 'event_espresso'),
1660 1660
 
1661 1661
 	// Reference: packages/form-builder/src/data/useElementMutator.ts:54
1662
-	__( 'element', 'event_espresso' ),
1662
+	__('element', 'event_espresso'),
1663 1663
 
1664 1664
 	// Reference: packages/form-builder/src/data/useSectionMutator.ts:54
1665
-	__( 'section', 'event_espresso' ),
1665
+	__('section', 'event_espresso'),
1666 1666
 
1667 1667
 	// Reference: packages/form-builder/src/state/utils.ts:360
1668
-	__( 'click', 'event_espresso' ),
1668
+	__('click', 'event_espresso'),
1669 1669
 
1670 1670
 	// Reference: packages/form-builder/src/state/utils.ts:363
1671
-	__( 'checkboxes', 'event_espresso' ),
1671
+	__('checkboxes', 'event_espresso'),
1672 1672
 
1673 1673
 	// Reference: packages/form-builder/src/state/utils.ts:366
1674
-	__( 'date', 'event_espresso' ),
1674
+	__('date', 'event_espresso'),
1675 1675
 
1676 1676
 	// Reference: packages/form-builder/src/state/utils.ts:372
1677
-	__( 'day', 'event_espresso' ),
1677
+	__('day', 'event_espresso'),
1678 1678
 
1679 1679
 	// Reference: packages/form-builder/src/state/utils.ts:381
1680
-	__( 'email address', 'event_espresso' ),
1680
+	__('email address', 'event_espresso'),
1681 1681
 
1682 1682
 	// Reference: packages/form-builder/src/state/utils.ts:384
1683
-	__( 'confirm email address', 'event_espresso' ),
1683
+	__('confirm email address', 'event_espresso'),
1684 1684
 
1685 1685
 	// Reference: packages/form-builder/src/state/utils.ts:388
1686
-	__( 'month', 'event_espresso' ),
1686
+	__('month', 'event_espresso'),
1687 1687
 
1688 1688
 	// Reference: packages/form-builder/src/state/utils.ts:391
1689
-	__( 'password', 'event_espresso' ),
1689
+	__('password', 'event_espresso'),
1690 1690
 
1691 1691
 	// Reference: packages/form-builder/src/state/utils.ts:394
1692
-	__( 'confirm password', 'event_espresso' ),
1692
+	__('confirm password', 'event_espresso'),
1693 1693
 
1694 1694
 	// Reference: packages/form-builder/src/state/utils.ts:397
1695
-	__( 'radio buttons', 'event_espresso' ),
1695
+	__('radio buttons', 'event_espresso'),
1696 1696
 
1697 1697
 	// Reference: packages/form-builder/src/state/utils.ts:400
1698
-	__( 'number range', 'event_espresso' ),
1698
+	__('number range', 'event_espresso'),
1699 1699
 
1700 1700
 	// Reference: packages/form-builder/src/state/utils.ts:403
1701
-	__( 'selection dropdown', 'event_espresso' ),
1701
+	__('selection dropdown', 'event_espresso'),
1702 1702
 
1703 1703
 	// Reference: packages/form-builder/src/state/utils.ts:406
1704
-	__( 'country', 'event_espresso' ),
1704
+	__('country', 'event_espresso'),
1705 1705
 
1706 1706
 	// Reference: packages/form-builder/src/state/utils.ts:409
1707
-	__( 'multi-select dropdown', 'event_espresso' ),
1707
+	__('multi-select dropdown', 'event_espresso'),
1708 1708
 
1709 1709
 	// Reference: packages/form-builder/src/state/utils.ts:412
1710
-	__( 'state/province', 'event_espresso' ),
1710
+	__('state/province', 'event_espresso'),
1711 1711
 
1712 1712
 	// Reference: packages/form-builder/src/state/utils.ts:415
1713
-	__( 'on/off switch', 'event_espresso' ),
1713
+	__('on/off switch', 'event_espresso'),
1714 1714
 
1715 1715
 	// Reference: packages/form-builder/src/state/utils.ts:418
1716
-	__( 'reset', 'event_espresso' ),
1716
+	__('reset', 'event_espresso'),
1717 1717
 
1718 1718
 	// Reference: packages/form-builder/src/state/utils.ts:421
1719
-	__( 'phone number', 'event_espresso' ),
1719
+	__('phone number', 'event_espresso'),
1720 1720
 
1721 1721
 	// Reference: packages/form-builder/src/state/utils.ts:424
1722
-	__( 'text', 'event_espresso' ),
1722
+	__('text', 'event_espresso'),
1723 1723
 
1724 1724
 	// Reference: packages/form-builder/src/state/utils.ts:427
1725
-	__( 'simple textarea', 'event_espresso' ),
1725
+	__('simple textarea', 'event_espresso'),
1726 1726
 
1727 1727
 	// Reference: packages/form-builder/src/state/utils.ts:430
1728
-	__( 'html textarea', 'event_espresso' ),
1728
+	__('html textarea', 'event_espresso'),
1729 1729
 
1730 1730
 	// Reference: packages/form-builder/src/state/utils.ts:439
1731
-	__( 'week', 'event_espresso' ),
1731
+	__('week', 'event_espresso'),
1732 1732
 
1733 1733
 	// Reference: packages/form-builder/src/state/utils.ts:442
1734
-	__( 'year', 'event_espresso' ),
1734
+	__('year', 'event_espresso'),
1735 1735
 
1736 1736
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:12
1737
-	__( 'Select Image', 'event_espresso' ),
1737
+	__('Select Image', 'event_espresso'),
1738 1738
 
1739 1739
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:44
1740 1740
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:11
1741 1741
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:12
1742 1742
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityTemplate.tsx:32
1743
-	__( 'Select', 'event_espresso' ),
1743
+	__('Select', 'event_espresso'),
1744 1744
 
1745 1745
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:36
1746 1746
 	/* translators: %d the entry number */
1747
-	__( 'Entry %d', 'event_espresso' ),
1747
+	__('Entry %d', 'event_espresso'),
1748 1748
 
1749 1749
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1750 1750
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1751
-	__( 'sold out', 'event_espresso' ),
1751
+	__('sold out', 'event_espresso'),
1752 1752
 
1753 1753
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1754 1754
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1755
-	__( 'expired', 'event_espresso' ),
1755
+	__('expired', 'event_espresso'),
1756 1756
 
1757 1757
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1758
-	__( 'upcoming', 'event_espresso' ),
1758
+	__('upcoming', 'event_espresso'),
1759 1759
 
1760 1760
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1761
-	__( 'active', 'event_espresso' ),
1761
+	__('active', 'event_espresso'),
1762 1762
 
1763 1763
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1764 1764
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1765
-	__( 'trashed', 'event_espresso' ),
1765
+	__('trashed', 'event_espresso'),
1766 1766
 
1767 1767
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1768
-	__( 'cancelled', 'event_espresso' ),
1768
+	__('cancelled', 'event_espresso'),
1769 1769
 
1770 1770
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1771
-	__( 'postponed', 'event_espresso' ),
1771
+	__('postponed', 'event_espresso'),
1772 1772
 
1773 1773
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1774
-	__( 'inactive', 'event_espresso' ),
1774
+	__('inactive', 'event_espresso'),
1775 1775
 
1776 1776
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1777
-	__( 'pending', 'event_espresso' ),
1777
+	__('pending', 'event_espresso'),
1778 1778
 
1779 1779
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1780
-	__( 'on sale', 'event_espresso' ),
1780
+	__('on sale', 'event_espresso'),
1781 1781
 
1782 1782
 	// Reference: packages/predicates/src/registration/statusOptions.ts:16
1783
-	__( 'Declined', 'event_espresso' ),
1783
+	__('Declined', 'event_espresso'),
1784 1784
 
1785 1785
 	// Reference: packages/predicates/src/registration/statusOptions.ts:21
1786
-	__( 'Incomplete', 'event_espresso' ),
1786
+	__('Incomplete', 'event_espresso'),
1787 1787
 
1788 1788
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1789
-	__( 'Not Approved', 'event_espresso' ),
1789
+	__('Not Approved', 'event_espresso'),
1790 1790
 
1791 1791
 	// Reference: packages/predicates/src/registration/statusOptions.ts:31
1792
-	__( 'Pending Payment', 'event_espresso' ),
1792
+	__('Pending Payment', 'event_espresso'),
1793 1793
 
1794 1794
 	// Reference: packages/predicates/src/registration/statusOptions.ts:36
1795
-	__( 'Wait List', 'event_espresso' ),
1795
+	__('Wait List', 'event_espresso'),
1796 1796
 
1797 1797
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1798
-	__( 'Approved', 'event_espresso' ),
1798
+	__('Approved', 'event_espresso'),
1799 1799
 
1800 1800
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:9
1801 1801
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:10
1802
-	__( 'Select media', 'event_espresso' ),
1802
+	__('Select media', 'event_espresso'),
1803 1803
 
1804 1804
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/RichTextEditor.tsx:84
1805
-	__( 'Write something…', 'event_espresso' ),
1805
+	__('Write something…', 'event_espresso'),
1806 1806
 
1807 1807
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/Toolbar.tsx:20
1808
-	__( 'RTE Toolbar', 'event_espresso' ),
1808
+	__('RTE Toolbar', 'event_espresso'),
1809 1809
 
1810 1810
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:11
1811
-	__( 'Normal', 'event_espresso' ),
1811
+	__('Normal', 'event_espresso'),
1812 1812
 
1813 1813
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:12
1814
-	__( 'H1', 'event_espresso' ),
1814
+	__('H1', 'event_espresso'),
1815 1815
 
1816 1816
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:13
1817
-	__( 'H2', 'event_espresso' ),
1817
+	__('H2', 'event_espresso'),
1818 1818
 
1819 1819
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:14
1820
-	__( 'H3', 'event_espresso' ),
1820
+	__('H3', 'event_espresso'),
1821 1821
 
1822 1822
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:15
1823
-	__( 'H4', 'event_espresso' ),
1823
+	__('H4', 'event_espresso'),
1824 1824
 
1825 1825
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:16
1826
-	__( 'H5', 'event_espresso' ),
1826
+	__('H5', 'event_espresso'),
1827 1827
 
1828 1828
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:17
1829
-	__( 'H6', 'event_espresso' ),
1829
+	__('H6', 'event_espresso'),
1830 1830
 
1831 1831
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:18
1832
-	__( 'Block quote', 'event_espresso' ),
1832
+	__('Block quote', 'event_espresso'),
1833 1833
 
1834 1834
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:19
1835
-	__( 'Code', 'event_espresso' ),
1835
+	__('Code', 'event_espresso'),
1836 1836
 
1837 1837
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:36
1838
-	__( 'Set color', 'event_espresso' ),
1838
+	__('Set color', 'event_espresso'),
1839 1839
 
1840 1840
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:45
1841
-	__( 'Text color', 'event_espresso' ),
1841
+	__('Text color', 'event_espresso'),
1842 1842
 
1843 1843
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:47
1844
-	__( 'Background color', 'event_espresso' ),
1844
+	__('Background color', 'event_espresso'),
1845 1845
 
1846 1846
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:39
1847
-	__( 'Add image', 'event_espresso' ),
1847
+	__('Add image', 'event_espresso'),
1848 1848
 
1849 1849
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:51
1850
-	__( 'Image URL', 'event_espresso' ),
1850
+	__('Image URL', 'event_espresso'),
1851 1851
 
1852 1852
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:55
1853
-	__( 'Alt text', 'event_espresso' ),
1853
+	__('Alt text', 'event_espresso'),
1854 1854
 
1855 1855
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:56
1856
-	__( 'Width', 'event_espresso' ),
1856
+	__('Width', 'event_espresso'),
1857 1857
 
1858 1858
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:60
1859
-	__( 'Height', 'event_espresso' ),
1859
+	__('Height', 'event_espresso'),
1860 1860
 
1861 1861
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:54
1862
-	__( 'Edit link', 'event_espresso' ),
1862
+	__('Edit link', 'event_espresso'),
1863 1863
 
1864 1864
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:64
1865
-	__( 'URL title', 'event_espresso' ),
1865
+	__('URL title', 'event_espresso'),
1866 1866
 
1867 1867
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:11
1868
-	__( 'Unordered list', 'event_espresso' ),
1868
+	__('Unordered list', 'event_espresso'),
1869 1869
 
1870 1870
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:12
1871
-	__( 'Ordered list', 'event_espresso' ),
1871
+	__('Ordered list', 'event_espresso'),
1872 1872
 
1873 1873
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:13
1874 1874
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:13
1875
-	__( 'Indent', 'event_espresso' ),
1875
+	__('Indent', 'event_espresso'),
1876 1876
 
1877 1877
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:14
1878 1878
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:14
1879
-	__( 'Outdent', 'event_espresso' ),
1879
+	__('Outdent', 'event_espresso'),
1880 1880
 
1881 1881
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:11
1882
-	__( 'Unordered textalign', 'event_espresso' ),
1882
+	__('Unordered textalign', 'event_espresso'),
1883 1883
 
1884 1884
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:12
1885
-	__( 'Ordered textalign', 'event_espresso' ),
1885
+	__('Ordered textalign', 'event_espresso'),
1886 1886
 
1887 1887
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/render/Image/Toolbar.tsx:32
1888
-	__( 'Image toolbar', 'event_espresso' ),
1888
+	__('Image toolbar', 'event_espresso'),
1889 1889
 
1890 1890
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:62
1891 1891
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:35
1892
-	__( 'Visual editor', 'event_espresso' ),
1892
+	__('Visual editor', 'event_espresso'),
1893 1893
 
1894 1894
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:66
1895 1895
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:39
1896
-	__( 'HTML editor', 'event_espresso' ),
1896
+	__('HTML editor', 'event_espresso'),
1897 1897
 
1898 1898
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:68
1899
-	__( 'Add Media', 'event_espresso' ),
1899
+	__('Add Media', 'event_espresso'),
1900 1900
 
1901 1901
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:14
1902
-	__( 'add new price modifier after this row', 'event_espresso' ),
1902
+	__('add new price modifier after this row', 'event_espresso'),
1903 1903
 
1904 1904
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:14
1905
-	__( 'Delete all prices', 'event_espresso' ),
1905
+	__('Delete all prices', 'event_espresso'),
1906 1906
 
1907 1907
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:27
1908
-	__( 'Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso' ),
1908
+	__('Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso'),
1909 1909
 
1910 1910
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:31
1911
-	__( 'Delete all prices?', 'event_espresso' ),
1911
+	__('Delete all prices?', 'event_espresso'),
1912 1912
 
1913 1913
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1914
-	__( 'delete price modifier', 'event_espresso' ),
1914
+	__('delete price modifier', 'event_espresso'),
1915 1915
 
1916 1916
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:14
1917
-	__( 'Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso' ),
1917
+	__('Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso'),
1918 1918
 
1919 1919
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:17
1920
-	__( 'Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso' ),
1920
+	__('Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso'),
1921 1921
 
1922 1922
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1923
-	__( 'Disable reverse calculate', 'event_espresso' ),
1923
+	__('Disable reverse calculate', 'event_espresso'),
1924 1924
 
1925 1925
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1926
-	__( 'Enable reverse calculate', 'event_espresso' ),
1926
+	__('Enable reverse calculate', 'event_espresso'),
1927 1927
 
1928 1928
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:28
1929
-	__( 'ticket price calculator', 'event_espresso' ),
1929
+	__('ticket price calculator', 'event_espresso'),
1930 1930
 
1931 1931
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:9
1932
-	__( 'Add default taxes', 'event_espresso' ),
1932
+	__('Add default taxes', 'event_espresso'),
1933 1933
 
1934 1934
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:10
1935
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1935
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1936 1936
 
1937 1937
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:14
1938
-	__( 'Remove all taxes?', 'event_espresso' ),
1938
+	__('Remove all taxes?', 'event_espresso'),
1939 1939
 
1940 1940
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:7
1941
-	__( 'Remove taxes', 'event_espresso' ),
1941
+	__('Remove taxes', 'event_espresso'),
1942 1942
 
1943 1943
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:29
1944
-	__( 'Modify default prices.', 'event_espresso' ),
1944
+	__('Modify default prices.', 'event_espresso'),
1945 1945
 
1946 1946
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:29
1947
-	__( 'New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso' ),
1947
+	__('New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso'),
1948 1948
 
1949 1949
 	// Reference: packages/tpc/src/components/LockedTicketsBanner.tsx:12
1950
-	__( 'Editing of prices is disabled', 'event_espresso' ),
1950
+	__('Editing of prices is disabled', 'event_espresso'),
1951 1951
 
1952 1952
 	// Reference: packages/tpc/src/components/NoPricesBanner/AddDefaultPricesButton.tsx:9
1953
-	__( 'Add default prices', 'event_espresso' ),
1953
+	__('Add default prices', 'event_espresso'),
1954 1954
 
1955 1955
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:13
1956
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1956
+	__('This Ticket is Currently Free', 'event_espresso'),
1957 1957
 
1958 1958
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:21
1959 1959
 	/* translators: %s default prices */
1960
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1960
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1961 1961
 
1962 1962
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:22
1963
-	__( 'default prices', 'event_espresso' ),
1963
+	__('default prices', 'event_espresso'),
1964 1964
 
1965 1965
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:29
1966
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1966
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1967 1967
 
1968 1968
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:32
1969
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1969
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1970 1970
 
1971 1971
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:32
1972 1972
 	/* translators: %s ticket name */
1973
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
1973
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
1974 1974
 
1975 1975
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:48
1976
-	__( 'Total', 'event_espresso' ),
1976
+	__('Total', 'event_espresso'),
1977 1977
 
1978 1978
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:57
1979
-	__( 'ticket total', 'event_espresso' ),
1979
+	__('ticket total', 'event_espresso'),
1980 1980
 
1981 1981
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
1982
-	__( 'Order', 'event_espresso' ),
1982
+	__('Order', 'event_espresso'),
1983 1983
 
1984 1984
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
1985
-	__( 'Price Type', 'event_espresso' ),
1985
+	__('Price Type', 'event_espresso'),
1986 1986
 
1987 1987
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
1988
-	__( 'Label', 'event_espresso' ),
1988
+	__('Label', 'event_espresso'),
1989 1989
 
1990 1990
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
1991
-	__( 'Amount', 'event_espresso' ),
1991
+	__('Amount', 'event_espresso'),
1992 1992
 
1993 1993
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:22
1994
-	__( 'Copy ticket', 'event_espresso' ),
1994
+	__('Copy ticket', 'event_espresso'),
1995 1995
 
1996 1996
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:26
1997
-	__( 'Copy and archive this ticket', 'event_espresso' ),
1997
+	__('Copy and archive this ticket', 'event_espresso'),
1998 1998
 
1999 1999
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:29
2000
-	__( 'OK', 'event_espresso' ),
2000
+	__('OK', 'event_espresso'),
2001 2001
 
2002 2002
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:32
2003
-	__( 'amount', 'event_espresso' ),
2003
+	__('amount', 'event_espresso'),
2004 2004
 
2005 2005
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:44
2006
-	__( 'amount…', 'event_espresso' ),
2006
+	__('amount…', 'event_espresso'),
2007 2007
 
2008 2008
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:14
2009
-	__( 'description…', 'event_espresso' ),
2009
+	__('description…', 'event_espresso'),
2010 2010
 
2011 2011
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:9
2012
-	__( 'price description', 'event_espresso' ),
2012
+	__('price description', 'event_espresso'),
2013 2013
 
2014 2014
 	// Reference: packages/tpc/src/inputs/PriceIdInput.tsx:5
2015
-	__( 'price id', 'event_espresso' ),
2015
+	__('price id', 'event_espresso'),
2016 2016
 
2017 2017
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:13
2018
-	__( 'label…', 'event_espresso' ),
2018
+	__('label…', 'event_espresso'),
2019 2019
 
2020 2020
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:8
2021
-	__( 'price name', 'event_espresso' ),
2021
+	__('price name', 'event_espresso'),
2022 2022
 
2023 2023
 	// Reference: packages/tpc/src/inputs/PriceOrderInput.tsx:14
2024
-	__( 'price order', 'event_espresso' ),
2024
+	__('price order', 'event_espresso'),
2025 2025
 
2026 2026
 	// Reference: packages/tpc/src/utils/constants.ts:8
2027
-	__( 'Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso' ),
2027
+	__('Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso'),
2028 2028
 
2029 2029
 	// Reference: packages/ui-components/src/ActiveFilters/ActiveFilters.tsx:8
2030
-	__( 'active filters:', 'event_espresso' ),
2030
+	__('active filters:', 'event_espresso'),
2031 2031
 
2032 2032
 	// Reference: packages/ui-components/src/ActiveFilters/FilterTag/index.tsx:15
2033 2033
 	/* translators: %s filter name */
2034
-	__( 'remove filter - %s', 'event_espresso' ),
2034
+	__('remove filter - %s', 'event_espresso'),
2035 2035
 
2036 2036
 	// Reference: packages/ui-components/src/Address/Address.tsx:72
2037
-	__( 'Address:', 'event_espresso' ),
2037
+	__('Address:', 'event_espresso'),
2038 2038
 
2039 2039
 	// Reference: packages/ui-components/src/Address/Address.tsx:80
2040
-	__( 'City:', 'event_espresso' ),
2040
+	__('City:', 'event_espresso'),
2041 2041
 
2042 2042
 	// Reference: packages/ui-components/src/Address/Address.tsx:86
2043
-	__( 'State:', 'event_espresso' ),
2043
+	__('State:', 'event_espresso'),
2044 2044
 
2045 2045
 	// Reference: packages/ui-components/src/Address/Address.tsx:92
2046
-	__( 'Country:', 'event_espresso' ),
2046
+	__('Country:', 'event_espresso'),
2047 2047
 
2048 2048
 	// Reference: packages/ui-components/src/Address/Address.tsx:98
2049
-	__( 'Zip:', 'event_espresso' ),
2049
+	__('Zip:', 'event_espresso'),
2050 2050
 
2051 2051
 	// Reference: packages/ui-components/src/CalendarDateRange/CalendarDateRange.tsx:37
2052
-	__( 'to', 'event_espresso' ),
2052
+	__('to', 'event_espresso'),
2053 2053
 
2054 2054
 	// Reference: packages/ui-components/src/CalendarPageDate/CalendarPageDate.tsx:54
2055
-	__( 'TO', 'event_espresso' ),
2055
+	__('TO', 'event_espresso'),
2056 2056
 
2057 2057
 	// Reference: packages/ui-components/src/ColorPicker/ColorPicker.tsx:60
2058
-	__( 'Custom color', 'event_espresso' ),
2058
+	__('Custom color', 'event_espresso'),
2059 2059
 
2060 2060
 	// Reference: packages/ui-components/src/ColorPicker/Swatch.tsx:23
2061 2061
 	/* translators: color name */
2062
-	__( 'Color: %s', 'event_espresso' ),
2062
+	__('Color: %s', 'event_espresso'),
2063 2063
 
2064 2064
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:13
2065
-	__( 'Cyan bluish gray', 'event_espresso' ),
2065
+	__('Cyan bluish gray', 'event_espresso'),
2066 2066
 
2067 2067
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:17
2068
-	__( 'White', 'event_espresso' ),
2068
+	__('White', 'event_espresso'),
2069 2069
 
2070 2070
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:21
2071
-	__( 'Pale pink', 'event_espresso' ),
2071
+	__('Pale pink', 'event_espresso'),
2072 2072
 
2073 2073
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:25
2074
-	__( 'Vivid red', 'event_espresso' ),
2074
+	__('Vivid red', 'event_espresso'),
2075 2075
 
2076 2076
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:29
2077
-	__( 'Luminous vivid orange', 'event_espresso' ),
2077
+	__('Luminous vivid orange', 'event_espresso'),
2078 2078
 
2079 2079
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:33
2080
-	__( 'Luminous vivid amber', 'event_espresso' ),
2080
+	__('Luminous vivid amber', 'event_espresso'),
2081 2081
 
2082 2082
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:37
2083
-	__( 'Light green cyan', 'event_espresso' ),
2083
+	__('Light green cyan', 'event_espresso'),
2084 2084
 
2085 2085
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:41
2086
-	__( 'Vivid green cyan', 'event_espresso' ),
2086
+	__('Vivid green cyan', 'event_espresso'),
2087 2087
 
2088 2088
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:45
2089
-	__( 'Pale cyan blue', 'event_espresso' ),
2089
+	__('Pale cyan blue', 'event_espresso'),
2090 2090
 
2091 2091
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:49
2092
-	__( 'Vivid cyan blue', 'event_espresso' ),
2092
+	__('Vivid cyan blue', 'event_espresso'),
2093 2093
 
2094 2094
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:53
2095
-	__( 'Vivid purple', 'event_espresso' ),
2095
+	__('Vivid purple', 'event_espresso'),
2096 2096
 
2097 2097
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:9
2098
-	__( 'Black', 'event_espresso' ),
2098
+	__('Black', 'event_espresso'),
2099 2099
 
2100 2100
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:7
2101 2101
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:22
2102
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
2102
+	__('Are you sure you want to close this?', 'event_espresso'),
2103 2103
 
2104 2104
 	// Reference: packages/ui-components/src/Confirm/ConfirmDelete.tsx:7
2105
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
2105
+	__('Are you sure you want to delete this?', 'event_espresso'),
2106 2106
 
2107 2107
 	// Reference: packages/ui-components/src/Confirm/useConfirmWithButton.tsx:10
2108
-	__( 'Please confirm this action.', 'event_espresso' ),
2108
+	__('Please confirm this action.', 'event_espresso'),
2109 2109
 
2110 2110
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:32
2111
-	__( 'No', 'event_espresso' ),
2111
+	__('No', 'event_espresso'),
2112 2112
 
2113 2113
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:33
2114
-	__( 'Yes', 'event_espresso' ),
2114
+	__('Yes', 'event_espresso'),
2115 2115
 
2116 2116
 	// Reference: packages/ui-components/src/CurrencyDisplay/CurrencyDisplay.tsx:34
2117
-	__( 'free', 'event_espresso' ),
2117
+	__('free', 'event_espresso'),
2118 2118
 
2119 2119
 	// Reference: packages/ui-components/src/DateTimeRangePicker/DateTimeRangePicker.tsx:117
2120 2120
 	// Reference: packages/ui-components/src/Popover/PopoverForm/PopoverForm.tsx:44
2121
-	__( 'save', 'event_espresso' ),
2121
+	__('save', 'event_espresso'),
2122 2122
 
2123 2123
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2124
-	__( 'Hide Debug Info', 'event_espresso' ),
2124
+	__('Hide Debug Info', 'event_espresso'),
2125 2125
 
2126 2126
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2127
-	__( 'Show Debug Info', 'event_espresso' ),
2127
+	__('Show Debug Info', 'event_espresso'),
2128 2128
 
2129 2129
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:49
2130
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
2130
+	__('Edit Start and End Dates and Times', 'event_espresso'),
2131 2131
 
2132 2132
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Copy.tsx:8
2133
-	__( 'copy', 'event_espresso' ),
2133
+	__('copy', 'event_espresso'),
2134 2134
 
2135 2135
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Edit.tsx:8
2136
-	__( 'edit', 'event_espresso' ),
2136
+	__('edit', 'event_espresso'),
2137 2137
 
2138 2138
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Trash.tsx:8
2139
-	__( 'trash', 'event_espresso' ),
2139
+	__('trash', 'event_espresso'),
2140 2140
 
2141 2141
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Untrash.tsx:8
2142
-	__( 'untrash', 'event_espresso' ),
2142
+	__('untrash', 'event_espresso'),
2143 2143
 
2144 2144
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:22
2145
-	__( 'card view', 'event_espresso' ),
2145
+	__('card view', 'event_espresso'),
2146 2146
 
2147 2147
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:21
2148
-	__( 'table view', 'event_espresso' ),
2148
+	__('table view', 'event_espresso'),
2149 2149
 
2150 2150
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2151
-	__( 'hide bulk actions', 'event_espresso' ),
2151
+	__('hide bulk actions', 'event_espresso'),
2152 2152
 
2153 2153
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2154
-	__( 'show bulk actions', 'event_espresso' ),
2154
+	__('show bulk actions', 'event_espresso'),
2155 2155
 
2156 2156
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
2157
-	__( 'hide filters', 'event_espresso' ),
2157
+	__('hide filters', 'event_espresso'),
2158 2158
 
2159 2159
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
2160
-	__( 'show filters', 'event_espresso' ),
2160
+	__('show filters', 'event_espresso'),
2161 2161
 
2162 2162
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
2163
-	__( 'hide legend', 'event_espresso' ),
2163
+	__('hide legend', 'event_espresso'),
2164 2164
 
2165 2165
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
2166
-	__( 'show legend', 'event_espresso' ),
2166
+	__('show legend', 'event_espresso'),
2167 2167
 
2168 2168
 	// Reference: packages/ui-components/src/LoadingNotice/LoadingNotice.tsx:11
2169
-	__( 'loading…', 'event_espresso' ),
2169
+	__('loading…', 'event_espresso'),
2170 2170
 
2171 2171
 	// Reference: packages/ui-components/src/Modal/Modal.tsx:58
2172
-	__( 'close modal', 'event_espresso' ),
2172
+	__('close modal', 'event_espresso'),
2173 2173
 
2174 2174
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:10
2175
-	__( 'jump to previous', 'event_espresso' ),
2175
+	__('jump to previous', 'event_espresso'),
2176 2176
 
2177 2177
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:11
2178
-	__( 'jump to next', 'event_espresso' ),
2178
+	__('jump to next', 'event_espresso'),
2179 2179
 
2180 2180
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:12
2181
-	__( 'page', 'event_espresso' ),
2181
+	__('page', 'event_espresso'),
2182 2182
 
2183 2183
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:8
2184
-	__( 'previous', 'event_espresso' ),
2184
+	__('previous', 'event_espresso'),
2185 2185
 
2186 2186
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:9
2187
-	__( 'next', 'event_espresso' ),
2187
+	__('next', 'event_espresso'),
2188 2188
 
2189 2189
 	// Reference: packages/ui-components/src/Pagination/PerPage.tsx:37
2190
-	__( 'items per page', 'event_espresso' ),
2190
+	__('items per page', 'event_espresso'),
2191 2191
 
2192 2192
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
2193 2193
 	/* translators: %s is per page value */
2194
-	__( '%s / page', 'event_espresso' ),
2194
+	__('%s / page', 'event_espresso'),
2195 2195
 
2196 2196
 	// Reference: packages/ui-components/src/Pagination/constants.ts:13
2197
-	__( 'Next Page', 'event_espresso' ),
2197
+	__('Next Page', 'event_espresso'),
2198 2198
 
2199 2199
 	// Reference: packages/ui-components/src/Pagination/constants.ts:14
2200
-	__( 'Previous Page', 'event_espresso' ),
2200
+	__('Previous Page', 'event_espresso'),
2201 2201
 
2202 2202
 	// Reference: packages/ui-components/src/PercentSign/index.tsx:10
2203
-	__( '%', 'event_espresso' ),
2203
+	__('%', 'event_espresso'),
2204 2204
 
2205 2205
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:31
2206 2206
 	/* translators: entity type to select */
2207
-	__( 'Select an existing %s to use as a template.', 'event_espresso' ),
2207
+	__('Select an existing %s to use as a template.', 'event_espresso'),
2208 2208
 
2209 2209
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:38
2210
-	__( 'or', 'event_espresso' ),
2210
+	__('or', 'event_espresso'),
2211 2211
 
2212 2212
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:43
2213 2213
 	/* translators: entity type to add */
2214
-	__( 'Add a new %s and insert details manually', 'event_espresso' ),
2214
+	__('Add a new %s and insert details manually', 'event_espresso'),
2215 2215
 
2216 2216
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:48
2217
-	__( 'Add New', 'event_espresso' ),
2217
+	__('Add New', 'event_espresso'),
2218 2218
 
2219 2219
 	// Reference: packages/ui-components/src/Stepper/buttons/Next.tsx:8
2220
-	__( 'Next', 'event_espresso' ),
2220
+	__('Next', 'event_espresso'),
2221 2221
 
2222 2222
 	// Reference: packages/ui-components/src/Stepper/buttons/Previous.tsx:8
2223
-	__( 'Previous', 'event_espresso' ),
2223
+	__('Previous', 'event_espresso'),
2224 2224
 
2225 2225
 	// Reference: packages/ui-components/src/Steps/Steps.tsx:31
2226
-	__( 'Steps', 'event_espresso' ),
2226
+	__('Steps', 'event_espresso'),
2227 2227
 
2228 2228
 	// Reference: packages/ui-components/src/TabbableText/index.tsx:21
2229
-	__( 'click to edit…', 'event_espresso' ),
2229
+	__('click to edit…', 'event_espresso'),
2230 2230
 
2231 2231
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:14
2232
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
2232
+	__('The Website\'s Time Zone', 'event_espresso'),
2233 2233
 
2234 2234
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:19
2235
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
2235
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
2236 2236
 
2237 2237
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:9
2238
-	__( 'Your Local Time Zone', 'event_espresso' ),
2238
+	__('Your Local Time Zone', 'event_espresso'),
2239 2239
 
2240 2240
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:27
2241
-	__( 'click for timezone information', 'event_espresso' ),
2241
+	__('click for timezone information', 'event_espresso'),
2242 2242
 
2243 2243
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:32
2244
-	__( 'This Date Converted To:', 'event_espresso' ),
2244
+	__('This Date Converted To:', 'event_espresso'),
2245 2245
 
2246 2246
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:120
2247
-	__( 'Add New Venue', 'event_espresso' ),
2247
+	__('Add New Venue', 'event_espresso'),
2248 2248
 
2249 2249
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:36
2250
-	__( '~ no venue ~', 'event_espresso' ),
2250
+	__('~ no venue ~', 'event_espresso'),
2251 2251
 
2252 2252
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:43
2253
-	__( 'assign venue…', 'event_espresso' ),
2253
+	__('assign venue…', 'event_espresso'),
2254 2254
 
2255 2255
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:44
2256
-	__( 'click to select a venue…', 'event_espresso' ),
2256
+	__('click to select a venue…', 'event_espresso'),
2257 2257
 
2258 2258
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:51
2259
-	__( 'select all', 'event_espresso' ),
2259
+	__('select all', 'event_espresso'),
2260 2260
 
2261 2261
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:54
2262
-	__( 'apply', 'event_espresso' )
2262
+	__('apply', 'event_espresso')
2263 2263
 );
2264 2264
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.
core/services/graphql/fields/GraphQLField.php 1 patch
Indentation   +258 added lines, -258 removed lines patch added patch discarded remove patch
@@ -20,262 +20,262 @@
 block discarded – undo
20 20
 class GraphQLField implements GraphQLFieldInterface
21 21
 {
22 22
 
23
-    /**
24
-     * @var string $name
25
-     */
26
-    protected $name;
27
-
28
-    /**
29
-     * @var string|string[] $type
30
-     */
31
-    protected $type;
32
-
33
-    /**
34
-     * @var string|null $key
35
-     */
36
-    protected $key;
37
-
38
-    /**
39
-     * @var string $description
40
-     */
41
-    protected $description;
42
-
43
-    /**
44
-     * @var callable $formatter
45
-     */
46
-    protected $formatter;
47
-
48
-    /**
49
-     * @var callable $resolve
50
-     */
51
-    protected $resolver;
52
-
53
-    /**
54
-     * @var array $caps
55
-     */
56
-    protected $caps;
57
-
58
-    /**
59
-     * @var array $args
60
-     */
61
-    protected $args;
62
-
63
-    /**
64
-     * @var bool $use_for_input
65
-     */
66
-    protected $use_for_input = true;
67
-
68
-    /**
69
-     * @var bool $use_for_output
70
-     */
71
-    protected $use_for_output = true;
72
-
73
-
74
-    /**
75
-     * @param string          $name
76
-     * @param string|string[] $type
77
-     * @param string|null     $key
78
-     * @param string          $description
79
-     * @param callable|null   $formatter
80
-     * @param callable|null   $resolver
81
-     * @param array           $args
82
-     * @param array           $caps
83
-     * @param array           $args
84
-     */
85
-    public function __construct(
86
-        $name,
87
-        $type,
88
-        $key = null,
89
-        $description = '',
90
-        callable $formatter = null,
91
-        callable $resolver = null,
92
-        array $caps = [],
93
-        array $args = []
94
-    ) {
95
-        $this->name = $name;
96
-        $this->type = $type;
97
-        $this->key = $key;
98
-        $this->description = $description;
99
-        $this->formatter = $formatter;
100
-        $this->resolver = $resolver;
101
-        $this->caps = $caps;
102
-        $this->args = $args;
103
-    }
104
-
105
-
106
-    /**
107
-     * @return array
108
-     */
109
-    public function caps()
110
-    {
111
-        return $this->caps;
112
-    }
113
-
114
-
115
-    /**
116
-     * @return string
117
-     */
118
-    public function description()
119
-    {
120
-        return $this->description;
121
-    }
122
-
123
-
124
-    /**
125
-     * @return string
126
-     */
127
-    public function key()
128
-    {
129
-        return $this->key;
130
-    }
131
-
132
-
133
-    /**
134
-     * @return string
135
-     */
136
-    public function name()
137
-    {
138
-        return $this->name;
139
-    }
140
-
141
-
142
-    /**
143
-     * @return string|string[]
144
-     */
145
-    public function type()
146
-    {
147
-        return $this->type;
148
-    }
149
-
150
-
151
-    /**
152
-     * Convert the field to array to be
153
-     * able to pass as config to WP GraphQL
154
-     *
155
-     * @return array
156
-     */
157
-    public function toArray()
158
-    {
159
-        return get_object_vars($this);
160
-    }
161
-
162
-
163
-    /**
164
-     * Sets the value for use_for_input.
165
-     *
166
-     * @param bool $use_for_input
167
-     */
168
-    protected function setUseForInput($use_for_input)
169
-    {
170
-        $this->use_for_input = filter_var($use_for_input, FILTER_VALIDATE_BOOLEAN);
171
-    }
172
-
173
-
174
-    /**
175
-     * Whether the field should be used for
176
-     * mutation inputs.
177
-     *
178
-     * @return bool
179
-     */
180
-    public function useForInput()
181
-    {
182
-        return (bool) $this->use_for_input;
183
-    }
184
-
185
-
186
-    /**
187
-     * Whether the field should be used for
188
-     * query outputs.
189
-     *
190
-     * @return bool
191
-     */
192
-    public function useForOutput()
193
-    {
194
-        return (bool) $this->use_for_output;
195
-    }
196
-
197
-
198
-    /**
199
-     * Sets the value for use_for_output
200
-     *
201
-     * @param bool $use_for_output
202
-     */
203
-    protected function setUseForOutput($use_for_output)
204
-    {
205
-        $this->use_for_output = filter_var($use_for_output, FILTER_VALIDATE_BOOLEAN);
206
-    }
207
-
208
-
209
-    /**
210
-     * Whether the field should resolve
211
-     * based on the user caps etc.
212
-     *
213
-     * @return boolean
214
-     */
215
-    public function shouldResolve()
216
-    {
217
-        foreach ($this->caps as $cap) {
218
-            if (! current_user_can($cap)) {
219
-                return false;
220
-            }
221
-        }
222
-        return true;
223
-    }
224
-
225
-
226
-    /**
227
-     * Whether the field has an explicit resolver set.
228
-     *
229
-     * @return boolean
230
-     */
231
-    public function hasInternalResolver()
232
-    {
233
-        return is_callable($this->resolver);
234
-    }
235
-
236
-
237
-    /**
238
-     * Whether the field has an explicit resolver set.
239
-     *
240
-     * @param mixed       $source  The source that's passed down the GraphQL queries
241
-     * @param array       $args    The inputArgs on the field
242
-     * @param AppContext  $context The AppContext passed down the GraphQL tree
243
-     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
244
-     * @return mixed
245
-     * @throws LogicException
246
-     */
247
-    public function resolve($source, array $args, AppContext $context, ResolveInfo $info)
248
-    {
249
-        if (! $this->hasInternalResolver()) {
250
-            throw new LogicException('GraphQLField has no internal resolver.');
251
-        }
252
-        // dynamic methods using $this don't play nice
253
-        // so capture resolver to a single var first
254
-        $resolver = $this->resolver;
255
-        return $resolver($source, $args, $context, $info);
256
-    }
257
-
258
-
259
-    /**
260
-     * Checks if the format callback is set.
261
-     * If yes, then uses it to format the value.
262
-     *
263
-     * @param mixed         $value
264
-     * @param EE_Base_Class $source
265
-     * @return mixed The formatted value.
266
-     * @throws InvalidDataTypeException
267
-     * @throws InvalidInterfaceException
268
-     * @throws InvalidArgumentException
269
-     * @throws ReflectionException
270
-     */
271
-    public function mayBeFormatValue($value, EE_Base_Class $source)
272
-    {
273
-        if (is_callable($this->formatter)) {
274
-            // dynamic methods using $this don't play nice
275
-            // so capture formatter to a single var first
276
-            $formatter = $this->formatter;
277
-            return $formatter($value, $source);
278
-        }
279
-        return $value;
280
-    }
23
+	/**
24
+	 * @var string $name
25
+	 */
26
+	protected $name;
27
+
28
+	/**
29
+	 * @var string|string[] $type
30
+	 */
31
+	protected $type;
32
+
33
+	/**
34
+	 * @var string|null $key
35
+	 */
36
+	protected $key;
37
+
38
+	/**
39
+	 * @var string $description
40
+	 */
41
+	protected $description;
42
+
43
+	/**
44
+	 * @var callable $formatter
45
+	 */
46
+	protected $formatter;
47
+
48
+	/**
49
+	 * @var callable $resolve
50
+	 */
51
+	protected $resolver;
52
+
53
+	/**
54
+	 * @var array $caps
55
+	 */
56
+	protected $caps;
57
+
58
+	/**
59
+	 * @var array $args
60
+	 */
61
+	protected $args;
62
+
63
+	/**
64
+	 * @var bool $use_for_input
65
+	 */
66
+	protected $use_for_input = true;
67
+
68
+	/**
69
+	 * @var bool $use_for_output
70
+	 */
71
+	protected $use_for_output = true;
72
+
73
+
74
+	/**
75
+	 * @param string          $name
76
+	 * @param string|string[] $type
77
+	 * @param string|null     $key
78
+	 * @param string          $description
79
+	 * @param callable|null   $formatter
80
+	 * @param callable|null   $resolver
81
+	 * @param array           $args
82
+	 * @param array           $caps
83
+	 * @param array           $args
84
+	 */
85
+	public function __construct(
86
+		$name,
87
+		$type,
88
+		$key = null,
89
+		$description = '',
90
+		callable $formatter = null,
91
+		callable $resolver = null,
92
+		array $caps = [],
93
+		array $args = []
94
+	) {
95
+		$this->name = $name;
96
+		$this->type = $type;
97
+		$this->key = $key;
98
+		$this->description = $description;
99
+		$this->formatter = $formatter;
100
+		$this->resolver = $resolver;
101
+		$this->caps = $caps;
102
+		$this->args = $args;
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return array
108
+	 */
109
+	public function caps()
110
+	{
111
+		return $this->caps;
112
+	}
113
+
114
+
115
+	/**
116
+	 * @return string
117
+	 */
118
+	public function description()
119
+	{
120
+		return $this->description;
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return string
126
+	 */
127
+	public function key()
128
+	{
129
+		return $this->key;
130
+	}
131
+
132
+
133
+	/**
134
+	 * @return string
135
+	 */
136
+	public function name()
137
+	{
138
+		return $this->name;
139
+	}
140
+
141
+
142
+	/**
143
+	 * @return string|string[]
144
+	 */
145
+	public function type()
146
+	{
147
+		return $this->type;
148
+	}
149
+
150
+
151
+	/**
152
+	 * Convert the field to array to be
153
+	 * able to pass as config to WP GraphQL
154
+	 *
155
+	 * @return array
156
+	 */
157
+	public function toArray()
158
+	{
159
+		return get_object_vars($this);
160
+	}
161
+
162
+
163
+	/**
164
+	 * Sets the value for use_for_input.
165
+	 *
166
+	 * @param bool $use_for_input
167
+	 */
168
+	protected function setUseForInput($use_for_input)
169
+	{
170
+		$this->use_for_input = filter_var($use_for_input, FILTER_VALIDATE_BOOLEAN);
171
+	}
172
+
173
+
174
+	/**
175
+	 * Whether the field should be used for
176
+	 * mutation inputs.
177
+	 *
178
+	 * @return bool
179
+	 */
180
+	public function useForInput()
181
+	{
182
+		return (bool) $this->use_for_input;
183
+	}
184
+
185
+
186
+	/**
187
+	 * Whether the field should be used for
188
+	 * query outputs.
189
+	 *
190
+	 * @return bool
191
+	 */
192
+	public function useForOutput()
193
+	{
194
+		return (bool) $this->use_for_output;
195
+	}
196
+
197
+
198
+	/**
199
+	 * Sets the value for use_for_output
200
+	 *
201
+	 * @param bool $use_for_output
202
+	 */
203
+	protected function setUseForOutput($use_for_output)
204
+	{
205
+		$this->use_for_output = filter_var($use_for_output, FILTER_VALIDATE_BOOLEAN);
206
+	}
207
+
208
+
209
+	/**
210
+	 * Whether the field should resolve
211
+	 * based on the user caps etc.
212
+	 *
213
+	 * @return boolean
214
+	 */
215
+	public function shouldResolve()
216
+	{
217
+		foreach ($this->caps as $cap) {
218
+			if (! current_user_can($cap)) {
219
+				return false;
220
+			}
221
+		}
222
+		return true;
223
+	}
224
+
225
+
226
+	/**
227
+	 * Whether the field has an explicit resolver set.
228
+	 *
229
+	 * @return boolean
230
+	 */
231
+	public function hasInternalResolver()
232
+	{
233
+		return is_callable($this->resolver);
234
+	}
235
+
236
+
237
+	/**
238
+	 * Whether the field has an explicit resolver set.
239
+	 *
240
+	 * @param mixed       $source  The source that's passed down the GraphQL queries
241
+	 * @param array       $args    The inputArgs on the field
242
+	 * @param AppContext  $context The AppContext passed down the GraphQL tree
243
+	 * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
244
+	 * @return mixed
245
+	 * @throws LogicException
246
+	 */
247
+	public function resolve($source, array $args, AppContext $context, ResolveInfo $info)
248
+	{
249
+		if (! $this->hasInternalResolver()) {
250
+			throw new LogicException('GraphQLField has no internal resolver.');
251
+		}
252
+		// dynamic methods using $this don't play nice
253
+		// so capture resolver to a single var first
254
+		$resolver = $this->resolver;
255
+		return $resolver($source, $args, $context, $info);
256
+	}
257
+
258
+
259
+	/**
260
+	 * Checks if the format callback is set.
261
+	 * If yes, then uses it to format the value.
262
+	 *
263
+	 * @param mixed         $value
264
+	 * @param EE_Base_Class $source
265
+	 * @return mixed The formatted value.
266
+	 * @throws InvalidDataTypeException
267
+	 * @throws InvalidInterfaceException
268
+	 * @throws InvalidArgumentException
269
+	 * @throws ReflectionException
270
+	 */
271
+	public function mayBeFormatValue($value, EE_Base_Class $source)
272
+	{
273
+		if (is_callable($this->formatter)) {
274
+			// dynamic methods using $this don't play nice
275
+			// so capture formatter to a single var first
276
+			$formatter = $this->formatter;
277
+			return $formatter($value, $source);
278
+		}
279
+		return $value;
280
+	}
281 281
 }
Please login to merge, or discard this patch.
core/services/graphql/fields/GraphQLOutputField.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -11,37 +11,37 @@
 block discarded – undo
11 11
 class GraphQLOutputField extends GraphQLField
12 12
 {
13 13
 
14
-    /**
15
-     * @param string          $name
16
-     * @param string|string[] $type
17
-     * @param string|null     $key
18
-     * @param string          $description
19
-     * @param callable|null   $formatter
20
-     * @param callable|null   $resolver
21
-     * @param array           $caps
22
-     * @param array           $args
23
-     */
24
-    public function __construct(
25
-        $name,
26
-        $type,
27
-        $key = null,
28
-        $description = '',
29
-        callable $formatter = null,
30
-        callable $resolver = null,
31
-        array $caps = [],
32
-        array $args = []
33
-    ) {
34
-        parent::__construct(
35
-            $name,
36
-            $type,
37
-            $key,
38
-            $description,
39
-            $formatter,
40
-            $resolver,
41
-            $caps,
42
-            $args
43
-        );
14
+	/**
15
+	 * @param string          $name
16
+	 * @param string|string[] $type
17
+	 * @param string|null     $key
18
+	 * @param string          $description
19
+	 * @param callable|null   $formatter
20
+	 * @param callable|null   $resolver
21
+	 * @param array           $caps
22
+	 * @param array           $args
23
+	 */
24
+	public function __construct(
25
+		$name,
26
+		$type,
27
+		$key = null,
28
+		$description = '',
29
+		callable $formatter = null,
30
+		callable $resolver = null,
31
+		array $caps = [],
32
+		array $args = []
33
+	) {
34
+		parent::__construct(
35
+			$name,
36
+			$type,
37
+			$key,
38
+			$description,
39
+			$formatter,
40
+			$resolver,
41
+			$caps,
42
+			$args
43
+		);
44 44
 
45
-        $this->setUseForInput(false);
46
-    }
45
+		$this->setUseForInput(false);
46
+	}
47 47
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Base_Class.class.php 2 patches
Indentation   +3368 added lines, -3368 removed lines patch added patch discarded remove patch
@@ -13,3384 +13,3384 @@
 block discarded – undo
13 13
 abstract class EE_Base_Class
14 14
 {
15 15
 
16
-    /**
17
-     * This is an array of the original properties and values provided during construction
18
-     * of this model object. (keys are model field names, values are their values).
19
-     * This list is important to remember so that when we are merging data from the db, we know
20
-     * which values to override and which to not override.
21
-     *
22
-     * @var array
23
-     */
24
-    protected $_props_n_values_provided_in_constructor;
25
-
26
-    /**
27
-     * Timezone
28
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
29
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
30
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
31
-     * access to it.
32
-     *
33
-     * @var string
34
-     */
35
-    protected $_timezone;
36
-
37
-    /**
38
-     * date format
39
-     * pattern or format for displaying dates
40
-     *
41
-     * @var string $_dt_frmt
42
-     */
43
-    protected $_dt_frmt;
44
-
45
-    /**
46
-     * time format
47
-     * pattern or format for displaying time
48
-     *
49
-     * @var string $_tm_frmt
50
-     */
51
-    protected $_tm_frmt;
52
-
53
-    /**
54
-     * This property is for holding a cached array of object properties indexed by property name as the key.
55
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
56
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
57
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
58
-     *
59
-     * @var array
60
-     */
61
-    protected $_cached_properties = array();
62
-
63
-    /**
64
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
65
-     * single
66
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
67
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
68
-     * all others have an array)
69
-     *
70
-     * @var array
71
-     */
72
-    protected $_model_relations = array();
73
-
74
-    /**
75
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
76
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
77
-     *
78
-     * @var array
79
-     */
80
-    protected $_fields = array();
81
-
82
-    /**
83
-     * @var boolean indicating whether or not this model object is intended to ever be saved
84
-     * For example, we might create model objects intended to only be used for the duration
85
-     * of this request and to be thrown away, and if they were accidentally saved
86
-     * it would be a bug.
87
-     */
88
-    protected $_allow_persist = true;
89
-
90
-    /**
91
-     * @var boolean indicating whether or not this model object's properties have changed since construction
92
-     */
93
-    protected $_has_changes = false;
94
-
95
-    /**
96
-     * @var EEM_Base
97
-     */
98
-    protected $_model;
99
-
100
-    /**
101
-     * This is a cache of results from custom selections done on a query that constructs this entity. The only purpose
102
-     * for these values is for retrieval of the results, they are not further queryable and they are not persisted to
103
-     * the db.  They also do not automatically update if there are any changes to the data that produced their results.
104
-     * The format is a simple array of field_alias => field_value.  So for instance if a custom select was something
105
-     * like,  "Select COUNT(Registration.REG_ID) as Registration_Count ...", then the resulting value will be in this
106
-     * array as:
107
-     * array(
108
-     *  'Registration_Count' => 24
109
-     * );
110
-     * Note: if the custom select configuration for the query included a data type, the value will be in the data type
111
-     * provided for the query (@see EventEspresso\core\domain\values\model\CustomSelects::__construct phpdocs for more
112
-     * info)
113
-     *
114
-     * @var array
115
-     */
116
-    protected $custom_selection_results = array();
117
-
118
-
119
-    /**
120
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
121
-     * play nice
122
-     *
123
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
124
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
125
-     *                                                         TXN_amount, QST_name, etc) and values are their values
126
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
127
-     *                                                         corresponding db model or not.
128
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
129
-     *                                                         be in when instantiating a EE_Base_Class object.
130
-     * @param array   $date_formats                            An array of date formats to set on construct where first
131
-     *                                                         value is the date_format and second value is the time
132
-     *                                                         format.
133
-     * @throws InvalidArgumentException
134
-     * @throws InvalidInterfaceException
135
-     * @throws InvalidDataTypeException
136
-     * @throws EE_Error
137
-     * @throws ReflectionException
138
-     */
139
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
140
-    {
141
-        $className = get_class($this);
142
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
143
-        $model = $this->get_model();
144
-        $model_fields = $model->field_settings(false);
145
-        // ensure $fieldValues is an array
146
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
147
-        // verify client code has not passed any invalid field names
148
-        foreach ($fieldValues as $field_name => $field_value) {
149
-            if (! isset($model_fields[ $field_name ])) {
150
-                throw new EE_Error(
151
-                    sprintf(
152
-                        esc_html__(
153
-                            'Invalid field (%s) passed to constructor of %s. Allowed fields are :%s',
154
-                            'event_espresso'
155
-                        ),
156
-                        $field_name,
157
-                        get_class($this),
158
-                        implode(', ', array_keys($model_fields))
159
-                    )
160
-                );
161
-            }
162
-        }
163
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
164
-        if (! empty($date_formats) && is_array($date_formats)) {
165
-            [$this->_dt_frmt, $this->_tm_frmt] = $date_formats;
166
-        } else {
167
-            // set default formats for date and time
168
-            $this->_dt_frmt = (string) get_option('date_format', 'Y-m-d');
169
-            $this->_tm_frmt = (string) get_option('time_format', 'g:i a');
170
-        }
171
-        // if db model is instantiating
172
-        if ($bydb) {
173
-            // client code has indicated these field values are from the database
174
-            foreach ($model_fields as $fieldName => $field) {
175
-                $this->set_from_db(
176
-                    $fieldName,
177
-                    isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null
178
-                );
179
-            }
180
-        } else {
181
-            // we're constructing a brand
182
-            // new instance of the model object. Generally, this means we'll need to do more field validation
183
-            foreach ($model_fields as $fieldName => $field) {
184
-                $this->set(
185
-                    $fieldName,
186
-                    isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null,
187
-                    true
188
-                );
189
-            }
190
-        }
191
-        // remember what values were passed to this constructor
192
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
193
-        // remember in entity mapper
194
-        if (! $bydb && $model->has_primary_key_field() && $this->ID()) {
195
-            $model->add_to_entity_map($this);
196
-        }
197
-        // setup all the relations
198
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
199
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
200
-                $this->_model_relations[ $relation_name ] = null;
201
-            } else {
202
-                $this->_model_relations[ $relation_name ] = array();
203
-            }
204
-        }
205
-        /**
206
-         * Action done at the end of each model object construction
207
-         *
208
-         * @param EE_Base_Class $this the model object just created
209
-         */
210
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
211
-    }
212
-
213
-
214
-    /**
215
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
216
-     *
217
-     * @return boolean
218
-     */
219
-    public function allow_persist()
220
-    {
221
-        return $this->_allow_persist;
222
-    }
223
-
224
-
225
-    /**
226
-     * Sets whether or not this model object should be allowed to be saved to the DB.
227
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
228
-     * you got new information that somehow made you change your mind.
229
-     *
230
-     * @param boolean $allow_persist
231
-     * @return boolean
232
-     */
233
-    public function set_allow_persist($allow_persist)
234
-    {
235
-        return $this->_allow_persist = $allow_persist;
236
-    }
237
-
238
-
239
-    /**
240
-     * Gets the field's original value when this object was constructed during this request.
241
-     * This can be helpful when determining if a model object has changed or not
242
-     *
243
-     * @param string $field_name
244
-     * @return mixed|null
245
-     * @throws ReflectionException
246
-     * @throws InvalidArgumentException
247
-     * @throws InvalidInterfaceException
248
-     * @throws InvalidDataTypeException
249
-     * @throws EE_Error
250
-     */
251
-    public function get_original($field_name)
252
-    {
253
-        if (
254
-            isset($this->_props_n_values_provided_in_constructor[ $field_name ])
255
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
256
-        ) {
257
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[ $field_name ]);
258
-        }
259
-        return null;
260
-    }
261
-
262
-
263
-    /**
264
-     * @param EE_Base_Class $obj
265
-     * @return string
266
-     */
267
-    public function get_class($obj)
268
-    {
269
-        return get_class($obj);
270
-    }
271
-
272
-
273
-    /**
274
-     * Overrides parent because parent expects old models.
275
-     * This also doesn't do any validation, and won't work for serialized arrays
276
-     *
277
-     * @param    string $field_name
278
-     * @param    mixed  $field_value
279
-     * @param bool      $use_default
280
-     * @throws InvalidArgumentException
281
-     * @throws InvalidInterfaceException
282
-     * @throws InvalidDataTypeException
283
-     * @throws EE_Error
284
-     * @throws ReflectionException
285
-     * @throws ReflectionException
286
-     * @throws ReflectionException
287
-     */
288
-    public function set($field_name, $field_value, $use_default = false)
289
-    {
290
-        // if not using default and nothing has changed, and object has already been setup (has ID),
291
-        // then don't do anything
292
-        if (
293
-            ! $use_default
294
-            && $this->_fields[ $field_name ] === $field_value
295
-            && $this->ID()
296
-        ) {
297
-            return;
298
-        }
299
-        $model = $this->get_model();
300
-        $this->_has_changes = true;
301
-        $field_obj = $model->field_settings_for($field_name);
302
-        if ($field_obj instanceof EE_Model_Field_Base) {
303
-            // if ( method_exists( $field_obj, 'set_timezone' )) {
304
-            if ($field_obj instanceof EE_Datetime_Field) {
305
-                $field_obj->set_timezone($this->_timezone);
306
-                $field_obj->set_date_format($this->_dt_frmt);
307
-                $field_obj->set_time_format($this->_tm_frmt);
308
-            }
309
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
310
-            // should the value be null?
311
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
312
-                $this->_fields[ $field_name ] = $field_obj->get_default_value();
313
-                /**
314
-                 * To save having to refactor all the models, if a default value is used for a
315
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
316
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
317
-                 * object.
318
-                 *
319
-                 * @since 4.6.10+
320
-                 */
321
-                if (
322
-                    $field_obj instanceof EE_Datetime_Field
323
-                    && $this->_fields[ $field_name ] !== null
324
-                    && ! $this->_fields[ $field_name ] instanceof DateTime
325
-                ) {
326
-                    empty($this->_fields[ $field_name ])
327
-                        ? $this->set($field_name, time())
328
-                        : $this->set($field_name, $this->_fields[ $field_name ]);
329
-                }
330
-            } else {
331
-                $this->_fields[ $field_name ] = $holder_of_value;
332
-            }
333
-            // if we're not in the constructor...
334
-            // now check if what we set was a primary key
335
-            if (
16
+	/**
17
+	 * This is an array of the original properties and values provided during construction
18
+	 * of this model object. (keys are model field names, values are their values).
19
+	 * This list is important to remember so that when we are merging data from the db, we know
20
+	 * which values to override and which to not override.
21
+	 *
22
+	 * @var array
23
+	 */
24
+	protected $_props_n_values_provided_in_constructor;
25
+
26
+	/**
27
+	 * Timezone
28
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
29
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
30
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
31
+	 * access to it.
32
+	 *
33
+	 * @var string
34
+	 */
35
+	protected $_timezone;
36
+
37
+	/**
38
+	 * date format
39
+	 * pattern or format for displaying dates
40
+	 *
41
+	 * @var string $_dt_frmt
42
+	 */
43
+	protected $_dt_frmt;
44
+
45
+	/**
46
+	 * time format
47
+	 * pattern or format for displaying time
48
+	 *
49
+	 * @var string $_tm_frmt
50
+	 */
51
+	protected $_tm_frmt;
52
+
53
+	/**
54
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
55
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
56
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
57
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
58
+	 *
59
+	 * @var array
60
+	 */
61
+	protected $_cached_properties = array();
62
+
63
+	/**
64
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
65
+	 * single
66
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
67
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
68
+	 * all others have an array)
69
+	 *
70
+	 * @var array
71
+	 */
72
+	protected $_model_relations = array();
73
+
74
+	/**
75
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
76
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
77
+	 *
78
+	 * @var array
79
+	 */
80
+	protected $_fields = array();
81
+
82
+	/**
83
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
84
+	 * For example, we might create model objects intended to only be used for the duration
85
+	 * of this request and to be thrown away, and if they were accidentally saved
86
+	 * it would be a bug.
87
+	 */
88
+	protected $_allow_persist = true;
89
+
90
+	/**
91
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
92
+	 */
93
+	protected $_has_changes = false;
94
+
95
+	/**
96
+	 * @var EEM_Base
97
+	 */
98
+	protected $_model;
99
+
100
+	/**
101
+	 * This is a cache of results from custom selections done on a query that constructs this entity. The only purpose
102
+	 * for these values is for retrieval of the results, they are not further queryable and they are not persisted to
103
+	 * the db.  They also do not automatically update if there are any changes to the data that produced their results.
104
+	 * The format is a simple array of field_alias => field_value.  So for instance if a custom select was something
105
+	 * like,  "Select COUNT(Registration.REG_ID) as Registration_Count ...", then the resulting value will be in this
106
+	 * array as:
107
+	 * array(
108
+	 *  'Registration_Count' => 24
109
+	 * );
110
+	 * Note: if the custom select configuration for the query included a data type, the value will be in the data type
111
+	 * provided for the query (@see EventEspresso\core\domain\values\model\CustomSelects::__construct phpdocs for more
112
+	 * info)
113
+	 *
114
+	 * @var array
115
+	 */
116
+	protected $custom_selection_results = array();
117
+
118
+
119
+	/**
120
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
121
+	 * play nice
122
+	 *
123
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
124
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
125
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
126
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
127
+	 *                                                         corresponding db model or not.
128
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
129
+	 *                                                         be in when instantiating a EE_Base_Class object.
130
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
131
+	 *                                                         value is the date_format and second value is the time
132
+	 *                                                         format.
133
+	 * @throws InvalidArgumentException
134
+	 * @throws InvalidInterfaceException
135
+	 * @throws InvalidDataTypeException
136
+	 * @throws EE_Error
137
+	 * @throws ReflectionException
138
+	 */
139
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
140
+	{
141
+		$className = get_class($this);
142
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
143
+		$model = $this->get_model();
144
+		$model_fields = $model->field_settings(false);
145
+		// ensure $fieldValues is an array
146
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
147
+		// verify client code has not passed any invalid field names
148
+		foreach ($fieldValues as $field_name => $field_value) {
149
+			if (! isset($model_fields[ $field_name ])) {
150
+				throw new EE_Error(
151
+					sprintf(
152
+						esc_html__(
153
+							'Invalid field (%s) passed to constructor of %s. Allowed fields are :%s',
154
+							'event_espresso'
155
+						),
156
+						$field_name,
157
+						get_class($this),
158
+						implode(', ', array_keys($model_fields))
159
+					)
160
+				);
161
+			}
162
+		}
163
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
164
+		if (! empty($date_formats) && is_array($date_formats)) {
165
+			[$this->_dt_frmt, $this->_tm_frmt] = $date_formats;
166
+		} else {
167
+			// set default formats for date and time
168
+			$this->_dt_frmt = (string) get_option('date_format', 'Y-m-d');
169
+			$this->_tm_frmt = (string) get_option('time_format', 'g:i a');
170
+		}
171
+		// if db model is instantiating
172
+		if ($bydb) {
173
+			// client code has indicated these field values are from the database
174
+			foreach ($model_fields as $fieldName => $field) {
175
+				$this->set_from_db(
176
+					$fieldName,
177
+					isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null
178
+				);
179
+			}
180
+		} else {
181
+			// we're constructing a brand
182
+			// new instance of the model object. Generally, this means we'll need to do more field validation
183
+			foreach ($model_fields as $fieldName => $field) {
184
+				$this->set(
185
+					$fieldName,
186
+					isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null,
187
+					true
188
+				);
189
+			}
190
+		}
191
+		// remember what values were passed to this constructor
192
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
193
+		// remember in entity mapper
194
+		if (! $bydb && $model->has_primary_key_field() && $this->ID()) {
195
+			$model->add_to_entity_map($this);
196
+		}
197
+		// setup all the relations
198
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
199
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
200
+				$this->_model_relations[ $relation_name ] = null;
201
+			} else {
202
+				$this->_model_relations[ $relation_name ] = array();
203
+			}
204
+		}
205
+		/**
206
+		 * Action done at the end of each model object construction
207
+		 *
208
+		 * @param EE_Base_Class $this the model object just created
209
+		 */
210
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
211
+	}
212
+
213
+
214
+	/**
215
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
216
+	 *
217
+	 * @return boolean
218
+	 */
219
+	public function allow_persist()
220
+	{
221
+		return $this->_allow_persist;
222
+	}
223
+
224
+
225
+	/**
226
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
227
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
228
+	 * you got new information that somehow made you change your mind.
229
+	 *
230
+	 * @param boolean $allow_persist
231
+	 * @return boolean
232
+	 */
233
+	public function set_allow_persist($allow_persist)
234
+	{
235
+		return $this->_allow_persist = $allow_persist;
236
+	}
237
+
238
+
239
+	/**
240
+	 * Gets the field's original value when this object was constructed during this request.
241
+	 * This can be helpful when determining if a model object has changed or not
242
+	 *
243
+	 * @param string $field_name
244
+	 * @return mixed|null
245
+	 * @throws ReflectionException
246
+	 * @throws InvalidArgumentException
247
+	 * @throws InvalidInterfaceException
248
+	 * @throws InvalidDataTypeException
249
+	 * @throws EE_Error
250
+	 */
251
+	public function get_original($field_name)
252
+	{
253
+		if (
254
+			isset($this->_props_n_values_provided_in_constructor[ $field_name ])
255
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
256
+		) {
257
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[ $field_name ]);
258
+		}
259
+		return null;
260
+	}
261
+
262
+
263
+	/**
264
+	 * @param EE_Base_Class $obj
265
+	 * @return string
266
+	 */
267
+	public function get_class($obj)
268
+	{
269
+		return get_class($obj);
270
+	}
271
+
272
+
273
+	/**
274
+	 * Overrides parent because parent expects old models.
275
+	 * This also doesn't do any validation, and won't work for serialized arrays
276
+	 *
277
+	 * @param    string $field_name
278
+	 * @param    mixed  $field_value
279
+	 * @param bool      $use_default
280
+	 * @throws InvalidArgumentException
281
+	 * @throws InvalidInterfaceException
282
+	 * @throws InvalidDataTypeException
283
+	 * @throws EE_Error
284
+	 * @throws ReflectionException
285
+	 * @throws ReflectionException
286
+	 * @throws ReflectionException
287
+	 */
288
+	public function set($field_name, $field_value, $use_default = false)
289
+	{
290
+		// if not using default and nothing has changed, and object has already been setup (has ID),
291
+		// then don't do anything
292
+		if (
293
+			! $use_default
294
+			&& $this->_fields[ $field_name ] === $field_value
295
+			&& $this->ID()
296
+		) {
297
+			return;
298
+		}
299
+		$model = $this->get_model();
300
+		$this->_has_changes = true;
301
+		$field_obj = $model->field_settings_for($field_name);
302
+		if ($field_obj instanceof EE_Model_Field_Base) {
303
+			// if ( method_exists( $field_obj, 'set_timezone' )) {
304
+			if ($field_obj instanceof EE_Datetime_Field) {
305
+				$field_obj->set_timezone($this->_timezone);
306
+				$field_obj->set_date_format($this->_dt_frmt);
307
+				$field_obj->set_time_format($this->_tm_frmt);
308
+			}
309
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
310
+			// should the value be null?
311
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
312
+				$this->_fields[ $field_name ] = $field_obj->get_default_value();
313
+				/**
314
+				 * To save having to refactor all the models, if a default value is used for a
315
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
316
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
317
+				 * object.
318
+				 *
319
+				 * @since 4.6.10+
320
+				 */
321
+				if (
322
+					$field_obj instanceof EE_Datetime_Field
323
+					&& $this->_fields[ $field_name ] !== null
324
+					&& ! $this->_fields[ $field_name ] instanceof DateTime
325
+				) {
326
+					empty($this->_fields[ $field_name ])
327
+						? $this->set($field_name, time())
328
+						: $this->set($field_name, $this->_fields[ $field_name ]);
329
+				}
330
+			} else {
331
+				$this->_fields[ $field_name ] = $holder_of_value;
332
+			}
333
+			// if we're not in the constructor...
334
+			// now check if what we set was a primary key
335
+			if (
336 336
 // note: props_n_values_provided_in_constructor is only set at the END of the constructor
337
-                $this->_props_n_values_provided_in_constructor
338
-                && $field_value
339
-                && $field_name === $model->primary_key_name()
340
-            ) {
341
-                // if so, we want all this object's fields to be filled either with
342
-                // what we've explicitly set on this model
343
-                // or what we have in the db
344
-                // echo "setting primary key!";
345
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
346
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
347
-                foreach ($fields_on_model as $field_obj) {
348
-                    if (
349
-                        ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
350
-                        && $field_obj->get_name() !== $field_name
351
-                    ) {
352
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
353
-                    }
354
-                }
355
-                // oh this model object has an ID? well make sure its in the entity mapper
356
-                $model->add_to_entity_map($this);
357
-            }
358
-            // let's unset any cache for this field_name from the $_cached_properties property.
359
-            $this->_clear_cached_property($field_name);
360
-        } else {
361
-            throw new EE_Error(
362
-                sprintf(
363
-                    esc_html__(
364
-                        'A valid EE_Model_Field_Base could not be found for the given field name: %s',
365
-                        'event_espresso'
366
-                    ),
367
-                    $field_name
368
-                )
369
-            );
370
-        }
371
-    }
372
-
373
-
374
-    /**
375
-     * Set custom select values for model.
376
-     *
377
-     * @param array $custom_select_values
378
-     */
379
-    public function setCustomSelectsValues(array $custom_select_values)
380
-    {
381
-        $this->custom_selection_results = $custom_select_values;
382
-    }
383
-
384
-
385
-    /**
386
-     * Returns the custom select value for the provided alias if its set.
387
-     * If not set, returns null.
388
-     *
389
-     * @param string $alias
390
-     * @return string|int|float|null
391
-     */
392
-    public function getCustomSelect($alias)
393
-    {
394
-        return isset($this->custom_selection_results[ $alias ])
395
-            ? $this->custom_selection_results[ $alias ]
396
-            : null;
397
-    }
398
-
399
-
400
-    /**
401
-     * This sets the field value on the db column if it exists for the given $column_name or
402
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
403
-     *
404
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
405
-     * @param string $field_name  Must be the exact column name.
406
-     * @param mixed  $field_value The value to set.
407
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
408
-     * @throws InvalidArgumentException
409
-     * @throws InvalidInterfaceException
410
-     * @throws InvalidDataTypeException
411
-     * @throws EE_Error
412
-     * @throws ReflectionException
413
-     */
414
-    public function set_field_or_extra_meta($field_name, $field_value)
415
-    {
416
-        if ($this->get_model()->has_field($field_name)) {
417
-            $this->set($field_name, $field_value);
418
-            return true;
419
-        }
420
-        // ensure this object is saved first so that extra meta can be properly related.
421
-        $this->save();
422
-        return $this->update_extra_meta($field_name, $field_value);
423
-    }
424
-
425
-
426
-    /**
427
-     * This retrieves the value of the db column set on this class or if that's not present
428
-     * it will attempt to retrieve from extra_meta if found.
429
-     * Example Usage:
430
-     * Via EE_Message child class:
431
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
432
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
433
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
434
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
435
-     * value for those extra fields dynamically via the EE_message object.
436
-     *
437
-     * @param  string $field_name expecting the fully qualified field name.
438
-     * @return mixed|null  value for the field if found.  null if not found.
439
-     * @throws ReflectionException
440
-     * @throws InvalidArgumentException
441
-     * @throws InvalidInterfaceException
442
-     * @throws InvalidDataTypeException
443
-     * @throws EE_Error
444
-     */
445
-    public function get_field_or_extra_meta($field_name)
446
-    {
447
-        if ($this->get_model()->has_field($field_name)) {
448
-            $column_value = $this->get($field_name);
449
-        } else {
450
-            // This isn't a column in the main table, let's see if it is in the extra meta.
451
-            $column_value = $this->get_extra_meta($field_name, true, null);
452
-        }
453
-        return $column_value;
454
-    }
455
-
456
-
457
-    /**
458
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
459
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
460
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
461
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
462
-     *
463
-     * @access public
464
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
465
-     * @return void
466
-     * @throws InvalidArgumentException
467
-     * @throws InvalidInterfaceException
468
-     * @throws InvalidDataTypeException
469
-     * @throws EE_Error
470
-     * @throws ReflectionException
471
-     */
472
-    public function set_timezone($timezone = '')
473
-    {
474
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
475
-        // make sure we clear all cached properties because they won't be relevant now
476
-        $this->_clear_cached_properties();
477
-        // make sure we update field settings and the date for all EE_Datetime_Fields
478
-        $model_fields = $this->get_model()->field_settings(false);
479
-        foreach ($model_fields as $field_name => $field_obj) {
480
-            if ($field_obj instanceof EE_Datetime_Field) {
481
-                $field_obj->set_timezone($this->_timezone);
482
-                if (isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime) {
483
-                    EEH_DTT_Helper::setTimezone($this->_fields[ $field_name ], new DateTimeZone($this->_timezone));
484
-                }
485
-            }
486
-        }
487
-    }
488
-
489
-
490
-    /**
491
-     * This just returns whatever is set for the current timezone.
492
-     *
493
-     * @access public
494
-     * @return string timezone string
495
-     */
496
-    public function get_timezone()
497
-    {
498
-        return $this->_timezone;
499
-    }
500
-
501
-
502
-    /**
503
-     * This sets the internal date format to what is sent in to be used as the new default for the class
504
-     * internally instead of wp set date format options
505
-     *
506
-     * @since 4.6
507
-     * @param string $format should be a format recognizable by PHP date() functions.
508
-     */
509
-    public function set_date_format($format)
510
-    {
511
-        $this->_dt_frmt = $format;
512
-        // clear cached_properties because they won't be relevant now.
513
-        $this->_clear_cached_properties();
514
-    }
515
-
516
-
517
-    /**
518
-     * This sets the internal time format string to what is sent in to be used as the new default for the
519
-     * class internally instead of wp set time format options.
520
-     *
521
-     * @since 4.6
522
-     * @param string $format should be a format recognizable by PHP date() functions.
523
-     */
524
-    public function set_time_format($format)
525
-    {
526
-        $this->_tm_frmt = $format;
527
-        // clear cached_properties because they won't be relevant now.
528
-        $this->_clear_cached_properties();
529
-    }
530
-
531
-
532
-    /**
533
-     * This returns the current internal set format for the date and time formats.
534
-     *
535
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
536
-     *                             where the first value is the date format and the second value is the time format.
537
-     * @return mixed string|array
538
-     */
539
-    public function get_format($full = true)
540
-    {
541
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
542
-    }
543
-
544
-
545
-    /**
546
-     * cache
547
-     * stores the passed model object on the current model object.
548
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
549
-     *
550
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
551
-     *                                       'Registration' associated with this model object
552
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
553
-     *                                       that could be a payment or a registration)
554
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
555
-     *                                       items which will be stored in an array on this object
556
-     * @throws ReflectionException
557
-     * @throws InvalidArgumentException
558
-     * @throws InvalidInterfaceException
559
-     * @throws InvalidDataTypeException
560
-     * @throws EE_Error
561
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
562
-     *                                       related thing, no array)
563
-     */
564
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
565
-    {
566
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
567
-        if (! $object_to_cache instanceof EE_Base_Class) {
568
-            return false;
569
-        }
570
-        // also get "how" the object is related, or throw an error
571
-        if (! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
572
-            throw new EE_Error(
573
-                sprintf(
574
-                    esc_html__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
575
-                    $relationName,
576
-                    get_class($this)
577
-                )
578
-            );
579
-        }
580
-        // how many things are related ?
581
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
582
-            // if it's a "belongs to" relationship, then there's only one related model object
583
-            // eg, if this is a registration, there's only 1 attendee for it
584
-            // so for these model objects just set it to be cached
585
-            $this->_model_relations[ $relationName ] = $object_to_cache;
586
-            $return = true;
587
-        } else {
588
-            // otherwise, this is the "many" side of a one to many relationship,
589
-            // so we'll add the object to the array of related objects for that type.
590
-            // eg: if this is an event, there are many registrations for that event,
591
-            // so we cache the registrations in an array
592
-            if (! is_array($this->_model_relations[ $relationName ])) {
593
-                // if for some reason, the cached item is a model object,
594
-                // then stick that in the array, otherwise start with an empty array
595
-                $this->_model_relations[ $relationName ] = $this->_model_relations[ $relationName ]
596
-                                                           instanceof
597
-                                                           EE_Base_Class
598
-                    ? array($this->_model_relations[ $relationName ]) : array();
599
-            }
600
-            // first check for a cache_id which is normally empty
601
-            if (! empty($cache_id)) {
602
-                // if the cache_id exists, then it means we are purposely trying to cache this
603
-                // with a known key that can then be used to retrieve the object later on
604
-                $this->_model_relations[ $relationName ][ $cache_id ] = $object_to_cache;
605
-                $return = $cache_id;
606
-            } elseif ($object_to_cache->ID()) {
607
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
608
-                $this->_model_relations[ $relationName ][ $object_to_cache->ID() ] = $object_to_cache;
609
-                $return = $object_to_cache->ID();
610
-            } else {
611
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
612
-                $this->_model_relations[ $relationName ][] = $object_to_cache;
613
-                // move the internal pointer to the end of the array
614
-                end($this->_model_relations[ $relationName ]);
615
-                // and grab the key so that we can return it
616
-                $return = key($this->_model_relations[ $relationName ]);
617
-            }
618
-        }
619
-        return $return;
620
-    }
621
-
622
-
623
-    /**
624
-     * For adding an item to the cached_properties property.
625
-     *
626
-     * @access protected
627
-     * @param string      $fieldname the property item the corresponding value is for.
628
-     * @param mixed       $value     The value we are caching.
629
-     * @param string|null $cache_type
630
-     * @return void
631
-     * @throws ReflectionException
632
-     * @throws InvalidArgumentException
633
-     * @throws InvalidInterfaceException
634
-     * @throws InvalidDataTypeException
635
-     * @throws EE_Error
636
-     */
637
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
638
-    {
639
-        // first make sure this property exists
640
-        $this->get_model()->field_settings_for($fieldname);
641
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
642
-        $this->_cached_properties[ $fieldname ][ $cache_type ] = $value;
643
-    }
644
-
645
-
646
-    /**
647
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
648
-     * This also SETS the cache if we return the actual property!
649
-     *
650
-     * @param string $fieldname        the name of the property we're trying to retrieve
651
-     * @param bool   $pretty
652
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
653
-     *                                 (in cases where the same property may be used for different outputs
654
-     *                                 - i.e. datetime, money etc.)
655
-     *                                 It can also accept certain pre-defined "schema" strings
656
-     *                                 to define how to output the property.
657
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
658
-     * @return mixed                   whatever the value for the property is we're retrieving
659
-     * @throws ReflectionException
660
-     * @throws InvalidArgumentException
661
-     * @throws InvalidInterfaceException
662
-     * @throws InvalidDataTypeException
663
-     * @throws EE_Error
664
-     */
665
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
666
-    {
667
-        // verify the field exists
668
-        $model = $this->get_model();
669
-        $model->field_settings_for($fieldname);
670
-        $cache_type = $pretty ? 'pretty' : 'standard';
671
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
672
-        if (isset($this->_cached_properties[ $fieldname ][ $cache_type ])) {
673
-            return $this->_cached_properties[ $fieldname ][ $cache_type ];
674
-        }
675
-        $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
676
-        $this->_set_cached_property($fieldname, $value, $cache_type);
677
-        return $value;
678
-    }
679
-
680
-
681
-    /**
682
-     * If the cache didn't fetch the needed item, this fetches it.
683
-     *
684
-     * @param string $fieldname
685
-     * @param bool   $pretty
686
-     * @param string $extra_cache_ref
687
-     * @return mixed
688
-     * @throws InvalidArgumentException
689
-     * @throws InvalidInterfaceException
690
-     * @throws InvalidDataTypeException
691
-     * @throws EE_Error
692
-     * @throws ReflectionException
693
-     */
694
-    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
695
-    {
696
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
697
-        // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
698
-        if ($field_obj instanceof EE_Datetime_Field) {
699
-            $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
700
-        }
701
-        if (! isset($this->_fields[ $fieldname ])) {
702
-            $this->_fields[ $fieldname ] = null;
703
-        }
704
-        $value = $pretty
705
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[ $fieldname ], $extra_cache_ref)
706
-            : $field_obj->prepare_for_get($this->_fields[ $fieldname ]);
707
-        return $value;
708
-    }
709
-
710
-
711
-    /**
712
-     * set timezone, formats, and output for EE_Datetime_Field objects
713
-     *
714
-     * @param \EE_Datetime_Field $datetime_field
715
-     * @param bool               $pretty
716
-     * @param null               $date_or_time
717
-     * @return void
718
-     * @throws InvalidArgumentException
719
-     * @throws InvalidInterfaceException
720
-     * @throws InvalidDataTypeException
721
-     * @throws EE_Error
722
-     */
723
-    protected function _prepare_datetime_field(
724
-        EE_Datetime_Field $datetime_field,
725
-        $pretty = false,
726
-        $date_or_time = null
727
-    ) {
728
-        $datetime_field->set_timezone($this->_timezone);
729
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
730
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
731
-        // set the output returned
732
-        switch ($date_or_time) {
733
-            case 'D':
734
-                $datetime_field->set_date_time_output('date');
735
-                break;
736
-            case 'T':
737
-                $datetime_field->set_date_time_output('time');
738
-                break;
739
-            default:
740
-                $datetime_field->set_date_time_output();
741
-        }
742
-    }
743
-
744
-
745
-    /**
746
-     * This just takes care of clearing out the cached_properties
747
-     *
748
-     * @return void
749
-     */
750
-    protected function _clear_cached_properties()
751
-    {
752
-        $this->_cached_properties = array();
753
-    }
754
-
755
-
756
-    /**
757
-     * This just clears out ONE property if it exists in the cache
758
-     *
759
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
760
-     * @return void
761
-     */
762
-    protected function _clear_cached_property($property_name)
763
-    {
764
-        if (isset($this->_cached_properties[ $property_name ])) {
765
-            unset($this->_cached_properties[ $property_name ]);
766
-        }
767
-    }
768
-
769
-
770
-    /**
771
-     * Ensures that this related thing is a model object.
772
-     *
773
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
774
-     * @param string $model_name   name of the related thing, eg 'Attendee',
775
-     * @return EE_Base_Class
776
-     * @throws ReflectionException
777
-     * @throws InvalidArgumentException
778
-     * @throws InvalidInterfaceException
779
-     * @throws InvalidDataTypeException
780
-     * @throws EE_Error
781
-     */
782
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
783
-    {
784
-        $other_model_instance = self::_get_model_instance_with_name(
785
-            self::_get_model_classname($model_name),
786
-            $this->_timezone
787
-        );
788
-        return $other_model_instance->ensure_is_obj($object_or_id);
789
-    }
790
-
791
-
792
-    /**
793
-     * Forgets the cached model of the given relation Name. So the next time we request it,
794
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
795
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
796
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
797
-     *
798
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
799
-     *                                                     Eg 'Registration'
800
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
801
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
802
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
803
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
804
-     *                                                     this is HasMany or HABTM.
805
-     * @throws ReflectionException
806
-     * @throws InvalidArgumentException
807
-     * @throws InvalidInterfaceException
808
-     * @throws InvalidDataTypeException
809
-     * @throws EE_Error
810
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
811
-     *                                                     relation from all
812
-     */
813
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
814
-    {
815
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
816
-        $index_in_cache = '';
817
-        if (! $relationship_to_model) {
818
-            throw new EE_Error(
819
-                sprintf(
820
-                    esc_html__('There is no relationship to %s on a %s. Cannot clear that cache', 'event_espresso'),
821
-                    $relationName,
822
-                    get_class($this)
823
-                )
824
-            );
825
-        }
826
-        if ($clear_all) {
827
-            $obj_removed = true;
828
-            $this->_model_relations[ $relationName ] = null;
829
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
830
-            $obj_removed = $this->_model_relations[ $relationName ];
831
-            $this->_model_relations[ $relationName ] = null;
832
-        } else {
833
-            if (
834
-                $object_to_remove_or_index_into_array instanceof EE_Base_Class
835
-                && $object_to_remove_or_index_into_array->ID()
836
-            ) {
837
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
838
-                if (
839
-                    is_array($this->_model_relations[ $relationName ])
840
-                    && ! isset($this->_model_relations[ $relationName ][ $index_in_cache ])
841
-                ) {
842
-                    $index_found_at = null;
843
-                    // find this object in the array even though it has a different key
844
-                    foreach ($this->_model_relations[ $relationName ] as $index => $obj) {
845
-                        /** @noinspection TypeUnsafeComparisonInspection */
846
-                        if (
847
-                            $obj instanceof EE_Base_Class
848
-                            && (
849
-                                $obj == $object_to_remove_or_index_into_array
850
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
851
-                            )
852
-                        ) {
853
-                            $index_found_at = $index;
854
-                            break;
855
-                        }
856
-                    }
857
-                    if ($index_found_at) {
858
-                        $index_in_cache = $index_found_at;
859
-                    } else {
860
-                        // it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
861
-                        // if it wasn't in it to begin with. So we're done
862
-                        return $object_to_remove_or_index_into_array;
863
-                    }
864
-                }
865
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
866
-                // so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
867
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
868
-                    /** @noinspection TypeUnsafeComparisonInspection */
869
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
870
-                        $index_in_cache = $index;
871
-                    }
872
-                }
873
-            } else {
874
-                $index_in_cache = $object_to_remove_or_index_into_array;
875
-            }
876
-            // supposedly we've found it. But it could just be that the client code
877
-            // provided a bad index/object
878
-            if (isset($this->_model_relations[ $relationName ][ $index_in_cache ])) {
879
-                $obj_removed = $this->_model_relations[ $relationName ][ $index_in_cache ];
880
-                unset($this->_model_relations[ $relationName ][ $index_in_cache ]);
881
-            } else {
882
-                // that thing was never cached anyways.
883
-                $obj_removed = null;
884
-            }
885
-        }
886
-        return $obj_removed;
887
-    }
888
-
889
-
890
-    /**
891
-     * update_cache_after_object_save
892
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
893
-     * obtained after being saved to the db
894
-     *
895
-     * @param string        $relationName       - the type of object that is cached
896
-     * @param EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
897
-     * @param string        $current_cache_id   - the ID that was used when originally caching the object
898
-     * @return boolean TRUE on success, FALSE on fail
899
-     * @throws ReflectionException
900
-     * @throws InvalidArgumentException
901
-     * @throws InvalidInterfaceException
902
-     * @throws InvalidDataTypeException
903
-     * @throws EE_Error
904
-     */
905
-    public function update_cache_after_object_save(
906
-        $relationName,
907
-        EE_Base_Class $newly_saved_object,
908
-        $current_cache_id = ''
909
-    ) {
910
-        // verify that incoming object is of the correct type
911
-        $obj_class = 'EE_' . $relationName;
912
-        if ($newly_saved_object instanceof $obj_class) {
913
-            /* @type EE_Base_Class $newly_saved_object */
914
-            // now get the type of relation
915
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
916
-            // if this is a 1:1 relationship
917
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
918
-                // then just replace the cached object with the newly saved object
919
-                $this->_model_relations[ $relationName ] = $newly_saved_object;
920
-                return true;
921
-                // or if it's some kind of sordid feral polyamorous relationship...
922
-            }
923
-            if (
924
-                is_array($this->_model_relations[ $relationName ])
925
-                && isset($this->_model_relations[ $relationName ][ $current_cache_id ])
926
-            ) {
927
-                // then remove the current cached item
928
-                unset($this->_model_relations[ $relationName ][ $current_cache_id ]);
929
-                // and cache the newly saved object using it's new ID
930
-                $this->_model_relations[ $relationName ][ $newly_saved_object->ID() ] = $newly_saved_object;
931
-                return true;
932
-            }
933
-        }
934
-        return false;
935
-    }
936
-
937
-
938
-    /**
939
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
940
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
941
-     *
942
-     * @param string $relationName
943
-     * @return EE_Base_Class
944
-     */
945
-    public function get_one_from_cache($relationName)
946
-    {
947
-        $cached_array_or_object = isset($this->_model_relations[ $relationName ])
948
-            ? $this->_model_relations[ $relationName ]
949
-            : null;
950
-        if (is_array($cached_array_or_object)) {
951
-            return array_shift($cached_array_or_object);
952
-        }
953
-        return $cached_array_or_object;
954
-    }
955
-
956
-
957
-    /**
958
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
959
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
960
-     *
961
-     * @param string $relationName
962
-     * @throws ReflectionException
963
-     * @throws InvalidArgumentException
964
-     * @throws InvalidInterfaceException
965
-     * @throws InvalidDataTypeException
966
-     * @throws EE_Error
967
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
968
-     */
969
-    public function get_all_from_cache($relationName)
970
-    {
971
-        $objects = isset($this->_model_relations[ $relationName ]) ? $this->_model_relations[ $relationName ] : array();
972
-        // if the result is not an array, but exists, make it an array
973
-        $objects = is_array($objects) ? $objects : array($objects);
974
-        // bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
975
-        // basically, if this model object was stored in the session, and these cached model objects
976
-        // already have IDs, let's make sure they're in their model's entity mapper
977
-        // otherwise we will have duplicates next time we call
978
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
979
-        $model = EE_Registry::instance()->load_model($relationName);
980
-        foreach ($objects as $model_object) {
981
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
982
-                // ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
983
-                if ($model_object->ID()) {
984
-                    $model->add_to_entity_map($model_object);
985
-                }
986
-            } else {
987
-                throw new EE_Error(
988
-                    sprintf(
989
-                        esc_html__(
990
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
991
-                            'event_espresso'
992
-                        ),
993
-                        $relationName,
994
-                        gettype($model_object)
995
-                    )
996
-                );
997
-            }
998
-        }
999
-        return $objects;
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
1005
-     * matching the given query conditions.
1006
-     *
1007
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1008
-     * @param int   $limit              How many objects to return.
1009
-     * @param array $query_params       Any additional conditions on the query.
1010
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1011
-     *                                  you can indicate just the columns you want returned
1012
-     * @return array|EE_Base_Class[]
1013
-     * @throws ReflectionException
1014
-     * @throws InvalidArgumentException
1015
-     * @throws InvalidInterfaceException
1016
-     * @throws InvalidDataTypeException
1017
-     * @throws EE_Error
1018
-     */
1019
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
1020
-    {
1021
-        $model = $this->get_model();
1022
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1023
-            ? $model->get_primary_key_field()->get_name()
1024
-            : $field_to_order_by;
1025
-        $current_value = ! empty($field) ? $this->get($field) : null;
1026
-        if (empty($field) || empty($current_value)) {
1027
-            return array();
1028
-        }
1029
-        return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
1030
-    }
1031
-
1032
-
1033
-    /**
1034
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
1035
-     * matching the given query conditions.
1036
-     *
1037
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1038
-     * @param int   $limit              How many objects to return.
1039
-     * @param array $query_params       Any additional conditions on the query.
1040
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1041
-     *                                  you can indicate just the columns you want returned
1042
-     * @return array|EE_Base_Class[]
1043
-     * @throws ReflectionException
1044
-     * @throws InvalidArgumentException
1045
-     * @throws InvalidInterfaceException
1046
-     * @throws InvalidDataTypeException
1047
-     * @throws EE_Error
1048
-     */
1049
-    public function previous_x(
1050
-        $field_to_order_by = null,
1051
-        $limit = 1,
1052
-        $query_params = array(),
1053
-        $columns_to_select = null
1054
-    ) {
1055
-        $model = $this->get_model();
1056
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1057
-            ? $model->get_primary_key_field()->get_name()
1058
-            : $field_to_order_by;
1059
-        $current_value = ! empty($field) ? $this->get($field) : null;
1060
-        if (empty($field) || empty($current_value)) {
1061
-            return array();
1062
-        }
1063
-        return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
1064
-    }
1065
-
1066
-
1067
-    /**
1068
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
1069
-     * matching the given query conditions.
1070
-     *
1071
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1072
-     * @param array $query_params       Any additional conditions on the query.
1073
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1074
-     *                                  you can indicate just the columns you want returned
1075
-     * @return array|EE_Base_Class
1076
-     * @throws ReflectionException
1077
-     * @throws InvalidArgumentException
1078
-     * @throws InvalidInterfaceException
1079
-     * @throws InvalidDataTypeException
1080
-     * @throws EE_Error
1081
-     */
1082
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1083
-    {
1084
-        $model = $this->get_model();
1085
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1086
-            ? $model->get_primary_key_field()->get_name()
1087
-            : $field_to_order_by;
1088
-        $current_value = ! empty($field) ? $this->get($field) : null;
1089
-        if (empty($field) || empty($current_value)) {
1090
-            return array();
1091
-        }
1092
-        return $model->next($current_value, $field, $query_params, $columns_to_select);
1093
-    }
1094
-
1095
-
1096
-    /**
1097
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
1098
-     * matching the given query conditions.
1099
-     *
1100
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1101
-     * @param array $query_params       Any additional conditions on the query.
1102
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1103
-     *                                  you can indicate just the column you want returned
1104
-     * @return array|EE_Base_Class
1105
-     * @throws ReflectionException
1106
-     * @throws InvalidArgumentException
1107
-     * @throws InvalidInterfaceException
1108
-     * @throws InvalidDataTypeException
1109
-     * @throws EE_Error
1110
-     */
1111
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1112
-    {
1113
-        $model = $this->get_model();
1114
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1115
-            ? $model->get_primary_key_field()->get_name()
1116
-            : $field_to_order_by;
1117
-        $current_value = ! empty($field) ? $this->get($field) : null;
1118
-        if (empty($field) || empty($current_value)) {
1119
-            return array();
1120
-        }
1121
-        return $model->previous($current_value, $field, $query_params, $columns_to_select);
1122
-    }
1123
-
1124
-
1125
-    /**
1126
-     * Overrides parent because parent expects old models.
1127
-     * This also doesn't do any validation, and won't work for serialized arrays
1128
-     *
1129
-     * @param string $field_name
1130
-     * @param mixed  $field_value_from_db
1131
-     * @throws ReflectionException
1132
-     * @throws InvalidArgumentException
1133
-     * @throws InvalidInterfaceException
1134
-     * @throws InvalidDataTypeException
1135
-     * @throws EE_Error
1136
-     */
1137
-    public function set_from_db($field_name, $field_value_from_db)
1138
-    {
1139
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1140
-        if ($field_obj instanceof EE_Model_Field_Base) {
1141
-            // you would think the DB has no NULLs for non-null label fields right? wrong!
1142
-            // eg, a CPT model object could have an entry in the posts table, but no
1143
-            // entry in the meta table. Meaning that all its columns in the meta table
1144
-            // are null! yikes! so when we find one like that, use defaults for its meta columns
1145
-            if ($field_value_from_db === null) {
1146
-                if ($field_obj->is_nullable()) {
1147
-                    // if the field allows nulls, then let it be null
1148
-                    $field_value = null;
1149
-                } else {
1150
-                    $field_value = $field_obj->get_default_value();
1151
-                }
1152
-            } else {
1153
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1154
-            }
1155
-            $this->_fields[ $field_name ] = $field_value;
1156
-            $this->_clear_cached_property($field_name);
1157
-        }
1158
-    }
1159
-
1160
-
1161
-    /**
1162
-     * verifies that the specified field is of the correct type
1163
-     *
1164
-     * @param string $field_name
1165
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1166
-     *                                (in cases where the same property may be used for different outputs
1167
-     *                                - i.e. datetime, money etc.)
1168
-     * @return mixed
1169
-     * @throws ReflectionException
1170
-     * @throws InvalidArgumentException
1171
-     * @throws InvalidInterfaceException
1172
-     * @throws InvalidDataTypeException
1173
-     * @throws EE_Error
1174
-     */
1175
-    public function get($field_name, $extra_cache_ref = null)
1176
-    {
1177
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * This method simply returns the RAW unprocessed value for the given property in this class
1183
-     *
1184
-     * @param  string $field_name A valid fieldname
1185
-     * @return mixed              Whatever the raw value stored on the property is.
1186
-     * @throws ReflectionException
1187
-     * @throws InvalidArgumentException
1188
-     * @throws InvalidInterfaceException
1189
-     * @throws InvalidDataTypeException
1190
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1191
-     */
1192
-    public function get_raw($field_name)
1193
-    {
1194
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1195
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[ $field_name ] instanceof DateTime
1196
-            ? $this->_fields[ $field_name ]->format('U')
1197
-            : $this->_fields[ $field_name ];
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     * This is used to return the internal DateTime object used for a field that is a
1203
-     * EE_Datetime_Field.
1204
-     *
1205
-     * @param string $field_name               The field name retrieving the DateTime object.
1206
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1207
-     * @throws EE_Error an error is set and false returned.  If the field IS an
1208
-     *                                         EE_Datetime_Field and but the field value is null, then
1209
-     *                                         just null is returned (because that indicates that likely
1210
-     *                                         this field is nullable).
1211
-     * @throws InvalidArgumentException
1212
-     * @throws InvalidDataTypeException
1213
-     * @throws InvalidInterfaceException
1214
-     * @throws ReflectionException
1215
-     */
1216
-    public function get_DateTime_object($field_name)
1217
-    {
1218
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1219
-        if (! $field_settings instanceof EE_Datetime_Field) {
1220
-            EE_Error::add_error(
1221
-                sprintf(
1222
-                    esc_html__(
1223
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1224
-                        'event_espresso'
1225
-                    ),
1226
-                    $field_name
1227
-                ),
1228
-                __FILE__,
1229
-                __FUNCTION__,
1230
-                __LINE__
1231
-            );
1232
-            return false;
1233
-        }
1234
-        return isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime
1235
-            ? clone $this->_fields[ $field_name ]
1236
-            : null;
1237
-    }
1238
-
1239
-
1240
-    /**
1241
-     * To be used in template to immediately echo out the value, and format it for output.
1242
-     * Eg, should call stripslashes and whatnot before echoing
1243
-     *
1244
-     * @param string $field_name      the name of the field as it appears in the DB
1245
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1246
-     *                                (in cases where the same property may be used for different outputs
1247
-     *                                - i.e. datetime, money etc.)
1248
-     * @return void
1249
-     * @throws ReflectionException
1250
-     * @throws InvalidArgumentException
1251
-     * @throws InvalidInterfaceException
1252
-     * @throws InvalidDataTypeException
1253
-     * @throws EE_Error
1254
-     */
1255
-    public function e($field_name, $extra_cache_ref = null)
1256
-    {
1257
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1263
-     * can be easily used as the value of form input.
1264
-     *
1265
-     * @param string $field_name
1266
-     * @return void
1267
-     * @throws ReflectionException
1268
-     * @throws InvalidArgumentException
1269
-     * @throws InvalidInterfaceException
1270
-     * @throws InvalidDataTypeException
1271
-     * @throws EE_Error
1272
-     */
1273
-    public function f($field_name)
1274
-    {
1275
-        $this->e($field_name, 'form_input');
1276
-    }
1277
-
1278
-
1279
-    /**
1280
-     * Same as `f()` but just returns the value instead of echoing it
1281
-     *
1282
-     * @param string $field_name
1283
-     * @return string
1284
-     * @throws ReflectionException
1285
-     * @throws InvalidArgumentException
1286
-     * @throws InvalidInterfaceException
1287
-     * @throws InvalidDataTypeException
1288
-     * @throws EE_Error
1289
-     */
1290
-    public function get_f($field_name)
1291
-    {
1292
-        return (string) $this->get_pretty($field_name, 'form_input');
1293
-    }
1294
-
1295
-
1296
-    /**
1297
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1298
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1299
-     * to see what options are available.
1300
-     *
1301
-     * @param string $field_name
1302
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1303
-     *                                (in cases where the same property may be used for different outputs
1304
-     *                                - i.e. datetime, money etc.)
1305
-     * @return mixed
1306
-     * @throws ReflectionException
1307
-     * @throws InvalidArgumentException
1308
-     * @throws InvalidInterfaceException
1309
-     * @throws InvalidDataTypeException
1310
-     * @throws EE_Error
1311
-     */
1312
-    public function get_pretty($field_name, $extra_cache_ref = null)
1313
-    {
1314
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1315
-    }
1316
-
1317
-
1318
-    /**
1319
-     * This simply returns the datetime for the given field name
1320
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1321
-     * (and the equivalent e_date, e_time, e_datetime).
1322
-     *
1323
-     * @access   protected
1324
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1325
-     * @param string   $dt_frmt      valid datetime format used for date
1326
-     *                               (if '' then we just use the default on the field,
1327
-     *                               if NULL we use the last-used format)
1328
-     * @param string   $tm_frmt      Same as above except this is for time format
1329
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1330
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1331
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1332
-     *                               if field is not a valid dtt field, or void if echoing
1333
-     * @throws ReflectionException
1334
-     * @throws InvalidArgumentException
1335
-     * @throws InvalidInterfaceException
1336
-     * @throws InvalidDataTypeException
1337
-     * @throws EE_Error
1338
-     */
1339
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1340
-    {
1341
-        // clear cached property
1342
-        $this->_clear_cached_property($field_name);
1343
-        // reset format properties because they are used in get()
1344
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1345
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1346
-        if ($echo) {
1347
-            $this->e($field_name, $date_or_time);
1348
-            return '';
1349
-        }
1350
-        return $this->get($field_name, $date_or_time);
1351
-    }
1352
-
1353
-
1354
-    /**
1355
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1356
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1357
-     * other echoes the pretty value for dtt)
1358
-     *
1359
-     * @param  string $field_name name of model object datetime field holding the value
1360
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1361
-     * @return string            datetime value formatted
1362
-     * @throws ReflectionException
1363
-     * @throws InvalidArgumentException
1364
-     * @throws InvalidInterfaceException
1365
-     * @throws InvalidDataTypeException
1366
-     * @throws EE_Error
1367
-     */
1368
-    public function get_date($field_name, $format = '')
1369
-    {
1370
-        return $this->_get_datetime($field_name, $format, null, 'D');
1371
-    }
1372
-
1373
-
1374
-    /**
1375
-     * @param        $field_name
1376
-     * @param string $format
1377
-     * @throws ReflectionException
1378
-     * @throws InvalidArgumentException
1379
-     * @throws InvalidInterfaceException
1380
-     * @throws InvalidDataTypeException
1381
-     * @throws EE_Error
1382
-     */
1383
-    public function e_date($field_name, $format = '')
1384
-    {
1385
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1386
-    }
1387
-
1388
-
1389
-    /**
1390
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1391
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1392
-     * other echoes the pretty value for dtt)
1393
-     *
1394
-     * @param  string $field_name name of model object datetime field holding the value
1395
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1396
-     * @return string             datetime value formatted
1397
-     * @throws ReflectionException
1398
-     * @throws InvalidArgumentException
1399
-     * @throws InvalidInterfaceException
1400
-     * @throws InvalidDataTypeException
1401
-     * @throws EE_Error
1402
-     */
1403
-    public function get_time($field_name, $format = '')
1404
-    {
1405
-        return $this->_get_datetime($field_name, null, $format, 'T');
1406
-    }
1407
-
1408
-
1409
-    /**
1410
-     * @param        $field_name
1411
-     * @param string $format
1412
-     * @throws ReflectionException
1413
-     * @throws InvalidArgumentException
1414
-     * @throws InvalidInterfaceException
1415
-     * @throws InvalidDataTypeException
1416
-     * @throws EE_Error
1417
-     */
1418
-    public function e_time($field_name, $format = '')
1419
-    {
1420
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1426
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1427
-     * other echoes the pretty value for dtt)
1428
-     *
1429
-     * @param  string $field_name name of model object datetime field holding the value
1430
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1431
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1432
-     * @return string             datetime value formatted
1433
-     * @throws ReflectionException
1434
-     * @throws InvalidArgumentException
1435
-     * @throws InvalidInterfaceException
1436
-     * @throws InvalidDataTypeException
1437
-     * @throws EE_Error
1438
-     */
1439
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1440
-    {
1441
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1442
-    }
1443
-
1444
-
1445
-    /**
1446
-     * @param string $field_name
1447
-     * @param string $dt_frmt
1448
-     * @param string $tm_frmt
1449
-     * @throws ReflectionException
1450
-     * @throws InvalidArgumentException
1451
-     * @throws InvalidInterfaceException
1452
-     * @throws InvalidDataTypeException
1453
-     * @throws EE_Error
1454
-     */
1455
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1456
-    {
1457
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1463
-     *
1464
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1465
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1466
-     *                           on the object will be used.
1467
-     * @return string Date and time string in set locale or false if no field exists for the given
1468
-     * @throws ReflectionException
1469
-     * @throws InvalidArgumentException
1470
-     * @throws InvalidInterfaceException
1471
-     * @throws InvalidDataTypeException
1472
-     * @throws EE_Error
1473
-     *                           field name.
1474
-     */
1475
-    public function get_i18n_datetime($field_name, $format = '')
1476
-    {
1477
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1478
-        return date_i18n(
1479
-            $format,
1480
-            EEH_DTT_Helper::get_timestamp_with_offset(
1481
-                $this->get_raw($field_name),
1482
-                $this->_timezone
1483
-            )
1484
-        );
1485
-    }
1486
-
1487
-
1488
-    /**
1489
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1490
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1491
-     * thrown.
1492
-     *
1493
-     * @param  string $field_name The field name being checked
1494
-     * @throws ReflectionException
1495
-     * @throws InvalidArgumentException
1496
-     * @throws InvalidInterfaceException
1497
-     * @throws InvalidDataTypeException
1498
-     * @throws EE_Error
1499
-     * @return EE_Datetime_Field
1500
-     */
1501
-    protected function _get_dtt_field_settings($field_name)
1502
-    {
1503
-        $field = $this->get_model()->field_settings_for($field_name);
1504
-        // check if field is dtt
1505
-        if ($field instanceof EE_Datetime_Field) {
1506
-            return $field;
1507
-        }
1508
-        throw new EE_Error(
1509
-            sprintf(
1510
-                esc_html__(
1511
-                    'The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1512
-                    'event_espresso'
1513
-                ),
1514
-                $field_name,
1515
-                self::_get_model_classname(get_class($this))
1516
-            )
1517
-        );
1518
-    }
1519
-
1520
-
1521
-
1522
-
1523
-    /**
1524
-     * NOTE ABOUT BELOW:
1525
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1526
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1527
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1528
-     * method and make sure you send the entire datetime value for setting.
1529
-     */
1530
-    /**
1531
-     * sets the time on a datetime property
1532
-     *
1533
-     * @access protected
1534
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1535
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1536
-     * @throws ReflectionException
1537
-     * @throws InvalidArgumentException
1538
-     * @throws InvalidInterfaceException
1539
-     * @throws InvalidDataTypeException
1540
-     * @throws EE_Error
1541
-     */
1542
-    protected function _set_time_for($time, $fieldname)
1543
-    {
1544
-        $this->_set_date_time('T', $time, $fieldname);
1545
-    }
1546
-
1547
-
1548
-    /**
1549
-     * sets the date on a datetime property
1550
-     *
1551
-     * @access protected
1552
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1553
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1554
-     * @throws ReflectionException
1555
-     * @throws InvalidArgumentException
1556
-     * @throws InvalidInterfaceException
1557
-     * @throws InvalidDataTypeException
1558
-     * @throws EE_Error
1559
-     */
1560
-    protected function _set_date_for($date, $fieldname)
1561
-    {
1562
-        $this->_set_date_time('D', $date, $fieldname);
1563
-    }
1564
-
1565
-
1566
-    /**
1567
-     * This takes care of setting a date or time independently on a given model object property. This method also
1568
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1569
-     *
1570
-     * @access protected
1571
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1572
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1573
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1574
-     *                                        EE_Datetime_Field property)
1575
-     * @throws ReflectionException
1576
-     * @throws InvalidArgumentException
1577
-     * @throws InvalidInterfaceException
1578
-     * @throws InvalidDataTypeException
1579
-     * @throws EE_Error
1580
-     */
1581
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1582
-    {
1583
-        $field = $this->_get_dtt_field_settings($fieldname);
1584
-        $field->set_timezone($this->_timezone);
1585
-        $field->set_date_format($this->_dt_frmt);
1586
-        $field->set_time_format($this->_tm_frmt);
1587
-        switch ($what) {
1588
-            case 'T':
1589
-                $this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_time(
1590
-                    $datetime_value,
1591
-                    $this->_fields[ $fieldname ]
1592
-                );
1593
-                $this->_has_changes = true;
1594
-                break;
1595
-            case 'D':
1596
-                $this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_date(
1597
-                    $datetime_value,
1598
-                    $this->_fields[ $fieldname ]
1599
-                );
1600
-                $this->_has_changes = true;
1601
-                break;
1602
-            case 'B':
1603
-                $this->_fields[ $fieldname ] = $field->prepare_for_set($datetime_value);
1604
-                $this->_has_changes = true;
1605
-                break;
1606
-        }
1607
-        $this->_clear_cached_property($fieldname);
1608
-    }
1609
-
1610
-
1611
-    /**
1612
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1613
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1614
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1615
-     * that could lead to some unexpected results!
1616
-     *
1617
-     * @access public
1618
-     * @param string $field_name               This is the name of the field on the object that contains the date/time
1619
-     *                                         value being returned.
1620
-     * @param string $callback                 must match a valid method in this class (defaults to get_datetime)
1621
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1622
-     * @param string $prepend                  You can include something to prepend on the timestamp
1623
-     * @param string $append                   You can include something to append on the timestamp
1624
-     * @throws ReflectionException
1625
-     * @throws InvalidArgumentException
1626
-     * @throws InvalidInterfaceException
1627
-     * @throws InvalidDataTypeException
1628
-     * @throws EE_Error
1629
-     * @return string timestamp
1630
-     */
1631
-    public function display_in_my_timezone(
1632
-        $field_name,
1633
-        $callback = 'get_datetime',
1634
-        $args = null,
1635
-        $prepend = '',
1636
-        $append = ''
1637
-    ) {
1638
-        $timezone = EEH_DTT_Helper::get_timezone();
1639
-        if ($timezone === $this->_timezone) {
1640
-            return '';
1641
-        }
1642
-        $original_timezone = $this->_timezone;
1643
-        $this->set_timezone($timezone);
1644
-        $fn = (array) $field_name;
1645
-        $args = array_merge($fn, (array) $args);
1646
-        if (! method_exists($this, $callback)) {
1647
-            throw new EE_Error(
1648
-                sprintf(
1649
-                    esc_html__(
1650
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1651
-                        'event_espresso'
1652
-                    ),
1653
-                    $callback
1654
-                )
1655
-            );
1656
-        }
1657
-        $args = (array) $args;
1658
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1659
-        $this->set_timezone($original_timezone);
1660
-        return $return;
1661
-    }
1662
-
1663
-
1664
-    /**
1665
-     * Deletes this model object.
1666
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1667
-     * override
1668
-     * `EE_Base_Class::_delete` NOT this class.
1669
-     *
1670
-     * @return boolean | int
1671
-     * @throws ReflectionException
1672
-     * @throws InvalidArgumentException
1673
-     * @throws InvalidInterfaceException
1674
-     * @throws InvalidDataTypeException
1675
-     * @throws EE_Error
1676
-     */
1677
-    public function delete()
1678
-    {
1679
-        /**
1680
-         * Called just before the `EE_Base_Class::_delete` method call.
1681
-         * Note:
1682
-         * `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1683
-         * should be aware that `_delete` may not always result in a permanent delete.
1684
-         * For example, `EE_Soft_Delete_Base_Class::_delete`
1685
-         * soft deletes (trash) the object and does not permanently delete it.
1686
-         *
1687
-         * @param EE_Base_Class $model_object about to be 'deleted'
1688
-         */
1689
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1690
-        $result = $this->_delete();
1691
-        /**
1692
-         * Called just after the `EE_Base_Class::_delete` method call.
1693
-         * Note:
1694
-         * `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1695
-         * should be aware that `_delete` may not always result in a permanent delete.
1696
-         * For example `EE_Soft_Base_Class::_delete`
1697
-         * soft deletes (trash) the object and does not permanently delete it.
1698
-         *
1699
-         * @param EE_Base_Class $model_object that was just 'deleted'
1700
-         * @param boolean       $result
1701
-         */
1702
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1703
-        return $result;
1704
-    }
1705
-
1706
-
1707
-    /**
1708
-     * Calls the specific delete method for the instantiated class.
1709
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1710
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1711
-     * `EE_Base_Class::delete`
1712
-     *
1713
-     * @return bool|int
1714
-     * @throws ReflectionException
1715
-     * @throws InvalidArgumentException
1716
-     * @throws InvalidInterfaceException
1717
-     * @throws InvalidDataTypeException
1718
-     * @throws EE_Error
1719
-     */
1720
-    protected function _delete()
1721
-    {
1722
-        return $this->delete_permanently();
1723
-    }
1724
-
1725
-
1726
-    /**
1727
-     * Deletes this model object permanently from db
1728
-     * (but keep in mind related models may block the delete and return an error)
1729
-     *
1730
-     * @return bool | int
1731
-     * @throws ReflectionException
1732
-     * @throws InvalidArgumentException
1733
-     * @throws InvalidInterfaceException
1734
-     * @throws InvalidDataTypeException
1735
-     * @throws EE_Error
1736
-     */
1737
-    public function delete_permanently()
1738
-    {
1739
-        /**
1740
-         * Called just before HARD deleting a model object
1741
-         *
1742
-         * @param EE_Base_Class $model_object about to be 'deleted'
1743
-         */
1744
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1745
-        $model = $this->get_model();
1746
-        $result = $model->delete_permanently_by_ID($this->ID());
1747
-        $this->refresh_cache_of_related_objects();
1748
-        /**
1749
-         * Called just after HARD deleting a model object
1750
-         *
1751
-         * @param EE_Base_Class $model_object that was just 'deleted'
1752
-         * @param boolean       $result
1753
-         */
1754
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1755
-        return $result;
1756
-    }
1757
-
1758
-
1759
-    /**
1760
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1761
-     * related model objects
1762
-     *
1763
-     * @throws ReflectionException
1764
-     * @throws InvalidArgumentException
1765
-     * @throws InvalidInterfaceException
1766
-     * @throws InvalidDataTypeException
1767
-     * @throws EE_Error
1768
-     */
1769
-    public function refresh_cache_of_related_objects()
1770
-    {
1771
-        $model = $this->get_model();
1772
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1773
-            if (! empty($this->_model_relations[ $relation_name ])) {
1774
-                $related_objects = $this->_model_relations[ $relation_name ];
1775
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1776
-                    // this relation only stores a single model object, not an array
1777
-                    // but let's make it consistent
1778
-                    $related_objects = array($related_objects);
1779
-                }
1780
-                foreach ($related_objects as $related_object) {
1781
-                    // only refresh their cache if they're in memory
1782
-                    if ($related_object instanceof EE_Base_Class) {
1783
-                        $related_object->clear_cache(
1784
-                            $model->get_this_model_name(),
1785
-                            $this
1786
-                        );
1787
-                    }
1788
-                }
1789
-            }
1790
-        }
1791
-    }
1792
-
1793
-
1794
-    /**
1795
-     *        Saves this object to the database. An array may be supplied to set some values on this
1796
-     * object just before saving.
1797
-     *
1798
-     * @access public
1799
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1800
-     *                                 if provided during the save() method (often client code will change the fields'
1801
-     *                                 values before calling save)
1802
-     * @return bool|int|string         1 on a successful update
1803
-     *                                 the ID of the new entry on insert
1804
-     *                                 0 on failure or if the model object isn't allowed to persist
1805
-     *                                 (as determined by EE_Base_Class::allow_persist())
1806
-     * @throws InvalidInterfaceException
1807
-     * @throws InvalidDataTypeException
1808
-     * @throws EE_Error
1809
-     * @throws InvalidArgumentException
1810
-     * @throws ReflectionException
1811
-     * @throws ReflectionException
1812
-     * @throws ReflectionException
1813
-     */
1814
-    public function save($set_cols_n_values = array())
1815
-    {
1816
-        $model = $this->get_model();
1817
-        /**
1818
-         * Filters the fields we're about to save on the model object
1819
-         *
1820
-         * @param array         $set_cols_n_values
1821
-         * @param EE_Base_Class $model_object
1822
-         */
1823
-        $set_cols_n_values = (array) apply_filters(
1824
-            'FHEE__EE_Base_Class__save__set_cols_n_values',
1825
-            $set_cols_n_values,
1826
-            $this
1827
-        );
1828
-        // set attributes as provided in $set_cols_n_values
1829
-        foreach ($set_cols_n_values as $column => $value) {
1830
-            $this->set($column, $value);
1831
-        }
1832
-        // no changes ? then don't do anything
1833
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1834
-            return 0;
1835
-        }
1836
-        /**
1837
-         * Saving a model object.
1838
-         * Before we perform a save, this action is fired.
1839
-         *
1840
-         * @param EE_Base_Class $model_object the model object about to be saved.
1841
-         */
1842
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1843
-        if (! $this->allow_persist()) {
1844
-            return 0;
1845
-        }
1846
-        // now get current attribute values
1847
-        $save_cols_n_values = $this->_fields;
1848
-        // if the object already has an ID, update it. Otherwise, insert it
1849
-        // also: change the assumption about values passed to the model NOT being prepare dby the model object.
1850
-        // They have been
1851
-        $old_assumption_concerning_value_preparation = $model
1852
-            ->get_assumption_concerning_values_already_prepared_by_model_object();
1853
-        $model->assume_values_already_prepared_by_model_object(true);
1854
-        // does this model have an autoincrement PK?
1855
-        if ($model->has_primary_key_field()) {
1856
-            if ($model->get_primary_key_field()->is_auto_increment()) {
1857
-                // ok check if it's set, if so: update; if not, insert
1858
-                if (! empty($save_cols_n_values[ $model->primary_key_name() ])) {
1859
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1860
-                } else {
1861
-                    unset($save_cols_n_values[ $model->primary_key_name() ]);
1862
-                    $results = $model->insert($save_cols_n_values);
1863
-                    if ($results) {
1864
-                        // if successful, set the primary key
1865
-                        // but don't use the normal SET method, because it will check if
1866
-                        // an item with the same ID exists in the mapper & db, then
1867
-                        // will find it in the db (because we just added it) and THAT object
1868
-                        // will get added to the mapper before we can add this one!
1869
-                        // but if we just avoid using the SET method, all that headache can be avoided
1870
-                        $pk_field_name = $model->primary_key_name();
1871
-                        $this->_fields[ $pk_field_name ] = $results;
1872
-                        $this->_clear_cached_property($pk_field_name);
1873
-                        $model->add_to_entity_map($this);
1874
-                        $this->_update_cached_related_model_objs_fks();
1875
-                    }
1876
-                }
1877
-            } else {// PK is NOT auto-increment
1878
-                // so check if one like it already exists in the db
1879
-                if ($model->exists_by_ID($this->ID())) {
1880
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1881
-                        throw new EE_Error(
1882
-                            sprintf(
1883
-                                esc_html__(
1884
-                                    'Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1885
-                                    'event_espresso'
1886
-                                ),
1887
-                                get_class($this),
1888
-                                get_class($model) . '::instance()->add_to_entity_map()',
1889
-                                get_class($model) . '::instance()->get_one_by_ID()',
1890
-                                '<br />'
1891
-                            )
1892
-                        );
1893
-                    }
1894
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1895
-                } else {
1896
-                    $results = $model->insert($save_cols_n_values);
1897
-                    $this->_update_cached_related_model_objs_fks();
1898
-                }
1899
-            }
1900
-        } else {// there is NO primary key
1901
-            $already_in_db = false;
1902
-            foreach ($model->unique_indexes() as $index) {
1903
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1904
-                if ($model->exists(array($uniqueness_where_params))) {
1905
-                    $already_in_db = true;
1906
-                }
1907
-            }
1908
-            if ($already_in_db) {
1909
-                $combined_pk_fields_n_values = array_intersect_key(
1910
-                    $save_cols_n_values,
1911
-                    $model->get_combined_primary_key_fields()
1912
-                );
1913
-                $results = $model->update(
1914
-                    $save_cols_n_values,
1915
-                    $combined_pk_fields_n_values
1916
-                );
1917
-            } else {
1918
-                $results = $model->insert($save_cols_n_values);
1919
-            }
1920
-        }
1921
-        // restore the old assumption about values being prepared by the model object
1922
-        $model->assume_values_already_prepared_by_model_object(
1923
-            $old_assumption_concerning_value_preparation
1924
-        );
1925
-        /**
1926
-         * After saving the model object this action is called
1927
-         *
1928
-         * @param EE_Base_Class $model_object which was just saved
1929
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1930
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1931
-         */
1932
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1933
-        $this->_has_changes = false;
1934
-        return $results;
1935
-    }
1936
-
1937
-
1938
-    /**
1939
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1940
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1941
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1942
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1943
-     * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1944
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1945
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1946
-     *
1947
-     * @return void
1948
-     * @throws ReflectionException
1949
-     * @throws InvalidArgumentException
1950
-     * @throws InvalidInterfaceException
1951
-     * @throws InvalidDataTypeException
1952
-     * @throws EE_Error
1953
-     */
1954
-    protected function _update_cached_related_model_objs_fks()
1955
-    {
1956
-        $model = $this->get_model();
1957
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1958
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1959
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1960
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1961
-                        $model->get_this_model_name()
1962
-                    );
1963
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1964
-                    if ($related_model_obj_in_cache->ID()) {
1965
-                        $related_model_obj_in_cache->save();
1966
-                    }
1967
-                }
1968
-            }
1969
-        }
1970
-    }
1971
-
1972
-
1973
-    /**
1974
-     * Saves this model object and its NEW cached relations to the database.
1975
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1976
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1977
-     * because otherwise, there's a potential for infinite looping of saving
1978
-     * Saves the cached related model objects, and ensures the relation between them
1979
-     * and this object and properly setup
1980
-     *
1981
-     * @return int ID of new model object on save; 0 on failure+
1982
-     * @throws ReflectionException
1983
-     * @throws InvalidArgumentException
1984
-     * @throws InvalidInterfaceException
1985
-     * @throws InvalidDataTypeException
1986
-     * @throws EE_Error
1987
-     */
1988
-    public function save_new_cached_related_model_objs()
1989
-    {
1990
-        // make sure this has been saved
1991
-        if (! $this->ID()) {
1992
-            $id = $this->save();
1993
-        } else {
1994
-            $id = $this->ID();
1995
-        }
1996
-        // now save all the NEW cached model objects  (ie they don't exist in the DB)
1997
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1998
-            if ($this->_model_relations[ $relationName ]) {
1999
-                // is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
2000
-                // or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
2001
-                /* @var $related_model_obj EE_Base_Class */
2002
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
2003
-                    // add a relation to that relation type (which saves the appropriate thing in the process)
2004
-                    // but ONLY if it DOES NOT exist in the DB
2005
-                    $related_model_obj = $this->_model_relations[ $relationName ];
2006
-                    // if( ! $related_model_obj->ID()){
2007
-                    $this->_add_relation_to($related_model_obj, $relationName);
2008
-                    $related_model_obj->save_new_cached_related_model_objs();
2009
-                    // }
2010
-                } else {
2011
-                    foreach ($this->_model_relations[ $relationName ] as $related_model_obj) {
2012
-                        // add a relation to that relation type (which saves the appropriate thing in the process)
2013
-                        // but ONLY if it DOES NOT exist in the DB
2014
-                        // if( ! $related_model_obj->ID()){
2015
-                        $this->_add_relation_to($related_model_obj, $relationName);
2016
-                        $related_model_obj->save_new_cached_related_model_objs();
2017
-                        // }
2018
-                    }
2019
-                }
2020
-            }
2021
-        }
2022
-        return $id;
2023
-    }
2024
-
2025
-
2026
-    /**
2027
-     * for getting a model while instantiated.
2028
-     *
2029
-     * @return EEM_Base | EEM_CPT_Base
2030
-     * @throws ReflectionException
2031
-     * @throws InvalidArgumentException
2032
-     * @throws InvalidInterfaceException
2033
-     * @throws InvalidDataTypeException
2034
-     * @throws EE_Error
2035
-     */
2036
-    public function get_model()
2037
-    {
2038
-        if (! $this->_model) {
2039
-            $modelName = self::_get_model_classname(get_class($this));
2040
-            $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
2041
-        } else {
2042
-            $this->_model->set_timezone($this->_timezone);
2043
-        }
2044
-        return $this->_model;
2045
-    }
2046
-
2047
-
2048
-    /**
2049
-     * @param $props_n_values
2050
-     * @param $classname
2051
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
2052
-     * @throws ReflectionException
2053
-     * @throws InvalidArgumentException
2054
-     * @throws InvalidInterfaceException
2055
-     * @throws InvalidDataTypeException
2056
-     * @throws EE_Error
2057
-     */
2058
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
2059
-    {
2060
-        // TODO: will not work for Term_Relationships because they have no PK!
2061
-        $primary_id_ref = self::_get_primary_key_name($classname);
2062
-        if (
2063
-            array_key_exists($primary_id_ref, $props_n_values)
2064
-            && ! empty($props_n_values[ $primary_id_ref ])
2065
-        ) {
2066
-            $id = $props_n_values[ $primary_id_ref ];
2067
-            return self::_get_model($classname)->get_from_entity_map($id);
2068
-        }
2069
-        return false;
2070
-    }
2071
-
2072
-
2073
-    /**
2074
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
2075
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
2076
-     * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
2077
-     * we return false.
2078
-     *
2079
-     * @param  array  $props_n_values   incoming array of properties and their values
2080
-     * @param  string $classname        the classname of the child class
2081
-     * @param null    $timezone
2082
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
2083
-     *                                  date_format and the second value is the time format
2084
-     * @return mixed (EE_Base_Class|bool)
2085
-     * @throws InvalidArgumentException
2086
-     * @throws InvalidInterfaceException
2087
-     * @throws InvalidDataTypeException
2088
-     * @throws EE_Error
2089
-     * @throws ReflectionException
2090
-     * @throws ReflectionException
2091
-     * @throws ReflectionException
2092
-     */
2093
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
2094
-    {
2095
-        $existing = null;
2096
-        $model = self::_get_model($classname, $timezone);
2097
-        if ($model->has_primary_key_field()) {
2098
-            $primary_id_ref = self::_get_primary_key_name($classname);
2099
-            if (
2100
-                array_key_exists($primary_id_ref, $props_n_values)
2101
-                && ! empty($props_n_values[ $primary_id_ref ])
2102
-            ) {
2103
-                $existing = $model->get_one_by_ID(
2104
-                    $props_n_values[ $primary_id_ref ]
2105
-                );
2106
-            }
2107
-        } elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
2108
-            // no primary key on this model, but there's still a matching item in the DB
2109
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
2110
-                self::_get_model($classname, $timezone)
2111
-                    ->get_index_primary_key_string($props_n_values)
2112
-            );
2113
-        }
2114
-        if ($existing) {
2115
-            // set date formats if present before setting values
2116
-            if (! empty($date_formats) && is_array($date_formats)) {
2117
-                $existing->set_date_format($date_formats[0]);
2118
-                $existing->set_time_format($date_formats[1]);
2119
-            } else {
2120
-                // set default formats for date and time
2121
-                $existing->set_date_format(get_option('date_format'));
2122
-                $existing->set_time_format(get_option('time_format'));
2123
-            }
2124
-            foreach ($props_n_values as $property => $field_value) {
2125
-                $existing->set($property, $field_value);
2126
-            }
2127
-            return $existing;
2128
-        }
2129
-        return false;
2130
-    }
2131
-
2132
-
2133
-    /**
2134
-     * Gets the EEM_*_Model for this class
2135
-     *
2136
-     * @access public now, as this is more convenient
2137
-     * @param      $classname
2138
-     * @param null $timezone
2139
-     * @throws ReflectionException
2140
-     * @throws InvalidArgumentException
2141
-     * @throws InvalidInterfaceException
2142
-     * @throws InvalidDataTypeException
2143
-     * @throws EE_Error
2144
-     * @return EEM_Base
2145
-     */
2146
-    protected static function _get_model($classname, $timezone = null)
2147
-    {
2148
-        // find model for this class
2149
-        if (! $classname) {
2150
-            throw new EE_Error(
2151
-                sprintf(
2152
-                    esc_html__(
2153
-                        'What were you thinking calling _get_model(%s)?? You need to specify the class name',
2154
-                        'event_espresso'
2155
-                    ),
2156
-                    $classname
2157
-                )
2158
-            );
2159
-        }
2160
-        $modelName = self::_get_model_classname($classname);
2161
-        return self::_get_model_instance_with_name($modelName, $timezone);
2162
-    }
2163
-
2164
-
2165
-    /**
2166
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
2167
-     *
2168
-     * @param string $model_classname
2169
-     * @param null   $timezone
2170
-     * @return EEM_Base
2171
-     * @throws ReflectionException
2172
-     * @throws InvalidArgumentException
2173
-     * @throws InvalidInterfaceException
2174
-     * @throws InvalidDataTypeException
2175
-     * @throws EE_Error
2176
-     */
2177
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
2178
-    {
2179
-        $model_classname = str_replace('EEM_', '', $model_classname);
2180
-        $model = EE_Registry::instance()->load_model($model_classname);
2181
-        $model->set_timezone($timezone);
2182
-        return $model;
2183
-    }
2184
-
2185
-
2186
-    /**
2187
-     * If a model name is provided (eg Registration), gets the model classname for that model.
2188
-     * Also works if a model class's classname is provided (eg EE_Registration).
2189
-     *
2190
-     * @param null $model_name
2191
-     * @return string like EEM_Attendee
2192
-     */
2193
-    private static function _get_model_classname($model_name = null)
2194
-    {
2195
-        if (strpos($model_name, 'EE_') === 0) {
2196
-            $model_classname = str_replace('EE_', 'EEM_', $model_name);
2197
-        } else {
2198
-            $model_classname = 'EEM_' . $model_name;
2199
-        }
2200
-        return $model_classname;
2201
-    }
2202
-
2203
-
2204
-    /**
2205
-     * returns the name of the primary key attribute
2206
-     *
2207
-     * @param null $classname
2208
-     * @throws ReflectionException
2209
-     * @throws InvalidArgumentException
2210
-     * @throws InvalidInterfaceException
2211
-     * @throws InvalidDataTypeException
2212
-     * @throws EE_Error
2213
-     * @return string
2214
-     */
2215
-    protected static function _get_primary_key_name($classname = null)
2216
-    {
2217
-        if (! $classname) {
2218
-            throw new EE_Error(
2219
-                sprintf(
2220
-                    esc_html__('What were you thinking calling _get_primary_key_name(%s)', 'event_espresso'),
2221
-                    $classname
2222
-                )
2223
-            );
2224
-        }
2225
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
2226
-    }
2227
-
2228
-
2229
-    /**
2230
-     * Gets the value of the primary key.
2231
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
2232
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2233
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2234
-     *
2235
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2236
-     * @throws ReflectionException
2237
-     * @throws InvalidArgumentException
2238
-     * @throws InvalidInterfaceException
2239
-     * @throws InvalidDataTypeException
2240
-     * @throws EE_Error
2241
-     */
2242
-    public function ID()
2243
-    {
2244
-        $model = $this->get_model();
2245
-        // now that we know the name of the variable, use a variable variable to get its value and return its
2246
-        if ($model->has_primary_key_field()) {
2247
-            return $this->_fields[ $model->primary_key_name() ];
2248
-        }
2249
-        return $model->get_index_primary_key_string($this->_fields);
2250
-    }
2251
-
2252
-
2253
-    /**
2254
-     * @param EE_Base_Class|int|string $otherModelObjectOrID
2255
-     * @param string                   $relationName
2256
-     * @return bool
2257
-     * @throws EE_Error
2258
-     * @throws ReflectionException
2259
-     * @since   $VID:$
2260
-     */
2261
-    public function hasRelation($otherModelObjectOrID, string $relationName): bool
2262
-    {
2263
-        $other_model = self::_get_model_instance_with_name(
2264
-            self::_get_model_classname($relationName),
2265
-            $this->_timezone
2266
-        );
2267
-        $primary_key = $other_model->primary_key_name();
2268
-        /** @var EE_Base_Class $otherModelObject */
2269
-        $otherModelObject = $other_model->ensure_is_obj($otherModelObjectOrID, $relationName);
2270
-        return $this->count_related($relationName, [[$primary_key => $otherModelObject->ID()]]) > 0;
2271
-    }
2272
-
2273
-
2274
-    /**
2275
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2276
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2277
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2278
-     *
2279
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2280
-     * @param string $relationName                     eg 'Events','Question',etc.
2281
-     *                                                 an attendee to a group, you also want to specify which role they
2282
-     *                                                 will have in that group. So you would use this parameter to
2283
-     *                                                 specify array('role-column-name'=>'role-id')
2284
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2285
-     *                                                 allow you to further constrict the relation to being added.
2286
-     *                                                 However, keep in mind that the columns (keys) given must match a
2287
-     *                                                 column on the JOIN table and currently only the HABTM models
2288
-     *                                                 accept these additional conditions.  Also remember that if an
2289
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
2290
-     *                                                 NEW row is created in the join table.
2291
-     * @param null   $cache_id
2292
-     * @throws ReflectionException
2293
-     * @throws InvalidArgumentException
2294
-     * @throws InvalidInterfaceException
2295
-     * @throws InvalidDataTypeException
2296
-     * @throws EE_Error
2297
-     * @return EE_Base_Class the object the relation was added to
2298
-     */
2299
-    public function _add_relation_to(
2300
-        $otherObjectModelObjectOrID,
2301
-        $relationName,
2302
-        $extra_join_model_fields_n_values = array(),
2303
-        $cache_id = null
2304
-    ) {
2305
-        $model = $this->get_model();
2306
-        // if this thing exists in the DB, save the relation to the DB
2307
-        if ($this->ID()) {
2308
-            $otherObject = $model->add_relationship_to(
2309
-                $this,
2310
-                $otherObjectModelObjectOrID,
2311
-                $relationName,
2312
-                $extra_join_model_fields_n_values
2313
-            );
2314
-            // clear cache so future get_many_related and get_first_related() return new results.
2315
-            $this->clear_cache($relationName, $otherObject, true);
2316
-            if ($otherObject instanceof EE_Base_Class) {
2317
-                $otherObject->clear_cache($model->get_this_model_name(), $this);
2318
-            }
2319
-        } else {
2320
-            // this thing doesn't exist in the DB,  so just cache it
2321
-            if (! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2322
-                throw new EE_Error(
2323
-                    sprintf(
2324
-                        esc_html__(
2325
-                            'Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2326
-                            'event_espresso'
2327
-                        ),
2328
-                        $otherObjectModelObjectOrID,
2329
-                        get_class($this)
2330
-                    )
2331
-                );
2332
-            }
2333
-            $otherObject = $otherObjectModelObjectOrID;
2334
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2335
-        }
2336
-        if ($otherObject instanceof EE_Base_Class) {
2337
-            // fix the reciprocal relation too
2338
-            if ($otherObject->ID()) {
2339
-                // its saved so assumed relations exist in the DB, so we can just
2340
-                // clear the cache so future queries use the updated info in the DB
2341
-                $otherObject->clear_cache(
2342
-                    $model->get_this_model_name(),
2343
-                    null,
2344
-                    true
2345
-                );
2346
-            } else {
2347
-                // it's not saved, so it caches relations like this
2348
-                $otherObject->cache($model->get_this_model_name(), $this);
2349
-            }
2350
-        }
2351
-        return $otherObject;
2352
-    }
2353
-
2354
-
2355
-    /**
2356
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2357
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2358
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2359
-     * from the cache
2360
-     *
2361
-     * @param mixed  $otherObjectModelObjectOrID
2362
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2363
-     *                to the DB yet
2364
-     * @param string $relationName
2365
-     * @param array  $where_query
2366
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2367
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2368
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2369
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then no row is
2370
-     *                deleted.
2371
-     * @return EE_Base_Class the relation was removed from
2372
-     * @throws ReflectionException
2373
-     * @throws InvalidArgumentException
2374
-     * @throws InvalidInterfaceException
2375
-     * @throws InvalidDataTypeException
2376
-     * @throws EE_Error
2377
-     */
2378
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2379
-    {
2380
-        if ($this->ID()) {
2381
-            // if this exists in the DB, save the relation change to the DB too
2382
-            $otherObject = $this->get_model()->remove_relationship_to(
2383
-                $this,
2384
-                $otherObjectModelObjectOrID,
2385
-                $relationName,
2386
-                $where_query
2387
-            );
2388
-            $this->clear_cache(
2389
-                $relationName,
2390
-                $otherObject
2391
-            );
2392
-        } else {
2393
-            // this doesn't exist in the DB, just remove it from the cache
2394
-            $otherObject = $this->clear_cache(
2395
-                $relationName,
2396
-                $otherObjectModelObjectOrID
2397
-            );
2398
-        }
2399
-        if ($otherObject instanceof EE_Base_Class) {
2400
-            $otherObject->clear_cache(
2401
-                $this->get_model()->get_this_model_name(),
2402
-                $this
2403
-            );
2404
-        }
2405
-        return $otherObject;
2406
-    }
2407
-
2408
-
2409
-    /**
2410
-     * Removes ALL the related things for the $relationName.
2411
-     *
2412
-     * @param string $relationName
2413
-     * @param array  $where_query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
2414
-     * @return EE_Base_Class
2415
-     * @throws ReflectionException
2416
-     * @throws InvalidArgumentException
2417
-     * @throws InvalidInterfaceException
2418
-     * @throws InvalidDataTypeException
2419
-     * @throws EE_Error
2420
-     */
2421
-    public function _remove_relations($relationName, $where_query_params = array())
2422
-    {
2423
-        if ($this->ID()) {
2424
-            // if this exists in the DB, save the relation change to the DB too
2425
-            $otherObjects = $this->get_model()->remove_relations(
2426
-                $this,
2427
-                $relationName,
2428
-                $where_query_params
2429
-            );
2430
-            $this->clear_cache(
2431
-                $relationName,
2432
-                null,
2433
-                true
2434
-            );
2435
-        } else {
2436
-            // this doesn't exist in the DB, just remove it from the cache
2437
-            $otherObjects = $this->clear_cache(
2438
-                $relationName,
2439
-                null,
2440
-                true
2441
-            );
2442
-        }
2443
-        if (is_array($otherObjects)) {
2444
-            foreach ($otherObjects as $otherObject) {
2445
-                $otherObject->clear_cache(
2446
-                    $this->get_model()->get_this_model_name(),
2447
-                    $this
2448
-                );
2449
-            }
2450
-        }
2451
-        return $otherObjects;
2452
-    }
2453
-
2454
-
2455
-    /**
2456
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2457
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2458
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2459
-     * because we want to get even deleted items etc.
2460
-     *
2461
-     * @param string $relationName key in the model's _model_relations array
2462
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
2463
-     * @return EE_Base_Class[]     Results not necessarily indexed by IDs, because some results might not have primary
2464
-     *                             keys or might not be saved yet. Consider using EEM_Base::get_IDs() on these
2465
-     *                             results if you want IDs
2466
-     * @throws ReflectionException
2467
-     * @throws InvalidArgumentException
2468
-     * @throws InvalidInterfaceException
2469
-     * @throws InvalidDataTypeException
2470
-     * @throws EE_Error
2471
-     */
2472
-    public function get_many_related($relationName, $query_params = array())
2473
-    {
2474
-        if ($this->ID()) {
2475
-            // this exists in the DB, so get the related things from either the cache or the DB
2476
-            // if there are query parameters, forget about caching the related model objects.
2477
-            if ($query_params) {
2478
-                $related_model_objects = $this->get_model()->get_all_related(
2479
-                    $this,
2480
-                    $relationName,
2481
-                    $query_params
2482
-                );
2483
-            } else {
2484
-                // did we already cache the result of this query?
2485
-                $cached_results = $this->get_all_from_cache($relationName);
2486
-                if (! $cached_results) {
2487
-                    $related_model_objects = $this->get_model()->get_all_related(
2488
-                        $this,
2489
-                        $relationName,
2490
-                        $query_params
2491
-                    );
2492
-                    // if no query parameters were passed, then we got all the related model objects
2493
-                    // for that relation. We can cache them then.
2494
-                    foreach ($related_model_objects as $related_model_object) {
2495
-                        $this->cache($relationName, $related_model_object);
2496
-                    }
2497
-                } else {
2498
-                    $related_model_objects = $cached_results;
2499
-                }
2500
-            }
2501
-        } else {
2502
-            // this doesn't exist in the DB, so just get the related things from the cache
2503
-            $related_model_objects = $this->get_all_from_cache($relationName);
2504
-        }
2505
-        return $related_model_objects;
2506
-    }
2507
-
2508
-
2509
-    /**
2510
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2511
-     * unless otherwise specified in the $query_params
2512
-     *
2513
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2514
-     * @param array  $query_params   @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2515
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2516
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2517
-     *                               that by the setting $distinct to TRUE;
2518
-     * @return int
2519
-     * @throws ReflectionException
2520
-     * @throws InvalidArgumentException
2521
-     * @throws InvalidInterfaceException
2522
-     * @throws InvalidDataTypeException
2523
-     * @throws EE_Error
2524
-     */
2525
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2526
-    {
2527
-        return $this->get_model()->count_related(
2528
-            $this,
2529
-            $relation_name,
2530
-            $query_params,
2531
-            $field_to_count,
2532
-            $distinct
2533
-        );
2534
-    }
2535
-
2536
-
2537
-    /**
2538
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2539
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2540
-     *
2541
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2542
-     * @param array  $query_params  @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2543
-     * @param string $field_to_sum  name of field to count by.
2544
-     *                              By default, uses primary key
2545
-     *                              (which doesn't make much sense, so you should probably change it)
2546
-     * @return int
2547
-     * @throws ReflectionException
2548
-     * @throws InvalidArgumentException
2549
-     * @throws InvalidInterfaceException
2550
-     * @throws InvalidDataTypeException
2551
-     * @throws EE_Error
2552
-     */
2553
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2554
-    {
2555
-        return $this->get_model()->sum_related(
2556
-            $this,
2557
-            $relation_name,
2558
-            $query_params,
2559
-            $field_to_sum
2560
-        );
2561
-    }
2562
-
2563
-
2564
-    /**
2565
-     * Gets the first (ie, one) related model object of the specified type.
2566
-     *
2567
-     * @param string $relationName key in the model's _model_relations array
2568
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2569
-     * @return EE_Base_Class (not an array, a single object)
2570
-     * @throws ReflectionException
2571
-     * @throws InvalidArgumentException
2572
-     * @throws InvalidInterfaceException
2573
-     * @throws InvalidDataTypeException
2574
-     * @throws EE_Error
2575
-     */
2576
-    public function get_first_related($relationName, $query_params = array())
2577
-    {
2578
-        $model = $this->get_model();
2579
-        if ($this->ID()) {// this exists in the DB, get from the cache OR the DB
2580
-            // if they've provided some query parameters, don't bother trying to cache the result
2581
-            // also make sure we're not caching the result of get_first_related
2582
-            // on a relation which should have an array of objects (because the cache might have an array of objects)
2583
-            if (
2584
-                $query_params
2585
-                || ! $model->related_settings_for($relationName)
2586
-                     instanceof
2587
-                     EE_Belongs_To_Relation
2588
-            ) {
2589
-                $related_model_object = $model->get_first_related(
2590
-                    $this,
2591
-                    $relationName,
2592
-                    $query_params
2593
-                );
2594
-            } else {
2595
-                // first, check if we've already cached the result of this query
2596
-                $cached_result = $this->get_one_from_cache($relationName);
2597
-                if (! $cached_result) {
2598
-                    $related_model_object = $model->get_first_related(
2599
-                        $this,
2600
-                        $relationName,
2601
-                        $query_params
2602
-                    );
2603
-                    $this->cache($relationName, $related_model_object);
2604
-                } else {
2605
-                    $related_model_object = $cached_result;
2606
-                }
2607
-            }
2608
-        } else {
2609
-            $related_model_object = null;
2610
-            // this doesn't exist in the Db,
2611
-            // but maybe the relation is of type belongs to, and so the related thing might
2612
-            if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2613
-                $related_model_object = $model->get_first_related(
2614
-                    $this,
2615
-                    $relationName,
2616
-                    $query_params
2617
-                );
2618
-            }
2619
-            // this doesn't exist in the DB and apparently the thing it belongs to doesn't either,
2620
-            // just get what's cached on this object
2621
-            if (! $related_model_object) {
2622
-                $related_model_object = $this->get_one_from_cache($relationName);
2623
-            }
2624
-        }
2625
-        return $related_model_object;
2626
-    }
2627
-
2628
-
2629
-    /**
2630
-     * Does a delete on all related objects of type $relationName and removes
2631
-     * the current model object's relation to them. If they can't be deleted (because
2632
-     * of blocking related model objects) does nothing. If the related model objects are
2633
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2634
-     * If this model object doesn't exist yet in the DB, just removes its related things
2635
-     *
2636
-     * @param string $relationName
2637
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2638
-     * @return int how many deleted
2639
-     * @throws ReflectionException
2640
-     * @throws InvalidArgumentException
2641
-     * @throws InvalidInterfaceException
2642
-     * @throws InvalidDataTypeException
2643
-     * @throws EE_Error
2644
-     */
2645
-    public function delete_related($relationName, $query_params = array())
2646
-    {
2647
-        if ($this->ID()) {
2648
-            $count = $this->get_model()->delete_related(
2649
-                $this,
2650
-                $relationName,
2651
-                $query_params
2652
-            );
2653
-        } else {
2654
-            $count = count($this->get_all_from_cache($relationName));
2655
-            $this->clear_cache($relationName, null, true);
2656
-        }
2657
-        return $count;
2658
-    }
2659
-
2660
-
2661
-    /**
2662
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2663
-     * the current model object's relation to them. If they can't be deleted (because
2664
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2665
-     * If the related thing isn't a soft-deletable model object, this function is identical
2666
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2667
-     *
2668
-     * @param string $relationName
2669
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2670
-     * @return int how many deleted (including those soft deleted)
2671
-     * @throws ReflectionException
2672
-     * @throws InvalidArgumentException
2673
-     * @throws InvalidInterfaceException
2674
-     * @throws InvalidDataTypeException
2675
-     * @throws EE_Error
2676
-     */
2677
-    public function delete_related_permanently($relationName, $query_params = array())
2678
-    {
2679
-        if ($this->ID()) {
2680
-            $count = $this->get_model()->delete_related_permanently(
2681
-                $this,
2682
-                $relationName,
2683
-                $query_params
2684
-            );
2685
-        } else {
2686
-            $count = count($this->get_all_from_cache($relationName));
2687
-        }
2688
-        $this->clear_cache($relationName, null, true);
2689
-        return $count;
2690
-    }
2691
-
2692
-
2693
-    /**
2694
-     * is_set
2695
-     * Just a simple utility function children can use for checking if property exists
2696
-     *
2697
-     * @access  public
2698
-     * @param  string $field_name property to check
2699
-     * @return bool                              TRUE if existing,FALSE if not.
2700
-     */
2701
-    public function is_set($field_name)
2702
-    {
2703
-        return isset($this->_fields[ $field_name ]);
2704
-    }
2705
-
2706
-
2707
-    /**
2708
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2709
-     * EE_Error exception if they don't
2710
-     *
2711
-     * @param  mixed (string|array) $properties properties to check
2712
-     * @throws EE_Error
2713
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2714
-     */
2715
-    protected function _property_exists($properties)
2716
-    {
2717
-        foreach ((array) $properties as $property_name) {
2718
-            // first make sure this property exists
2719
-            if (! $this->_fields[ $property_name ]) {
2720
-                throw new EE_Error(
2721
-                    sprintf(
2722
-                        esc_html__(
2723
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2724
-                            'event_espresso'
2725
-                        ),
2726
-                        $property_name
2727
-                    )
2728
-                );
2729
-            }
2730
-        }
2731
-        return true;
2732
-    }
2733
-
2734
-
2735
-    /**
2736
-     * This simply returns an array of model fields for this object
2737
-     *
2738
-     * @return array
2739
-     * @throws ReflectionException
2740
-     * @throws InvalidArgumentException
2741
-     * @throws InvalidInterfaceException
2742
-     * @throws InvalidDataTypeException
2743
-     * @throws EE_Error
2744
-     */
2745
-    public function model_field_array()
2746
-    {
2747
-        $fields = $this->get_model()->field_settings(false);
2748
-        $properties = array();
2749
-        // remove prepended underscore
2750
-        foreach ($fields as $field_name => $settings) {
2751
-            $properties[ $field_name ] = $this->get($field_name);
2752
-        }
2753
-        return $properties;
2754
-    }
2755
-
2756
-
2757
-    /**
2758
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2759
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2760
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments.
2761
-     * Instead of requiring a plugin to extend the EE_Base_Class
2762
-     * (which works fine is there's only 1 plugin, but when will that happen?)
2763
-     * they can add a hook onto 'filters_hook_espresso__{className}__{methodName}'
2764
-     * (eg, filters_hook_espresso__EE_Answer__my_great_function)
2765
-     * and accepts 2 arguments: the object on which the function was called,
2766
-     * and an array of the original arguments passed to the function.
2767
-     * Whatever their callback function returns will be returned by this function.
2768
-     * Example: in functions.php (or in a plugin):
2769
-     *      add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3);
2770
-     *      function my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2771
-     *          $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2772
-     *          return $previousReturnValue.$returnString;
2773
-     *      }
2774
-     * require('EE_Answer.class.php');
2775
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2776
-     * echo $answer->my_callback('monkeys',100);
2777
-     * //will output "you called my_callback! and passed args:monkeys,100"
2778
-     *
2779
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2780
-     * @param array  $args       array of original arguments passed to the function
2781
-     * @throws EE_Error
2782
-     * @return mixed whatever the plugin which calls add_filter decides
2783
-     */
2784
-    public function __call($methodName, $args)
2785
-    {
2786
-        $className = get_class($this);
2787
-        $tagName = "FHEE__{$className}__{$methodName}";
2788
-        if (! has_filter($tagName)) {
2789
-            throw new EE_Error(
2790
-                sprintf(
2791
-                    esc_html__(
2792
-                        "Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2793
-                        'event_espresso'
2794
-                    ),
2795
-                    $methodName,
2796
-                    $className,
2797
-                    $tagName
2798
-                )
2799
-            );
2800
-        }
2801
-        return apply_filters($tagName, null, $this, $args);
2802
-    }
2803
-
2804
-
2805
-    /**
2806
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2807
-     * A $previous_value can be specified in case there are many meta rows with the same key
2808
-     *
2809
-     * @param string $meta_key
2810
-     * @param mixed  $meta_value
2811
-     * @param mixed  $previous_value
2812
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2813
-     *                  NOTE: if the values haven't changed, returns 0
2814
-     * @throws InvalidArgumentException
2815
-     * @throws InvalidInterfaceException
2816
-     * @throws InvalidDataTypeException
2817
-     * @throws EE_Error
2818
-     * @throws ReflectionException
2819
-     */
2820
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2821
-    {
2822
-        $query_params = array(
2823
-            array(
2824
-                'EXM_key'  => $meta_key,
2825
-                'OBJ_ID'   => $this->ID(),
2826
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2827
-            ),
2828
-        );
2829
-        if ($previous_value !== null) {
2830
-            $query_params[0]['EXM_value'] = $meta_value;
2831
-        }
2832
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2833
-        if (! $existing_rows_like_that) {
2834
-            return $this->add_extra_meta($meta_key, $meta_value);
2835
-        }
2836
-        foreach ($existing_rows_like_that as $existing_row) {
2837
-            $existing_row->save(array('EXM_value' => $meta_value));
2838
-        }
2839
-        return count($existing_rows_like_that);
2840
-    }
2841
-
2842
-
2843
-    /**
2844
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2845
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2846
-     * extra meta row was entered, false if not
2847
-     *
2848
-     * @param string  $meta_key
2849
-     * @param mixed   $meta_value
2850
-     * @param boolean $unique
2851
-     * @return boolean
2852
-     * @throws InvalidArgumentException
2853
-     * @throws InvalidInterfaceException
2854
-     * @throws InvalidDataTypeException
2855
-     * @throws EE_Error
2856
-     * @throws ReflectionException
2857
-     * @throws ReflectionException
2858
-     */
2859
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2860
-    {
2861
-        if ($unique) {
2862
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2863
-                array(
2864
-                    array(
2865
-                        'EXM_key'  => $meta_key,
2866
-                        'OBJ_ID'   => $this->ID(),
2867
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2868
-                    ),
2869
-                )
2870
-            );
2871
-            if ($existing_extra_meta) {
2872
-                return false;
2873
-            }
2874
-        }
2875
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2876
-            array(
2877
-                'EXM_key'   => $meta_key,
2878
-                'EXM_value' => $meta_value,
2879
-                'OBJ_ID'    => $this->ID(),
2880
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2881
-            )
2882
-        );
2883
-        $new_extra_meta->save();
2884
-        return true;
2885
-    }
2886
-
2887
-
2888
-    /**
2889
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2890
-     * is specified, only deletes extra meta records with that value.
2891
-     *
2892
-     * @param string $meta_key
2893
-     * @param mixed  $meta_value
2894
-     * @return int number of extra meta rows deleted
2895
-     * @throws InvalidArgumentException
2896
-     * @throws InvalidInterfaceException
2897
-     * @throws InvalidDataTypeException
2898
-     * @throws EE_Error
2899
-     * @throws ReflectionException
2900
-     */
2901
-    public function delete_extra_meta($meta_key, $meta_value = null)
2902
-    {
2903
-        $query_params = array(
2904
-            array(
2905
-                'EXM_key'  => $meta_key,
2906
-                'OBJ_ID'   => $this->ID(),
2907
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2908
-            ),
2909
-        );
2910
-        if ($meta_value !== null) {
2911
-            $query_params[0]['EXM_value'] = $meta_value;
2912
-        }
2913
-        return EEM_Extra_Meta::instance()->delete($query_params);
2914
-    }
2915
-
2916
-
2917
-    /**
2918
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2919
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2920
-     * You can specify $default is case you haven't found the extra meta
2921
-     *
2922
-     * @param string  $meta_key
2923
-     * @param boolean $single
2924
-     * @param mixed   $default if we don't find anything, what should we return?
2925
-     * @return mixed single value if $single; array if ! $single
2926
-     * @throws ReflectionException
2927
-     * @throws InvalidArgumentException
2928
-     * @throws InvalidInterfaceException
2929
-     * @throws InvalidDataTypeException
2930
-     * @throws EE_Error
2931
-     */
2932
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2933
-    {
2934
-        if ($single) {
2935
-            $result = $this->get_first_related(
2936
-                'Extra_Meta',
2937
-                array(array('EXM_key' => $meta_key))
2938
-            );
2939
-            if ($result instanceof EE_Extra_Meta) {
2940
-                return $result->value();
2941
-            }
2942
-        } else {
2943
-            $results = $this->get_many_related(
2944
-                'Extra_Meta',
2945
-                array(array('EXM_key' => $meta_key))
2946
-            );
2947
-            if ($results) {
2948
-                $values = array();
2949
-                foreach ($results as $result) {
2950
-                    if ($result instanceof EE_Extra_Meta) {
2951
-                        $values[ $result->ID() ] = $result->value();
2952
-                    }
2953
-                }
2954
-                return $values;
2955
-            }
2956
-        }
2957
-        // if nothing discovered yet return default.
2958
-        return apply_filters(
2959
-            'FHEE__EE_Base_Class__get_extra_meta__default_value',
2960
-            $default,
2961
-            $meta_key,
2962
-            $single,
2963
-            $this
2964
-        );
2965
-    }
2966
-
2967
-
2968
-    /**
2969
-     * Returns a simple array of all the extra meta associated with this model object.
2970
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2971
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2972
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2973
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2974
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2975
-     * finally the extra meta's value as each sub-value. (eg
2976
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2977
-     *
2978
-     * @param boolean $one_of_each_key
2979
-     * @return array
2980
-     * @throws ReflectionException
2981
-     * @throws InvalidArgumentException
2982
-     * @throws InvalidInterfaceException
2983
-     * @throws InvalidDataTypeException
2984
-     * @throws EE_Error
2985
-     */
2986
-    public function all_extra_meta_array($one_of_each_key = true)
2987
-    {
2988
-        $return_array = array();
2989
-        if ($one_of_each_key) {
2990
-            $extra_meta_objs = $this->get_many_related(
2991
-                'Extra_Meta',
2992
-                array('group_by' => 'EXM_key')
2993
-            );
2994
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2995
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2996
-                    $return_array[ $extra_meta_obj->key() ] = $extra_meta_obj->value();
2997
-                }
2998
-            }
2999
-        } else {
3000
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
3001
-            foreach ($extra_meta_objs as $extra_meta_obj) {
3002
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
3003
-                    if (! isset($return_array[ $extra_meta_obj->key() ])) {
3004
-                        $return_array[ $extra_meta_obj->key() ] = array();
3005
-                    }
3006
-                    $return_array[ $extra_meta_obj->key() ][ $extra_meta_obj->ID() ] = $extra_meta_obj->value();
3007
-                }
3008
-            }
3009
-        }
3010
-        return $return_array;
3011
-    }
3012
-
3013
-
3014
-    /**
3015
-     * Gets a pretty nice displayable nice for this model object. Often overridden
3016
-     *
3017
-     * @return string
3018
-     * @throws ReflectionException
3019
-     * @throws InvalidArgumentException
3020
-     * @throws InvalidInterfaceException
3021
-     * @throws InvalidDataTypeException
3022
-     * @throws EE_Error
3023
-     */
3024
-    public function name()
3025
-    {
3026
-        // find a field that's not a text field
3027
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
3028
-        if ($field_we_can_use) {
3029
-            return $this->get($field_we_can_use->get_name());
3030
-        }
3031
-        $first_few_properties = $this->model_field_array();
3032
-        $first_few_properties = array_slice($first_few_properties, 0, 3);
3033
-        $name_parts = array();
3034
-        foreach ($first_few_properties as $name => $value) {
3035
-            $name_parts[] = "$name:$value";
3036
-        }
3037
-        return implode(',', $name_parts);
3038
-    }
3039
-
3040
-
3041
-    /**
3042
-     * in_entity_map
3043
-     * Checks if this model object has been proven to already be in the entity map
3044
-     *
3045
-     * @return boolean
3046
-     * @throws ReflectionException
3047
-     * @throws InvalidArgumentException
3048
-     * @throws InvalidInterfaceException
3049
-     * @throws InvalidDataTypeException
3050
-     * @throws EE_Error
3051
-     */
3052
-    public function in_entity_map()
3053
-    {
3054
-        // well, if we looked, did we find it in the entity map?
3055
-        return $this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this;
3056
-    }
3057
-
3058
-
3059
-    /**
3060
-     * refresh_from_db
3061
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
3062
-     *
3063
-     * @throws ReflectionException
3064
-     * @throws InvalidArgumentException
3065
-     * @throws InvalidInterfaceException
3066
-     * @throws InvalidDataTypeException
3067
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
3068
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
3069
-     */
3070
-    public function refresh_from_db()
3071
-    {
3072
-        if ($this->ID() && $this->in_entity_map()) {
3073
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
3074
-        } else {
3075
-            // if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
3076
-            // if it has an ID but it's not in the map, and you're asking me to refresh it
3077
-            // that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
3078
-            // absolutely nothing in it for this ID
3079
-            if (WP_DEBUG) {
3080
-                throw new EE_Error(
3081
-                    sprintf(
3082
-                        esc_html__(
3083
-                            'Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
3084
-                            'event_espresso'
3085
-                        ),
3086
-                        $this->ID(),
3087
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
3088
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
3089
-                    )
3090
-                );
3091
-            }
3092
-        }
3093
-    }
3094
-
3095
-
3096
-    /**
3097
-     * Change $fields' values to $new_value_sql (which is a string of raw SQL)
3098
-     *
3099
-     * @since 4.9.80.p
3100
-     * @param EE_Model_Field_Base[] $fields
3101
-     * @param string $new_value_sql
3102
-     *      example: 'column_name=123',
3103
-     *      or 'column_name=column_name+1',
3104
-     *      or 'column_name= CASE
3105
-     *          WHEN (`column_name` + `other_column` + 5) <= `yet_another_column`
3106
-     *          THEN `column_name` + 5
3107
-     *          ELSE `column_name`
3108
-     *      END'
3109
-     *      Also updates $field on this model object with the latest value from the database.
3110
-     * @return bool
3111
-     * @throws EE_Error
3112
-     * @throws InvalidArgumentException
3113
-     * @throws InvalidDataTypeException
3114
-     * @throws InvalidInterfaceException
3115
-     * @throws ReflectionException
3116
-     */
3117
-    protected function updateFieldsInDB($fields, $new_value_sql)
3118
-    {
3119
-        // First make sure this model object actually exists in the DB. It would be silly to try to update it in the DB
3120
-        // if it wasn't even there to start off.
3121
-        if (! $this->ID()) {
3122
-            $this->save();
3123
-        }
3124
-        global $wpdb;
3125
-        if (empty($fields)) {
3126
-            throw new InvalidArgumentException(
3127
-                esc_html__(
3128
-                    'EE_Base_Class::updateFieldsInDB was passed an empty array of fields.',
3129
-                    'event_espresso'
3130
-                )
3131
-            );
3132
-        }
3133
-        $first_field = reset($fields);
3134
-        $table_alias = $first_field->get_table_alias();
3135
-        foreach ($fields as $field) {
3136
-            if ($table_alias !== $field->get_table_alias()) {
3137
-                throw new InvalidArgumentException(
3138
-                    sprintf(
3139
-                        esc_html__(
3140
-                            // @codingStandardsIgnoreStart
3141
-                            'EE_Base_Class::updateFieldsInDB was passed fields for different tables ("%1$s" and "%2$s"), which is not supported. Instead, please call the method multiple times.',
3142
-                            // @codingStandardsIgnoreEnd
3143
-                            'event_espresso'
3144
-                        ),
3145
-                        $table_alias,
3146
-                        $field->get_table_alias()
3147
-                    )
3148
-                );
3149
-            }
3150
-        }
3151
-        // Ok the fields are now known to all be for the same table. Proceed with creating the SQL to update it.
3152
-        $table_obj = $this->get_model()->get_table_obj_by_alias($table_alias);
3153
-        $table_pk_value = $this->ID();
3154
-        $table_name = $table_obj->get_table_name();
3155
-        if ($table_obj instanceof EE_Secondary_Table) {
3156
-            $table_pk_field_name = $table_obj->get_fk_on_table();
3157
-        } else {
3158
-            $table_pk_field_name = $table_obj->get_pk_column();
3159
-        }
3160
-
3161
-        $query =
3162
-            "UPDATE `{$table_name}`
337
+				$this->_props_n_values_provided_in_constructor
338
+				&& $field_value
339
+				&& $field_name === $model->primary_key_name()
340
+			) {
341
+				// if so, we want all this object's fields to be filled either with
342
+				// what we've explicitly set on this model
343
+				// or what we have in the db
344
+				// echo "setting primary key!";
345
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
346
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
347
+				foreach ($fields_on_model as $field_obj) {
348
+					if (
349
+						! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
350
+						&& $field_obj->get_name() !== $field_name
351
+					) {
352
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
353
+					}
354
+				}
355
+				// oh this model object has an ID? well make sure its in the entity mapper
356
+				$model->add_to_entity_map($this);
357
+			}
358
+			// let's unset any cache for this field_name from the $_cached_properties property.
359
+			$this->_clear_cached_property($field_name);
360
+		} else {
361
+			throw new EE_Error(
362
+				sprintf(
363
+					esc_html__(
364
+						'A valid EE_Model_Field_Base could not be found for the given field name: %s',
365
+						'event_espresso'
366
+					),
367
+					$field_name
368
+				)
369
+			);
370
+		}
371
+	}
372
+
373
+
374
+	/**
375
+	 * Set custom select values for model.
376
+	 *
377
+	 * @param array $custom_select_values
378
+	 */
379
+	public function setCustomSelectsValues(array $custom_select_values)
380
+	{
381
+		$this->custom_selection_results = $custom_select_values;
382
+	}
383
+
384
+
385
+	/**
386
+	 * Returns the custom select value for the provided alias if its set.
387
+	 * If not set, returns null.
388
+	 *
389
+	 * @param string $alias
390
+	 * @return string|int|float|null
391
+	 */
392
+	public function getCustomSelect($alias)
393
+	{
394
+		return isset($this->custom_selection_results[ $alias ])
395
+			? $this->custom_selection_results[ $alias ]
396
+			: null;
397
+	}
398
+
399
+
400
+	/**
401
+	 * This sets the field value on the db column if it exists for the given $column_name or
402
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
403
+	 *
404
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
405
+	 * @param string $field_name  Must be the exact column name.
406
+	 * @param mixed  $field_value The value to set.
407
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
408
+	 * @throws InvalidArgumentException
409
+	 * @throws InvalidInterfaceException
410
+	 * @throws InvalidDataTypeException
411
+	 * @throws EE_Error
412
+	 * @throws ReflectionException
413
+	 */
414
+	public function set_field_or_extra_meta($field_name, $field_value)
415
+	{
416
+		if ($this->get_model()->has_field($field_name)) {
417
+			$this->set($field_name, $field_value);
418
+			return true;
419
+		}
420
+		// ensure this object is saved first so that extra meta can be properly related.
421
+		$this->save();
422
+		return $this->update_extra_meta($field_name, $field_value);
423
+	}
424
+
425
+
426
+	/**
427
+	 * This retrieves the value of the db column set on this class or if that's not present
428
+	 * it will attempt to retrieve from extra_meta if found.
429
+	 * Example Usage:
430
+	 * Via EE_Message child class:
431
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
432
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
433
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
434
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
435
+	 * value for those extra fields dynamically via the EE_message object.
436
+	 *
437
+	 * @param  string $field_name expecting the fully qualified field name.
438
+	 * @return mixed|null  value for the field if found.  null if not found.
439
+	 * @throws ReflectionException
440
+	 * @throws InvalidArgumentException
441
+	 * @throws InvalidInterfaceException
442
+	 * @throws InvalidDataTypeException
443
+	 * @throws EE_Error
444
+	 */
445
+	public function get_field_or_extra_meta($field_name)
446
+	{
447
+		if ($this->get_model()->has_field($field_name)) {
448
+			$column_value = $this->get($field_name);
449
+		} else {
450
+			// This isn't a column in the main table, let's see if it is in the extra meta.
451
+			$column_value = $this->get_extra_meta($field_name, true, null);
452
+		}
453
+		return $column_value;
454
+	}
455
+
456
+
457
+	/**
458
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
459
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
460
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
461
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
462
+	 *
463
+	 * @access public
464
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
465
+	 * @return void
466
+	 * @throws InvalidArgumentException
467
+	 * @throws InvalidInterfaceException
468
+	 * @throws InvalidDataTypeException
469
+	 * @throws EE_Error
470
+	 * @throws ReflectionException
471
+	 */
472
+	public function set_timezone($timezone = '')
473
+	{
474
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
475
+		// make sure we clear all cached properties because they won't be relevant now
476
+		$this->_clear_cached_properties();
477
+		// make sure we update field settings and the date for all EE_Datetime_Fields
478
+		$model_fields = $this->get_model()->field_settings(false);
479
+		foreach ($model_fields as $field_name => $field_obj) {
480
+			if ($field_obj instanceof EE_Datetime_Field) {
481
+				$field_obj->set_timezone($this->_timezone);
482
+				if (isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime) {
483
+					EEH_DTT_Helper::setTimezone($this->_fields[ $field_name ], new DateTimeZone($this->_timezone));
484
+				}
485
+			}
486
+		}
487
+	}
488
+
489
+
490
+	/**
491
+	 * This just returns whatever is set for the current timezone.
492
+	 *
493
+	 * @access public
494
+	 * @return string timezone string
495
+	 */
496
+	public function get_timezone()
497
+	{
498
+		return $this->_timezone;
499
+	}
500
+
501
+
502
+	/**
503
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
504
+	 * internally instead of wp set date format options
505
+	 *
506
+	 * @since 4.6
507
+	 * @param string $format should be a format recognizable by PHP date() functions.
508
+	 */
509
+	public function set_date_format($format)
510
+	{
511
+		$this->_dt_frmt = $format;
512
+		// clear cached_properties because they won't be relevant now.
513
+		$this->_clear_cached_properties();
514
+	}
515
+
516
+
517
+	/**
518
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
519
+	 * class internally instead of wp set time format options.
520
+	 *
521
+	 * @since 4.6
522
+	 * @param string $format should be a format recognizable by PHP date() functions.
523
+	 */
524
+	public function set_time_format($format)
525
+	{
526
+		$this->_tm_frmt = $format;
527
+		// clear cached_properties because they won't be relevant now.
528
+		$this->_clear_cached_properties();
529
+	}
530
+
531
+
532
+	/**
533
+	 * This returns the current internal set format for the date and time formats.
534
+	 *
535
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
536
+	 *                             where the first value is the date format and the second value is the time format.
537
+	 * @return mixed string|array
538
+	 */
539
+	public function get_format($full = true)
540
+	{
541
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
542
+	}
543
+
544
+
545
+	/**
546
+	 * cache
547
+	 * stores the passed model object on the current model object.
548
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
549
+	 *
550
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
551
+	 *                                       'Registration' associated with this model object
552
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
553
+	 *                                       that could be a payment or a registration)
554
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
555
+	 *                                       items which will be stored in an array on this object
556
+	 * @throws ReflectionException
557
+	 * @throws InvalidArgumentException
558
+	 * @throws InvalidInterfaceException
559
+	 * @throws InvalidDataTypeException
560
+	 * @throws EE_Error
561
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
562
+	 *                                       related thing, no array)
563
+	 */
564
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
565
+	{
566
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
567
+		if (! $object_to_cache instanceof EE_Base_Class) {
568
+			return false;
569
+		}
570
+		// also get "how" the object is related, or throw an error
571
+		if (! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
572
+			throw new EE_Error(
573
+				sprintf(
574
+					esc_html__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
575
+					$relationName,
576
+					get_class($this)
577
+				)
578
+			);
579
+		}
580
+		// how many things are related ?
581
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
582
+			// if it's a "belongs to" relationship, then there's only one related model object
583
+			// eg, if this is a registration, there's only 1 attendee for it
584
+			// so for these model objects just set it to be cached
585
+			$this->_model_relations[ $relationName ] = $object_to_cache;
586
+			$return = true;
587
+		} else {
588
+			// otherwise, this is the "many" side of a one to many relationship,
589
+			// so we'll add the object to the array of related objects for that type.
590
+			// eg: if this is an event, there are many registrations for that event,
591
+			// so we cache the registrations in an array
592
+			if (! is_array($this->_model_relations[ $relationName ])) {
593
+				// if for some reason, the cached item is a model object,
594
+				// then stick that in the array, otherwise start with an empty array
595
+				$this->_model_relations[ $relationName ] = $this->_model_relations[ $relationName ]
596
+														   instanceof
597
+														   EE_Base_Class
598
+					? array($this->_model_relations[ $relationName ]) : array();
599
+			}
600
+			// first check for a cache_id which is normally empty
601
+			if (! empty($cache_id)) {
602
+				// if the cache_id exists, then it means we are purposely trying to cache this
603
+				// with a known key that can then be used to retrieve the object later on
604
+				$this->_model_relations[ $relationName ][ $cache_id ] = $object_to_cache;
605
+				$return = $cache_id;
606
+			} elseif ($object_to_cache->ID()) {
607
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
608
+				$this->_model_relations[ $relationName ][ $object_to_cache->ID() ] = $object_to_cache;
609
+				$return = $object_to_cache->ID();
610
+			} else {
611
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
612
+				$this->_model_relations[ $relationName ][] = $object_to_cache;
613
+				// move the internal pointer to the end of the array
614
+				end($this->_model_relations[ $relationName ]);
615
+				// and grab the key so that we can return it
616
+				$return = key($this->_model_relations[ $relationName ]);
617
+			}
618
+		}
619
+		return $return;
620
+	}
621
+
622
+
623
+	/**
624
+	 * For adding an item to the cached_properties property.
625
+	 *
626
+	 * @access protected
627
+	 * @param string      $fieldname the property item the corresponding value is for.
628
+	 * @param mixed       $value     The value we are caching.
629
+	 * @param string|null $cache_type
630
+	 * @return void
631
+	 * @throws ReflectionException
632
+	 * @throws InvalidArgumentException
633
+	 * @throws InvalidInterfaceException
634
+	 * @throws InvalidDataTypeException
635
+	 * @throws EE_Error
636
+	 */
637
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
638
+	{
639
+		// first make sure this property exists
640
+		$this->get_model()->field_settings_for($fieldname);
641
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
642
+		$this->_cached_properties[ $fieldname ][ $cache_type ] = $value;
643
+	}
644
+
645
+
646
+	/**
647
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
648
+	 * This also SETS the cache if we return the actual property!
649
+	 *
650
+	 * @param string $fieldname        the name of the property we're trying to retrieve
651
+	 * @param bool   $pretty
652
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
653
+	 *                                 (in cases where the same property may be used for different outputs
654
+	 *                                 - i.e. datetime, money etc.)
655
+	 *                                 It can also accept certain pre-defined "schema" strings
656
+	 *                                 to define how to output the property.
657
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
658
+	 * @return mixed                   whatever the value for the property is we're retrieving
659
+	 * @throws ReflectionException
660
+	 * @throws InvalidArgumentException
661
+	 * @throws InvalidInterfaceException
662
+	 * @throws InvalidDataTypeException
663
+	 * @throws EE_Error
664
+	 */
665
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
666
+	{
667
+		// verify the field exists
668
+		$model = $this->get_model();
669
+		$model->field_settings_for($fieldname);
670
+		$cache_type = $pretty ? 'pretty' : 'standard';
671
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
672
+		if (isset($this->_cached_properties[ $fieldname ][ $cache_type ])) {
673
+			return $this->_cached_properties[ $fieldname ][ $cache_type ];
674
+		}
675
+		$value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
676
+		$this->_set_cached_property($fieldname, $value, $cache_type);
677
+		return $value;
678
+	}
679
+
680
+
681
+	/**
682
+	 * If the cache didn't fetch the needed item, this fetches it.
683
+	 *
684
+	 * @param string $fieldname
685
+	 * @param bool   $pretty
686
+	 * @param string $extra_cache_ref
687
+	 * @return mixed
688
+	 * @throws InvalidArgumentException
689
+	 * @throws InvalidInterfaceException
690
+	 * @throws InvalidDataTypeException
691
+	 * @throws EE_Error
692
+	 * @throws ReflectionException
693
+	 */
694
+	protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
695
+	{
696
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
697
+		// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
698
+		if ($field_obj instanceof EE_Datetime_Field) {
699
+			$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
700
+		}
701
+		if (! isset($this->_fields[ $fieldname ])) {
702
+			$this->_fields[ $fieldname ] = null;
703
+		}
704
+		$value = $pretty
705
+			? $field_obj->prepare_for_pretty_echoing($this->_fields[ $fieldname ], $extra_cache_ref)
706
+			: $field_obj->prepare_for_get($this->_fields[ $fieldname ]);
707
+		return $value;
708
+	}
709
+
710
+
711
+	/**
712
+	 * set timezone, formats, and output for EE_Datetime_Field objects
713
+	 *
714
+	 * @param \EE_Datetime_Field $datetime_field
715
+	 * @param bool               $pretty
716
+	 * @param null               $date_or_time
717
+	 * @return void
718
+	 * @throws InvalidArgumentException
719
+	 * @throws InvalidInterfaceException
720
+	 * @throws InvalidDataTypeException
721
+	 * @throws EE_Error
722
+	 */
723
+	protected function _prepare_datetime_field(
724
+		EE_Datetime_Field $datetime_field,
725
+		$pretty = false,
726
+		$date_or_time = null
727
+	) {
728
+		$datetime_field->set_timezone($this->_timezone);
729
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
730
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
731
+		// set the output returned
732
+		switch ($date_or_time) {
733
+			case 'D':
734
+				$datetime_field->set_date_time_output('date');
735
+				break;
736
+			case 'T':
737
+				$datetime_field->set_date_time_output('time');
738
+				break;
739
+			default:
740
+				$datetime_field->set_date_time_output();
741
+		}
742
+	}
743
+
744
+
745
+	/**
746
+	 * This just takes care of clearing out the cached_properties
747
+	 *
748
+	 * @return void
749
+	 */
750
+	protected function _clear_cached_properties()
751
+	{
752
+		$this->_cached_properties = array();
753
+	}
754
+
755
+
756
+	/**
757
+	 * This just clears out ONE property if it exists in the cache
758
+	 *
759
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
760
+	 * @return void
761
+	 */
762
+	protected function _clear_cached_property($property_name)
763
+	{
764
+		if (isset($this->_cached_properties[ $property_name ])) {
765
+			unset($this->_cached_properties[ $property_name ]);
766
+		}
767
+	}
768
+
769
+
770
+	/**
771
+	 * Ensures that this related thing is a model object.
772
+	 *
773
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
774
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
775
+	 * @return EE_Base_Class
776
+	 * @throws ReflectionException
777
+	 * @throws InvalidArgumentException
778
+	 * @throws InvalidInterfaceException
779
+	 * @throws InvalidDataTypeException
780
+	 * @throws EE_Error
781
+	 */
782
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
783
+	{
784
+		$other_model_instance = self::_get_model_instance_with_name(
785
+			self::_get_model_classname($model_name),
786
+			$this->_timezone
787
+		);
788
+		return $other_model_instance->ensure_is_obj($object_or_id);
789
+	}
790
+
791
+
792
+	/**
793
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
794
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
795
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
796
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
797
+	 *
798
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
799
+	 *                                                     Eg 'Registration'
800
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
801
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
802
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
803
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
804
+	 *                                                     this is HasMany or HABTM.
805
+	 * @throws ReflectionException
806
+	 * @throws InvalidArgumentException
807
+	 * @throws InvalidInterfaceException
808
+	 * @throws InvalidDataTypeException
809
+	 * @throws EE_Error
810
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
811
+	 *                                                     relation from all
812
+	 */
813
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
814
+	{
815
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
816
+		$index_in_cache = '';
817
+		if (! $relationship_to_model) {
818
+			throw new EE_Error(
819
+				sprintf(
820
+					esc_html__('There is no relationship to %s on a %s. Cannot clear that cache', 'event_espresso'),
821
+					$relationName,
822
+					get_class($this)
823
+				)
824
+			);
825
+		}
826
+		if ($clear_all) {
827
+			$obj_removed = true;
828
+			$this->_model_relations[ $relationName ] = null;
829
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
830
+			$obj_removed = $this->_model_relations[ $relationName ];
831
+			$this->_model_relations[ $relationName ] = null;
832
+		} else {
833
+			if (
834
+				$object_to_remove_or_index_into_array instanceof EE_Base_Class
835
+				&& $object_to_remove_or_index_into_array->ID()
836
+			) {
837
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
838
+				if (
839
+					is_array($this->_model_relations[ $relationName ])
840
+					&& ! isset($this->_model_relations[ $relationName ][ $index_in_cache ])
841
+				) {
842
+					$index_found_at = null;
843
+					// find this object in the array even though it has a different key
844
+					foreach ($this->_model_relations[ $relationName ] as $index => $obj) {
845
+						/** @noinspection TypeUnsafeComparisonInspection */
846
+						if (
847
+							$obj instanceof EE_Base_Class
848
+							&& (
849
+								$obj == $object_to_remove_or_index_into_array
850
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
851
+							)
852
+						) {
853
+							$index_found_at = $index;
854
+							break;
855
+						}
856
+					}
857
+					if ($index_found_at) {
858
+						$index_in_cache = $index_found_at;
859
+					} else {
860
+						// it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
861
+						// if it wasn't in it to begin with. So we're done
862
+						return $object_to_remove_or_index_into_array;
863
+					}
864
+				}
865
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
866
+				// so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
867
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
868
+					/** @noinspection TypeUnsafeComparisonInspection */
869
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
870
+						$index_in_cache = $index;
871
+					}
872
+				}
873
+			} else {
874
+				$index_in_cache = $object_to_remove_or_index_into_array;
875
+			}
876
+			// supposedly we've found it. But it could just be that the client code
877
+			// provided a bad index/object
878
+			if (isset($this->_model_relations[ $relationName ][ $index_in_cache ])) {
879
+				$obj_removed = $this->_model_relations[ $relationName ][ $index_in_cache ];
880
+				unset($this->_model_relations[ $relationName ][ $index_in_cache ]);
881
+			} else {
882
+				// that thing was never cached anyways.
883
+				$obj_removed = null;
884
+			}
885
+		}
886
+		return $obj_removed;
887
+	}
888
+
889
+
890
+	/**
891
+	 * update_cache_after_object_save
892
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
893
+	 * obtained after being saved to the db
894
+	 *
895
+	 * @param string        $relationName       - the type of object that is cached
896
+	 * @param EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
897
+	 * @param string        $current_cache_id   - the ID that was used when originally caching the object
898
+	 * @return boolean TRUE on success, FALSE on fail
899
+	 * @throws ReflectionException
900
+	 * @throws InvalidArgumentException
901
+	 * @throws InvalidInterfaceException
902
+	 * @throws InvalidDataTypeException
903
+	 * @throws EE_Error
904
+	 */
905
+	public function update_cache_after_object_save(
906
+		$relationName,
907
+		EE_Base_Class $newly_saved_object,
908
+		$current_cache_id = ''
909
+	) {
910
+		// verify that incoming object is of the correct type
911
+		$obj_class = 'EE_' . $relationName;
912
+		if ($newly_saved_object instanceof $obj_class) {
913
+			/* @type EE_Base_Class $newly_saved_object */
914
+			// now get the type of relation
915
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
916
+			// if this is a 1:1 relationship
917
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
918
+				// then just replace the cached object with the newly saved object
919
+				$this->_model_relations[ $relationName ] = $newly_saved_object;
920
+				return true;
921
+				// or if it's some kind of sordid feral polyamorous relationship...
922
+			}
923
+			if (
924
+				is_array($this->_model_relations[ $relationName ])
925
+				&& isset($this->_model_relations[ $relationName ][ $current_cache_id ])
926
+			) {
927
+				// then remove the current cached item
928
+				unset($this->_model_relations[ $relationName ][ $current_cache_id ]);
929
+				// and cache the newly saved object using it's new ID
930
+				$this->_model_relations[ $relationName ][ $newly_saved_object->ID() ] = $newly_saved_object;
931
+				return true;
932
+			}
933
+		}
934
+		return false;
935
+	}
936
+
937
+
938
+	/**
939
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
940
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
941
+	 *
942
+	 * @param string $relationName
943
+	 * @return EE_Base_Class
944
+	 */
945
+	public function get_one_from_cache($relationName)
946
+	{
947
+		$cached_array_or_object = isset($this->_model_relations[ $relationName ])
948
+			? $this->_model_relations[ $relationName ]
949
+			: null;
950
+		if (is_array($cached_array_or_object)) {
951
+			return array_shift($cached_array_or_object);
952
+		}
953
+		return $cached_array_or_object;
954
+	}
955
+
956
+
957
+	/**
958
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
959
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
960
+	 *
961
+	 * @param string $relationName
962
+	 * @throws ReflectionException
963
+	 * @throws InvalidArgumentException
964
+	 * @throws InvalidInterfaceException
965
+	 * @throws InvalidDataTypeException
966
+	 * @throws EE_Error
967
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
968
+	 */
969
+	public function get_all_from_cache($relationName)
970
+	{
971
+		$objects = isset($this->_model_relations[ $relationName ]) ? $this->_model_relations[ $relationName ] : array();
972
+		// if the result is not an array, but exists, make it an array
973
+		$objects = is_array($objects) ? $objects : array($objects);
974
+		// bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
975
+		// basically, if this model object was stored in the session, and these cached model objects
976
+		// already have IDs, let's make sure they're in their model's entity mapper
977
+		// otherwise we will have duplicates next time we call
978
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
979
+		$model = EE_Registry::instance()->load_model($relationName);
980
+		foreach ($objects as $model_object) {
981
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
982
+				// ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
983
+				if ($model_object->ID()) {
984
+					$model->add_to_entity_map($model_object);
985
+				}
986
+			} else {
987
+				throw new EE_Error(
988
+					sprintf(
989
+						esc_html__(
990
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
991
+							'event_espresso'
992
+						),
993
+						$relationName,
994
+						gettype($model_object)
995
+					)
996
+				);
997
+			}
998
+		}
999
+		return $objects;
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
1005
+	 * matching the given query conditions.
1006
+	 *
1007
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1008
+	 * @param int   $limit              How many objects to return.
1009
+	 * @param array $query_params       Any additional conditions on the query.
1010
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1011
+	 *                                  you can indicate just the columns you want returned
1012
+	 * @return array|EE_Base_Class[]
1013
+	 * @throws ReflectionException
1014
+	 * @throws InvalidArgumentException
1015
+	 * @throws InvalidInterfaceException
1016
+	 * @throws InvalidDataTypeException
1017
+	 * @throws EE_Error
1018
+	 */
1019
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
1020
+	{
1021
+		$model = $this->get_model();
1022
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1023
+			? $model->get_primary_key_field()->get_name()
1024
+			: $field_to_order_by;
1025
+		$current_value = ! empty($field) ? $this->get($field) : null;
1026
+		if (empty($field) || empty($current_value)) {
1027
+			return array();
1028
+		}
1029
+		return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
1030
+	}
1031
+
1032
+
1033
+	/**
1034
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
1035
+	 * matching the given query conditions.
1036
+	 *
1037
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1038
+	 * @param int   $limit              How many objects to return.
1039
+	 * @param array $query_params       Any additional conditions on the query.
1040
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1041
+	 *                                  you can indicate just the columns you want returned
1042
+	 * @return array|EE_Base_Class[]
1043
+	 * @throws ReflectionException
1044
+	 * @throws InvalidArgumentException
1045
+	 * @throws InvalidInterfaceException
1046
+	 * @throws InvalidDataTypeException
1047
+	 * @throws EE_Error
1048
+	 */
1049
+	public function previous_x(
1050
+		$field_to_order_by = null,
1051
+		$limit = 1,
1052
+		$query_params = array(),
1053
+		$columns_to_select = null
1054
+	) {
1055
+		$model = $this->get_model();
1056
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1057
+			? $model->get_primary_key_field()->get_name()
1058
+			: $field_to_order_by;
1059
+		$current_value = ! empty($field) ? $this->get($field) : null;
1060
+		if (empty($field) || empty($current_value)) {
1061
+			return array();
1062
+		}
1063
+		return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
1064
+	}
1065
+
1066
+
1067
+	/**
1068
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
1069
+	 * matching the given query conditions.
1070
+	 *
1071
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1072
+	 * @param array $query_params       Any additional conditions on the query.
1073
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1074
+	 *                                  you can indicate just the columns you want returned
1075
+	 * @return array|EE_Base_Class
1076
+	 * @throws ReflectionException
1077
+	 * @throws InvalidArgumentException
1078
+	 * @throws InvalidInterfaceException
1079
+	 * @throws InvalidDataTypeException
1080
+	 * @throws EE_Error
1081
+	 */
1082
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1083
+	{
1084
+		$model = $this->get_model();
1085
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1086
+			? $model->get_primary_key_field()->get_name()
1087
+			: $field_to_order_by;
1088
+		$current_value = ! empty($field) ? $this->get($field) : null;
1089
+		if (empty($field) || empty($current_value)) {
1090
+			return array();
1091
+		}
1092
+		return $model->next($current_value, $field, $query_params, $columns_to_select);
1093
+	}
1094
+
1095
+
1096
+	/**
1097
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
1098
+	 * matching the given query conditions.
1099
+	 *
1100
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1101
+	 * @param array $query_params       Any additional conditions on the query.
1102
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1103
+	 *                                  you can indicate just the column you want returned
1104
+	 * @return array|EE_Base_Class
1105
+	 * @throws ReflectionException
1106
+	 * @throws InvalidArgumentException
1107
+	 * @throws InvalidInterfaceException
1108
+	 * @throws InvalidDataTypeException
1109
+	 * @throws EE_Error
1110
+	 */
1111
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1112
+	{
1113
+		$model = $this->get_model();
1114
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1115
+			? $model->get_primary_key_field()->get_name()
1116
+			: $field_to_order_by;
1117
+		$current_value = ! empty($field) ? $this->get($field) : null;
1118
+		if (empty($field) || empty($current_value)) {
1119
+			return array();
1120
+		}
1121
+		return $model->previous($current_value, $field, $query_params, $columns_to_select);
1122
+	}
1123
+
1124
+
1125
+	/**
1126
+	 * Overrides parent because parent expects old models.
1127
+	 * This also doesn't do any validation, and won't work for serialized arrays
1128
+	 *
1129
+	 * @param string $field_name
1130
+	 * @param mixed  $field_value_from_db
1131
+	 * @throws ReflectionException
1132
+	 * @throws InvalidArgumentException
1133
+	 * @throws InvalidInterfaceException
1134
+	 * @throws InvalidDataTypeException
1135
+	 * @throws EE_Error
1136
+	 */
1137
+	public function set_from_db($field_name, $field_value_from_db)
1138
+	{
1139
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1140
+		if ($field_obj instanceof EE_Model_Field_Base) {
1141
+			// you would think the DB has no NULLs for non-null label fields right? wrong!
1142
+			// eg, a CPT model object could have an entry in the posts table, but no
1143
+			// entry in the meta table. Meaning that all its columns in the meta table
1144
+			// are null! yikes! so when we find one like that, use defaults for its meta columns
1145
+			if ($field_value_from_db === null) {
1146
+				if ($field_obj->is_nullable()) {
1147
+					// if the field allows nulls, then let it be null
1148
+					$field_value = null;
1149
+				} else {
1150
+					$field_value = $field_obj->get_default_value();
1151
+				}
1152
+			} else {
1153
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1154
+			}
1155
+			$this->_fields[ $field_name ] = $field_value;
1156
+			$this->_clear_cached_property($field_name);
1157
+		}
1158
+	}
1159
+
1160
+
1161
+	/**
1162
+	 * verifies that the specified field is of the correct type
1163
+	 *
1164
+	 * @param string $field_name
1165
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1166
+	 *                                (in cases where the same property may be used for different outputs
1167
+	 *                                - i.e. datetime, money etc.)
1168
+	 * @return mixed
1169
+	 * @throws ReflectionException
1170
+	 * @throws InvalidArgumentException
1171
+	 * @throws InvalidInterfaceException
1172
+	 * @throws InvalidDataTypeException
1173
+	 * @throws EE_Error
1174
+	 */
1175
+	public function get($field_name, $extra_cache_ref = null)
1176
+	{
1177
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1183
+	 *
1184
+	 * @param  string $field_name A valid fieldname
1185
+	 * @return mixed              Whatever the raw value stored on the property is.
1186
+	 * @throws ReflectionException
1187
+	 * @throws InvalidArgumentException
1188
+	 * @throws InvalidInterfaceException
1189
+	 * @throws InvalidDataTypeException
1190
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1191
+	 */
1192
+	public function get_raw($field_name)
1193
+	{
1194
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1195
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[ $field_name ] instanceof DateTime
1196
+			? $this->_fields[ $field_name ]->format('U')
1197
+			: $this->_fields[ $field_name ];
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 * This is used to return the internal DateTime object used for a field that is a
1203
+	 * EE_Datetime_Field.
1204
+	 *
1205
+	 * @param string $field_name               The field name retrieving the DateTime object.
1206
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1207
+	 * @throws EE_Error an error is set and false returned.  If the field IS an
1208
+	 *                                         EE_Datetime_Field and but the field value is null, then
1209
+	 *                                         just null is returned (because that indicates that likely
1210
+	 *                                         this field is nullable).
1211
+	 * @throws InvalidArgumentException
1212
+	 * @throws InvalidDataTypeException
1213
+	 * @throws InvalidInterfaceException
1214
+	 * @throws ReflectionException
1215
+	 */
1216
+	public function get_DateTime_object($field_name)
1217
+	{
1218
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1219
+		if (! $field_settings instanceof EE_Datetime_Field) {
1220
+			EE_Error::add_error(
1221
+				sprintf(
1222
+					esc_html__(
1223
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1224
+						'event_espresso'
1225
+					),
1226
+					$field_name
1227
+				),
1228
+				__FILE__,
1229
+				__FUNCTION__,
1230
+				__LINE__
1231
+			);
1232
+			return false;
1233
+		}
1234
+		return isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime
1235
+			? clone $this->_fields[ $field_name ]
1236
+			: null;
1237
+	}
1238
+
1239
+
1240
+	/**
1241
+	 * To be used in template to immediately echo out the value, and format it for output.
1242
+	 * Eg, should call stripslashes and whatnot before echoing
1243
+	 *
1244
+	 * @param string $field_name      the name of the field as it appears in the DB
1245
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1246
+	 *                                (in cases where the same property may be used for different outputs
1247
+	 *                                - i.e. datetime, money etc.)
1248
+	 * @return void
1249
+	 * @throws ReflectionException
1250
+	 * @throws InvalidArgumentException
1251
+	 * @throws InvalidInterfaceException
1252
+	 * @throws InvalidDataTypeException
1253
+	 * @throws EE_Error
1254
+	 */
1255
+	public function e($field_name, $extra_cache_ref = null)
1256
+	{
1257
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1263
+	 * can be easily used as the value of form input.
1264
+	 *
1265
+	 * @param string $field_name
1266
+	 * @return void
1267
+	 * @throws ReflectionException
1268
+	 * @throws InvalidArgumentException
1269
+	 * @throws InvalidInterfaceException
1270
+	 * @throws InvalidDataTypeException
1271
+	 * @throws EE_Error
1272
+	 */
1273
+	public function f($field_name)
1274
+	{
1275
+		$this->e($field_name, 'form_input');
1276
+	}
1277
+
1278
+
1279
+	/**
1280
+	 * Same as `f()` but just returns the value instead of echoing it
1281
+	 *
1282
+	 * @param string $field_name
1283
+	 * @return string
1284
+	 * @throws ReflectionException
1285
+	 * @throws InvalidArgumentException
1286
+	 * @throws InvalidInterfaceException
1287
+	 * @throws InvalidDataTypeException
1288
+	 * @throws EE_Error
1289
+	 */
1290
+	public function get_f($field_name)
1291
+	{
1292
+		return (string) $this->get_pretty($field_name, 'form_input');
1293
+	}
1294
+
1295
+
1296
+	/**
1297
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1298
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1299
+	 * to see what options are available.
1300
+	 *
1301
+	 * @param string $field_name
1302
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1303
+	 *                                (in cases where the same property may be used for different outputs
1304
+	 *                                - i.e. datetime, money etc.)
1305
+	 * @return mixed
1306
+	 * @throws ReflectionException
1307
+	 * @throws InvalidArgumentException
1308
+	 * @throws InvalidInterfaceException
1309
+	 * @throws InvalidDataTypeException
1310
+	 * @throws EE_Error
1311
+	 */
1312
+	public function get_pretty($field_name, $extra_cache_ref = null)
1313
+	{
1314
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1315
+	}
1316
+
1317
+
1318
+	/**
1319
+	 * This simply returns the datetime for the given field name
1320
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1321
+	 * (and the equivalent e_date, e_time, e_datetime).
1322
+	 *
1323
+	 * @access   protected
1324
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1325
+	 * @param string   $dt_frmt      valid datetime format used for date
1326
+	 *                               (if '' then we just use the default on the field,
1327
+	 *                               if NULL we use the last-used format)
1328
+	 * @param string   $tm_frmt      Same as above except this is for time format
1329
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1330
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1331
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1332
+	 *                               if field is not a valid dtt field, or void if echoing
1333
+	 * @throws ReflectionException
1334
+	 * @throws InvalidArgumentException
1335
+	 * @throws InvalidInterfaceException
1336
+	 * @throws InvalidDataTypeException
1337
+	 * @throws EE_Error
1338
+	 */
1339
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1340
+	{
1341
+		// clear cached property
1342
+		$this->_clear_cached_property($field_name);
1343
+		// reset format properties because they are used in get()
1344
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1345
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1346
+		if ($echo) {
1347
+			$this->e($field_name, $date_or_time);
1348
+			return '';
1349
+		}
1350
+		return $this->get($field_name, $date_or_time);
1351
+	}
1352
+
1353
+
1354
+	/**
1355
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1356
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1357
+	 * other echoes the pretty value for dtt)
1358
+	 *
1359
+	 * @param  string $field_name name of model object datetime field holding the value
1360
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1361
+	 * @return string            datetime value formatted
1362
+	 * @throws ReflectionException
1363
+	 * @throws InvalidArgumentException
1364
+	 * @throws InvalidInterfaceException
1365
+	 * @throws InvalidDataTypeException
1366
+	 * @throws EE_Error
1367
+	 */
1368
+	public function get_date($field_name, $format = '')
1369
+	{
1370
+		return $this->_get_datetime($field_name, $format, null, 'D');
1371
+	}
1372
+
1373
+
1374
+	/**
1375
+	 * @param        $field_name
1376
+	 * @param string $format
1377
+	 * @throws ReflectionException
1378
+	 * @throws InvalidArgumentException
1379
+	 * @throws InvalidInterfaceException
1380
+	 * @throws InvalidDataTypeException
1381
+	 * @throws EE_Error
1382
+	 */
1383
+	public function e_date($field_name, $format = '')
1384
+	{
1385
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1386
+	}
1387
+
1388
+
1389
+	/**
1390
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1391
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1392
+	 * other echoes the pretty value for dtt)
1393
+	 *
1394
+	 * @param  string $field_name name of model object datetime field holding the value
1395
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1396
+	 * @return string             datetime value formatted
1397
+	 * @throws ReflectionException
1398
+	 * @throws InvalidArgumentException
1399
+	 * @throws InvalidInterfaceException
1400
+	 * @throws InvalidDataTypeException
1401
+	 * @throws EE_Error
1402
+	 */
1403
+	public function get_time($field_name, $format = '')
1404
+	{
1405
+		return $this->_get_datetime($field_name, null, $format, 'T');
1406
+	}
1407
+
1408
+
1409
+	/**
1410
+	 * @param        $field_name
1411
+	 * @param string $format
1412
+	 * @throws ReflectionException
1413
+	 * @throws InvalidArgumentException
1414
+	 * @throws InvalidInterfaceException
1415
+	 * @throws InvalidDataTypeException
1416
+	 * @throws EE_Error
1417
+	 */
1418
+	public function e_time($field_name, $format = '')
1419
+	{
1420
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1426
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1427
+	 * other echoes the pretty value for dtt)
1428
+	 *
1429
+	 * @param  string $field_name name of model object datetime field holding the value
1430
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1431
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1432
+	 * @return string             datetime value formatted
1433
+	 * @throws ReflectionException
1434
+	 * @throws InvalidArgumentException
1435
+	 * @throws InvalidInterfaceException
1436
+	 * @throws InvalidDataTypeException
1437
+	 * @throws EE_Error
1438
+	 */
1439
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1440
+	{
1441
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1442
+	}
1443
+
1444
+
1445
+	/**
1446
+	 * @param string $field_name
1447
+	 * @param string $dt_frmt
1448
+	 * @param string $tm_frmt
1449
+	 * @throws ReflectionException
1450
+	 * @throws InvalidArgumentException
1451
+	 * @throws InvalidInterfaceException
1452
+	 * @throws InvalidDataTypeException
1453
+	 * @throws EE_Error
1454
+	 */
1455
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1456
+	{
1457
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1463
+	 *
1464
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1465
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1466
+	 *                           on the object will be used.
1467
+	 * @return string Date and time string in set locale or false if no field exists for the given
1468
+	 * @throws ReflectionException
1469
+	 * @throws InvalidArgumentException
1470
+	 * @throws InvalidInterfaceException
1471
+	 * @throws InvalidDataTypeException
1472
+	 * @throws EE_Error
1473
+	 *                           field name.
1474
+	 */
1475
+	public function get_i18n_datetime($field_name, $format = '')
1476
+	{
1477
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1478
+		return date_i18n(
1479
+			$format,
1480
+			EEH_DTT_Helper::get_timestamp_with_offset(
1481
+				$this->get_raw($field_name),
1482
+				$this->_timezone
1483
+			)
1484
+		);
1485
+	}
1486
+
1487
+
1488
+	/**
1489
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1490
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1491
+	 * thrown.
1492
+	 *
1493
+	 * @param  string $field_name The field name being checked
1494
+	 * @throws ReflectionException
1495
+	 * @throws InvalidArgumentException
1496
+	 * @throws InvalidInterfaceException
1497
+	 * @throws InvalidDataTypeException
1498
+	 * @throws EE_Error
1499
+	 * @return EE_Datetime_Field
1500
+	 */
1501
+	protected function _get_dtt_field_settings($field_name)
1502
+	{
1503
+		$field = $this->get_model()->field_settings_for($field_name);
1504
+		// check if field is dtt
1505
+		if ($field instanceof EE_Datetime_Field) {
1506
+			return $field;
1507
+		}
1508
+		throw new EE_Error(
1509
+			sprintf(
1510
+				esc_html__(
1511
+					'The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1512
+					'event_espresso'
1513
+				),
1514
+				$field_name,
1515
+				self::_get_model_classname(get_class($this))
1516
+			)
1517
+		);
1518
+	}
1519
+
1520
+
1521
+
1522
+
1523
+	/**
1524
+	 * NOTE ABOUT BELOW:
1525
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1526
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1527
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1528
+	 * method and make sure you send the entire datetime value for setting.
1529
+	 */
1530
+	/**
1531
+	 * sets the time on a datetime property
1532
+	 *
1533
+	 * @access protected
1534
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1535
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1536
+	 * @throws ReflectionException
1537
+	 * @throws InvalidArgumentException
1538
+	 * @throws InvalidInterfaceException
1539
+	 * @throws InvalidDataTypeException
1540
+	 * @throws EE_Error
1541
+	 */
1542
+	protected function _set_time_for($time, $fieldname)
1543
+	{
1544
+		$this->_set_date_time('T', $time, $fieldname);
1545
+	}
1546
+
1547
+
1548
+	/**
1549
+	 * sets the date on a datetime property
1550
+	 *
1551
+	 * @access protected
1552
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1553
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1554
+	 * @throws ReflectionException
1555
+	 * @throws InvalidArgumentException
1556
+	 * @throws InvalidInterfaceException
1557
+	 * @throws InvalidDataTypeException
1558
+	 * @throws EE_Error
1559
+	 */
1560
+	protected function _set_date_for($date, $fieldname)
1561
+	{
1562
+		$this->_set_date_time('D', $date, $fieldname);
1563
+	}
1564
+
1565
+
1566
+	/**
1567
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1568
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1569
+	 *
1570
+	 * @access protected
1571
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1572
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1573
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1574
+	 *                                        EE_Datetime_Field property)
1575
+	 * @throws ReflectionException
1576
+	 * @throws InvalidArgumentException
1577
+	 * @throws InvalidInterfaceException
1578
+	 * @throws InvalidDataTypeException
1579
+	 * @throws EE_Error
1580
+	 */
1581
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1582
+	{
1583
+		$field = $this->_get_dtt_field_settings($fieldname);
1584
+		$field->set_timezone($this->_timezone);
1585
+		$field->set_date_format($this->_dt_frmt);
1586
+		$field->set_time_format($this->_tm_frmt);
1587
+		switch ($what) {
1588
+			case 'T':
1589
+				$this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_time(
1590
+					$datetime_value,
1591
+					$this->_fields[ $fieldname ]
1592
+				);
1593
+				$this->_has_changes = true;
1594
+				break;
1595
+			case 'D':
1596
+				$this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_date(
1597
+					$datetime_value,
1598
+					$this->_fields[ $fieldname ]
1599
+				);
1600
+				$this->_has_changes = true;
1601
+				break;
1602
+			case 'B':
1603
+				$this->_fields[ $fieldname ] = $field->prepare_for_set($datetime_value);
1604
+				$this->_has_changes = true;
1605
+				break;
1606
+		}
1607
+		$this->_clear_cached_property($fieldname);
1608
+	}
1609
+
1610
+
1611
+	/**
1612
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1613
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1614
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1615
+	 * that could lead to some unexpected results!
1616
+	 *
1617
+	 * @access public
1618
+	 * @param string $field_name               This is the name of the field on the object that contains the date/time
1619
+	 *                                         value being returned.
1620
+	 * @param string $callback                 must match a valid method in this class (defaults to get_datetime)
1621
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1622
+	 * @param string $prepend                  You can include something to prepend on the timestamp
1623
+	 * @param string $append                   You can include something to append on the timestamp
1624
+	 * @throws ReflectionException
1625
+	 * @throws InvalidArgumentException
1626
+	 * @throws InvalidInterfaceException
1627
+	 * @throws InvalidDataTypeException
1628
+	 * @throws EE_Error
1629
+	 * @return string timestamp
1630
+	 */
1631
+	public function display_in_my_timezone(
1632
+		$field_name,
1633
+		$callback = 'get_datetime',
1634
+		$args = null,
1635
+		$prepend = '',
1636
+		$append = ''
1637
+	) {
1638
+		$timezone = EEH_DTT_Helper::get_timezone();
1639
+		if ($timezone === $this->_timezone) {
1640
+			return '';
1641
+		}
1642
+		$original_timezone = $this->_timezone;
1643
+		$this->set_timezone($timezone);
1644
+		$fn = (array) $field_name;
1645
+		$args = array_merge($fn, (array) $args);
1646
+		if (! method_exists($this, $callback)) {
1647
+			throw new EE_Error(
1648
+				sprintf(
1649
+					esc_html__(
1650
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1651
+						'event_espresso'
1652
+					),
1653
+					$callback
1654
+				)
1655
+			);
1656
+		}
1657
+		$args = (array) $args;
1658
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1659
+		$this->set_timezone($original_timezone);
1660
+		return $return;
1661
+	}
1662
+
1663
+
1664
+	/**
1665
+	 * Deletes this model object.
1666
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1667
+	 * override
1668
+	 * `EE_Base_Class::_delete` NOT this class.
1669
+	 *
1670
+	 * @return boolean | int
1671
+	 * @throws ReflectionException
1672
+	 * @throws InvalidArgumentException
1673
+	 * @throws InvalidInterfaceException
1674
+	 * @throws InvalidDataTypeException
1675
+	 * @throws EE_Error
1676
+	 */
1677
+	public function delete()
1678
+	{
1679
+		/**
1680
+		 * Called just before the `EE_Base_Class::_delete` method call.
1681
+		 * Note:
1682
+		 * `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1683
+		 * should be aware that `_delete` may not always result in a permanent delete.
1684
+		 * For example, `EE_Soft_Delete_Base_Class::_delete`
1685
+		 * soft deletes (trash) the object and does not permanently delete it.
1686
+		 *
1687
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1688
+		 */
1689
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1690
+		$result = $this->_delete();
1691
+		/**
1692
+		 * Called just after the `EE_Base_Class::_delete` method call.
1693
+		 * Note:
1694
+		 * `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1695
+		 * should be aware that `_delete` may not always result in a permanent delete.
1696
+		 * For example `EE_Soft_Base_Class::_delete`
1697
+		 * soft deletes (trash) the object and does not permanently delete it.
1698
+		 *
1699
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1700
+		 * @param boolean       $result
1701
+		 */
1702
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1703
+		return $result;
1704
+	}
1705
+
1706
+
1707
+	/**
1708
+	 * Calls the specific delete method for the instantiated class.
1709
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1710
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1711
+	 * `EE_Base_Class::delete`
1712
+	 *
1713
+	 * @return bool|int
1714
+	 * @throws ReflectionException
1715
+	 * @throws InvalidArgumentException
1716
+	 * @throws InvalidInterfaceException
1717
+	 * @throws InvalidDataTypeException
1718
+	 * @throws EE_Error
1719
+	 */
1720
+	protected function _delete()
1721
+	{
1722
+		return $this->delete_permanently();
1723
+	}
1724
+
1725
+
1726
+	/**
1727
+	 * Deletes this model object permanently from db
1728
+	 * (but keep in mind related models may block the delete and return an error)
1729
+	 *
1730
+	 * @return bool | int
1731
+	 * @throws ReflectionException
1732
+	 * @throws InvalidArgumentException
1733
+	 * @throws InvalidInterfaceException
1734
+	 * @throws InvalidDataTypeException
1735
+	 * @throws EE_Error
1736
+	 */
1737
+	public function delete_permanently()
1738
+	{
1739
+		/**
1740
+		 * Called just before HARD deleting a model object
1741
+		 *
1742
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1743
+		 */
1744
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1745
+		$model = $this->get_model();
1746
+		$result = $model->delete_permanently_by_ID($this->ID());
1747
+		$this->refresh_cache_of_related_objects();
1748
+		/**
1749
+		 * Called just after HARD deleting a model object
1750
+		 *
1751
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1752
+		 * @param boolean       $result
1753
+		 */
1754
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1755
+		return $result;
1756
+	}
1757
+
1758
+
1759
+	/**
1760
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1761
+	 * related model objects
1762
+	 *
1763
+	 * @throws ReflectionException
1764
+	 * @throws InvalidArgumentException
1765
+	 * @throws InvalidInterfaceException
1766
+	 * @throws InvalidDataTypeException
1767
+	 * @throws EE_Error
1768
+	 */
1769
+	public function refresh_cache_of_related_objects()
1770
+	{
1771
+		$model = $this->get_model();
1772
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1773
+			if (! empty($this->_model_relations[ $relation_name ])) {
1774
+				$related_objects = $this->_model_relations[ $relation_name ];
1775
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1776
+					// this relation only stores a single model object, not an array
1777
+					// but let's make it consistent
1778
+					$related_objects = array($related_objects);
1779
+				}
1780
+				foreach ($related_objects as $related_object) {
1781
+					// only refresh their cache if they're in memory
1782
+					if ($related_object instanceof EE_Base_Class) {
1783
+						$related_object->clear_cache(
1784
+							$model->get_this_model_name(),
1785
+							$this
1786
+						);
1787
+					}
1788
+				}
1789
+			}
1790
+		}
1791
+	}
1792
+
1793
+
1794
+	/**
1795
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1796
+	 * object just before saving.
1797
+	 *
1798
+	 * @access public
1799
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1800
+	 *                                 if provided during the save() method (often client code will change the fields'
1801
+	 *                                 values before calling save)
1802
+	 * @return bool|int|string         1 on a successful update
1803
+	 *                                 the ID of the new entry on insert
1804
+	 *                                 0 on failure or if the model object isn't allowed to persist
1805
+	 *                                 (as determined by EE_Base_Class::allow_persist())
1806
+	 * @throws InvalidInterfaceException
1807
+	 * @throws InvalidDataTypeException
1808
+	 * @throws EE_Error
1809
+	 * @throws InvalidArgumentException
1810
+	 * @throws ReflectionException
1811
+	 * @throws ReflectionException
1812
+	 * @throws ReflectionException
1813
+	 */
1814
+	public function save($set_cols_n_values = array())
1815
+	{
1816
+		$model = $this->get_model();
1817
+		/**
1818
+		 * Filters the fields we're about to save on the model object
1819
+		 *
1820
+		 * @param array         $set_cols_n_values
1821
+		 * @param EE_Base_Class $model_object
1822
+		 */
1823
+		$set_cols_n_values = (array) apply_filters(
1824
+			'FHEE__EE_Base_Class__save__set_cols_n_values',
1825
+			$set_cols_n_values,
1826
+			$this
1827
+		);
1828
+		// set attributes as provided in $set_cols_n_values
1829
+		foreach ($set_cols_n_values as $column => $value) {
1830
+			$this->set($column, $value);
1831
+		}
1832
+		// no changes ? then don't do anything
1833
+		if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1834
+			return 0;
1835
+		}
1836
+		/**
1837
+		 * Saving a model object.
1838
+		 * Before we perform a save, this action is fired.
1839
+		 *
1840
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1841
+		 */
1842
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1843
+		if (! $this->allow_persist()) {
1844
+			return 0;
1845
+		}
1846
+		// now get current attribute values
1847
+		$save_cols_n_values = $this->_fields;
1848
+		// if the object already has an ID, update it. Otherwise, insert it
1849
+		// also: change the assumption about values passed to the model NOT being prepare dby the model object.
1850
+		// They have been
1851
+		$old_assumption_concerning_value_preparation = $model
1852
+			->get_assumption_concerning_values_already_prepared_by_model_object();
1853
+		$model->assume_values_already_prepared_by_model_object(true);
1854
+		// does this model have an autoincrement PK?
1855
+		if ($model->has_primary_key_field()) {
1856
+			if ($model->get_primary_key_field()->is_auto_increment()) {
1857
+				// ok check if it's set, if so: update; if not, insert
1858
+				if (! empty($save_cols_n_values[ $model->primary_key_name() ])) {
1859
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1860
+				} else {
1861
+					unset($save_cols_n_values[ $model->primary_key_name() ]);
1862
+					$results = $model->insert($save_cols_n_values);
1863
+					if ($results) {
1864
+						// if successful, set the primary key
1865
+						// but don't use the normal SET method, because it will check if
1866
+						// an item with the same ID exists in the mapper & db, then
1867
+						// will find it in the db (because we just added it) and THAT object
1868
+						// will get added to the mapper before we can add this one!
1869
+						// but if we just avoid using the SET method, all that headache can be avoided
1870
+						$pk_field_name = $model->primary_key_name();
1871
+						$this->_fields[ $pk_field_name ] = $results;
1872
+						$this->_clear_cached_property($pk_field_name);
1873
+						$model->add_to_entity_map($this);
1874
+						$this->_update_cached_related_model_objs_fks();
1875
+					}
1876
+				}
1877
+			} else {// PK is NOT auto-increment
1878
+				// so check if one like it already exists in the db
1879
+				if ($model->exists_by_ID($this->ID())) {
1880
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1881
+						throw new EE_Error(
1882
+							sprintf(
1883
+								esc_html__(
1884
+									'Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1885
+									'event_espresso'
1886
+								),
1887
+								get_class($this),
1888
+								get_class($model) . '::instance()->add_to_entity_map()',
1889
+								get_class($model) . '::instance()->get_one_by_ID()',
1890
+								'<br />'
1891
+							)
1892
+						);
1893
+					}
1894
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1895
+				} else {
1896
+					$results = $model->insert($save_cols_n_values);
1897
+					$this->_update_cached_related_model_objs_fks();
1898
+				}
1899
+			}
1900
+		} else {// there is NO primary key
1901
+			$already_in_db = false;
1902
+			foreach ($model->unique_indexes() as $index) {
1903
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1904
+				if ($model->exists(array($uniqueness_where_params))) {
1905
+					$already_in_db = true;
1906
+				}
1907
+			}
1908
+			if ($already_in_db) {
1909
+				$combined_pk_fields_n_values = array_intersect_key(
1910
+					$save_cols_n_values,
1911
+					$model->get_combined_primary_key_fields()
1912
+				);
1913
+				$results = $model->update(
1914
+					$save_cols_n_values,
1915
+					$combined_pk_fields_n_values
1916
+				);
1917
+			} else {
1918
+				$results = $model->insert($save_cols_n_values);
1919
+			}
1920
+		}
1921
+		// restore the old assumption about values being prepared by the model object
1922
+		$model->assume_values_already_prepared_by_model_object(
1923
+			$old_assumption_concerning_value_preparation
1924
+		);
1925
+		/**
1926
+		 * After saving the model object this action is called
1927
+		 *
1928
+		 * @param EE_Base_Class $model_object which was just saved
1929
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1930
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1931
+		 */
1932
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1933
+		$this->_has_changes = false;
1934
+		return $results;
1935
+	}
1936
+
1937
+
1938
+	/**
1939
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1940
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1941
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1942
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1943
+	 * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1944
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1945
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1946
+	 *
1947
+	 * @return void
1948
+	 * @throws ReflectionException
1949
+	 * @throws InvalidArgumentException
1950
+	 * @throws InvalidInterfaceException
1951
+	 * @throws InvalidDataTypeException
1952
+	 * @throws EE_Error
1953
+	 */
1954
+	protected function _update_cached_related_model_objs_fks()
1955
+	{
1956
+		$model = $this->get_model();
1957
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1958
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1959
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1960
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1961
+						$model->get_this_model_name()
1962
+					);
1963
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1964
+					if ($related_model_obj_in_cache->ID()) {
1965
+						$related_model_obj_in_cache->save();
1966
+					}
1967
+				}
1968
+			}
1969
+		}
1970
+	}
1971
+
1972
+
1973
+	/**
1974
+	 * Saves this model object and its NEW cached relations to the database.
1975
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1976
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1977
+	 * because otherwise, there's a potential for infinite looping of saving
1978
+	 * Saves the cached related model objects, and ensures the relation between them
1979
+	 * and this object and properly setup
1980
+	 *
1981
+	 * @return int ID of new model object on save; 0 on failure+
1982
+	 * @throws ReflectionException
1983
+	 * @throws InvalidArgumentException
1984
+	 * @throws InvalidInterfaceException
1985
+	 * @throws InvalidDataTypeException
1986
+	 * @throws EE_Error
1987
+	 */
1988
+	public function save_new_cached_related_model_objs()
1989
+	{
1990
+		// make sure this has been saved
1991
+		if (! $this->ID()) {
1992
+			$id = $this->save();
1993
+		} else {
1994
+			$id = $this->ID();
1995
+		}
1996
+		// now save all the NEW cached model objects  (ie they don't exist in the DB)
1997
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1998
+			if ($this->_model_relations[ $relationName ]) {
1999
+				// is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
2000
+				// or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
2001
+				/* @var $related_model_obj EE_Base_Class */
2002
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
2003
+					// add a relation to that relation type (which saves the appropriate thing in the process)
2004
+					// but ONLY if it DOES NOT exist in the DB
2005
+					$related_model_obj = $this->_model_relations[ $relationName ];
2006
+					// if( ! $related_model_obj->ID()){
2007
+					$this->_add_relation_to($related_model_obj, $relationName);
2008
+					$related_model_obj->save_new_cached_related_model_objs();
2009
+					// }
2010
+				} else {
2011
+					foreach ($this->_model_relations[ $relationName ] as $related_model_obj) {
2012
+						// add a relation to that relation type (which saves the appropriate thing in the process)
2013
+						// but ONLY if it DOES NOT exist in the DB
2014
+						// if( ! $related_model_obj->ID()){
2015
+						$this->_add_relation_to($related_model_obj, $relationName);
2016
+						$related_model_obj->save_new_cached_related_model_objs();
2017
+						// }
2018
+					}
2019
+				}
2020
+			}
2021
+		}
2022
+		return $id;
2023
+	}
2024
+
2025
+
2026
+	/**
2027
+	 * for getting a model while instantiated.
2028
+	 *
2029
+	 * @return EEM_Base | EEM_CPT_Base
2030
+	 * @throws ReflectionException
2031
+	 * @throws InvalidArgumentException
2032
+	 * @throws InvalidInterfaceException
2033
+	 * @throws InvalidDataTypeException
2034
+	 * @throws EE_Error
2035
+	 */
2036
+	public function get_model()
2037
+	{
2038
+		if (! $this->_model) {
2039
+			$modelName = self::_get_model_classname(get_class($this));
2040
+			$this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
2041
+		} else {
2042
+			$this->_model->set_timezone($this->_timezone);
2043
+		}
2044
+		return $this->_model;
2045
+	}
2046
+
2047
+
2048
+	/**
2049
+	 * @param $props_n_values
2050
+	 * @param $classname
2051
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
2052
+	 * @throws ReflectionException
2053
+	 * @throws InvalidArgumentException
2054
+	 * @throws InvalidInterfaceException
2055
+	 * @throws InvalidDataTypeException
2056
+	 * @throws EE_Error
2057
+	 */
2058
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
2059
+	{
2060
+		// TODO: will not work for Term_Relationships because they have no PK!
2061
+		$primary_id_ref = self::_get_primary_key_name($classname);
2062
+		if (
2063
+			array_key_exists($primary_id_ref, $props_n_values)
2064
+			&& ! empty($props_n_values[ $primary_id_ref ])
2065
+		) {
2066
+			$id = $props_n_values[ $primary_id_ref ];
2067
+			return self::_get_model($classname)->get_from_entity_map($id);
2068
+		}
2069
+		return false;
2070
+	}
2071
+
2072
+
2073
+	/**
2074
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
2075
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
2076
+	 * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
2077
+	 * we return false.
2078
+	 *
2079
+	 * @param  array  $props_n_values   incoming array of properties and their values
2080
+	 * @param  string $classname        the classname of the child class
2081
+	 * @param null    $timezone
2082
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
2083
+	 *                                  date_format and the second value is the time format
2084
+	 * @return mixed (EE_Base_Class|bool)
2085
+	 * @throws InvalidArgumentException
2086
+	 * @throws InvalidInterfaceException
2087
+	 * @throws InvalidDataTypeException
2088
+	 * @throws EE_Error
2089
+	 * @throws ReflectionException
2090
+	 * @throws ReflectionException
2091
+	 * @throws ReflectionException
2092
+	 */
2093
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
2094
+	{
2095
+		$existing = null;
2096
+		$model = self::_get_model($classname, $timezone);
2097
+		if ($model->has_primary_key_field()) {
2098
+			$primary_id_ref = self::_get_primary_key_name($classname);
2099
+			if (
2100
+				array_key_exists($primary_id_ref, $props_n_values)
2101
+				&& ! empty($props_n_values[ $primary_id_ref ])
2102
+			) {
2103
+				$existing = $model->get_one_by_ID(
2104
+					$props_n_values[ $primary_id_ref ]
2105
+				);
2106
+			}
2107
+		} elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
2108
+			// no primary key on this model, but there's still a matching item in the DB
2109
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
2110
+				self::_get_model($classname, $timezone)
2111
+					->get_index_primary_key_string($props_n_values)
2112
+			);
2113
+		}
2114
+		if ($existing) {
2115
+			// set date formats if present before setting values
2116
+			if (! empty($date_formats) && is_array($date_formats)) {
2117
+				$existing->set_date_format($date_formats[0]);
2118
+				$existing->set_time_format($date_formats[1]);
2119
+			} else {
2120
+				// set default formats for date and time
2121
+				$existing->set_date_format(get_option('date_format'));
2122
+				$existing->set_time_format(get_option('time_format'));
2123
+			}
2124
+			foreach ($props_n_values as $property => $field_value) {
2125
+				$existing->set($property, $field_value);
2126
+			}
2127
+			return $existing;
2128
+		}
2129
+		return false;
2130
+	}
2131
+
2132
+
2133
+	/**
2134
+	 * Gets the EEM_*_Model for this class
2135
+	 *
2136
+	 * @access public now, as this is more convenient
2137
+	 * @param      $classname
2138
+	 * @param null $timezone
2139
+	 * @throws ReflectionException
2140
+	 * @throws InvalidArgumentException
2141
+	 * @throws InvalidInterfaceException
2142
+	 * @throws InvalidDataTypeException
2143
+	 * @throws EE_Error
2144
+	 * @return EEM_Base
2145
+	 */
2146
+	protected static function _get_model($classname, $timezone = null)
2147
+	{
2148
+		// find model for this class
2149
+		if (! $classname) {
2150
+			throw new EE_Error(
2151
+				sprintf(
2152
+					esc_html__(
2153
+						'What were you thinking calling _get_model(%s)?? You need to specify the class name',
2154
+						'event_espresso'
2155
+					),
2156
+					$classname
2157
+				)
2158
+			);
2159
+		}
2160
+		$modelName = self::_get_model_classname($classname);
2161
+		return self::_get_model_instance_with_name($modelName, $timezone);
2162
+	}
2163
+
2164
+
2165
+	/**
2166
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
2167
+	 *
2168
+	 * @param string $model_classname
2169
+	 * @param null   $timezone
2170
+	 * @return EEM_Base
2171
+	 * @throws ReflectionException
2172
+	 * @throws InvalidArgumentException
2173
+	 * @throws InvalidInterfaceException
2174
+	 * @throws InvalidDataTypeException
2175
+	 * @throws EE_Error
2176
+	 */
2177
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
2178
+	{
2179
+		$model_classname = str_replace('EEM_', '', $model_classname);
2180
+		$model = EE_Registry::instance()->load_model($model_classname);
2181
+		$model->set_timezone($timezone);
2182
+		return $model;
2183
+	}
2184
+
2185
+
2186
+	/**
2187
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
2188
+	 * Also works if a model class's classname is provided (eg EE_Registration).
2189
+	 *
2190
+	 * @param null $model_name
2191
+	 * @return string like EEM_Attendee
2192
+	 */
2193
+	private static function _get_model_classname($model_name = null)
2194
+	{
2195
+		if (strpos($model_name, 'EE_') === 0) {
2196
+			$model_classname = str_replace('EE_', 'EEM_', $model_name);
2197
+		} else {
2198
+			$model_classname = 'EEM_' . $model_name;
2199
+		}
2200
+		return $model_classname;
2201
+	}
2202
+
2203
+
2204
+	/**
2205
+	 * returns the name of the primary key attribute
2206
+	 *
2207
+	 * @param null $classname
2208
+	 * @throws ReflectionException
2209
+	 * @throws InvalidArgumentException
2210
+	 * @throws InvalidInterfaceException
2211
+	 * @throws InvalidDataTypeException
2212
+	 * @throws EE_Error
2213
+	 * @return string
2214
+	 */
2215
+	protected static function _get_primary_key_name($classname = null)
2216
+	{
2217
+		if (! $classname) {
2218
+			throw new EE_Error(
2219
+				sprintf(
2220
+					esc_html__('What were you thinking calling _get_primary_key_name(%s)', 'event_espresso'),
2221
+					$classname
2222
+				)
2223
+			);
2224
+		}
2225
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
2226
+	}
2227
+
2228
+
2229
+	/**
2230
+	 * Gets the value of the primary key.
2231
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
2232
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2233
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2234
+	 *
2235
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2236
+	 * @throws ReflectionException
2237
+	 * @throws InvalidArgumentException
2238
+	 * @throws InvalidInterfaceException
2239
+	 * @throws InvalidDataTypeException
2240
+	 * @throws EE_Error
2241
+	 */
2242
+	public function ID()
2243
+	{
2244
+		$model = $this->get_model();
2245
+		// now that we know the name of the variable, use a variable variable to get its value and return its
2246
+		if ($model->has_primary_key_field()) {
2247
+			return $this->_fields[ $model->primary_key_name() ];
2248
+		}
2249
+		return $model->get_index_primary_key_string($this->_fields);
2250
+	}
2251
+
2252
+
2253
+	/**
2254
+	 * @param EE_Base_Class|int|string $otherModelObjectOrID
2255
+	 * @param string                   $relationName
2256
+	 * @return bool
2257
+	 * @throws EE_Error
2258
+	 * @throws ReflectionException
2259
+	 * @since   $VID:$
2260
+	 */
2261
+	public function hasRelation($otherModelObjectOrID, string $relationName): bool
2262
+	{
2263
+		$other_model = self::_get_model_instance_with_name(
2264
+			self::_get_model_classname($relationName),
2265
+			$this->_timezone
2266
+		);
2267
+		$primary_key = $other_model->primary_key_name();
2268
+		/** @var EE_Base_Class $otherModelObject */
2269
+		$otherModelObject = $other_model->ensure_is_obj($otherModelObjectOrID, $relationName);
2270
+		return $this->count_related($relationName, [[$primary_key => $otherModelObject->ID()]]) > 0;
2271
+	}
2272
+
2273
+
2274
+	/**
2275
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2276
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2277
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2278
+	 *
2279
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2280
+	 * @param string $relationName                     eg 'Events','Question',etc.
2281
+	 *                                                 an attendee to a group, you also want to specify which role they
2282
+	 *                                                 will have in that group. So you would use this parameter to
2283
+	 *                                                 specify array('role-column-name'=>'role-id')
2284
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2285
+	 *                                                 allow you to further constrict the relation to being added.
2286
+	 *                                                 However, keep in mind that the columns (keys) given must match a
2287
+	 *                                                 column on the JOIN table and currently only the HABTM models
2288
+	 *                                                 accept these additional conditions.  Also remember that if an
2289
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
2290
+	 *                                                 NEW row is created in the join table.
2291
+	 * @param null   $cache_id
2292
+	 * @throws ReflectionException
2293
+	 * @throws InvalidArgumentException
2294
+	 * @throws InvalidInterfaceException
2295
+	 * @throws InvalidDataTypeException
2296
+	 * @throws EE_Error
2297
+	 * @return EE_Base_Class the object the relation was added to
2298
+	 */
2299
+	public function _add_relation_to(
2300
+		$otherObjectModelObjectOrID,
2301
+		$relationName,
2302
+		$extra_join_model_fields_n_values = array(),
2303
+		$cache_id = null
2304
+	) {
2305
+		$model = $this->get_model();
2306
+		// if this thing exists in the DB, save the relation to the DB
2307
+		if ($this->ID()) {
2308
+			$otherObject = $model->add_relationship_to(
2309
+				$this,
2310
+				$otherObjectModelObjectOrID,
2311
+				$relationName,
2312
+				$extra_join_model_fields_n_values
2313
+			);
2314
+			// clear cache so future get_many_related and get_first_related() return new results.
2315
+			$this->clear_cache($relationName, $otherObject, true);
2316
+			if ($otherObject instanceof EE_Base_Class) {
2317
+				$otherObject->clear_cache($model->get_this_model_name(), $this);
2318
+			}
2319
+		} else {
2320
+			// this thing doesn't exist in the DB,  so just cache it
2321
+			if (! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2322
+				throw new EE_Error(
2323
+					sprintf(
2324
+						esc_html__(
2325
+							'Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2326
+							'event_espresso'
2327
+						),
2328
+						$otherObjectModelObjectOrID,
2329
+						get_class($this)
2330
+					)
2331
+				);
2332
+			}
2333
+			$otherObject = $otherObjectModelObjectOrID;
2334
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2335
+		}
2336
+		if ($otherObject instanceof EE_Base_Class) {
2337
+			// fix the reciprocal relation too
2338
+			if ($otherObject->ID()) {
2339
+				// its saved so assumed relations exist in the DB, so we can just
2340
+				// clear the cache so future queries use the updated info in the DB
2341
+				$otherObject->clear_cache(
2342
+					$model->get_this_model_name(),
2343
+					null,
2344
+					true
2345
+				);
2346
+			} else {
2347
+				// it's not saved, so it caches relations like this
2348
+				$otherObject->cache($model->get_this_model_name(), $this);
2349
+			}
2350
+		}
2351
+		return $otherObject;
2352
+	}
2353
+
2354
+
2355
+	/**
2356
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2357
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2358
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2359
+	 * from the cache
2360
+	 *
2361
+	 * @param mixed  $otherObjectModelObjectOrID
2362
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2363
+	 *                to the DB yet
2364
+	 * @param string $relationName
2365
+	 * @param array  $where_query
2366
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2367
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2368
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2369
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then no row is
2370
+	 *                deleted.
2371
+	 * @return EE_Base_Class the relation was removed from
2372
+	 * @throws ReflectionException
2373
+	 * @throws InvalidArgumentException
2374
+	 * @throws InvalidInterfaceException
2375
+	 * @throws InvalidDataTypeException
2376
+	 * @throws EE_Error
2377
+	 */
2378
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2379
+	{
2380
+		if ($this->ID()) {
2381
+			// if this exists in the DB, save the relation change to the DB too
2382
+			$otherObject = $this->get_model()->remove_relationship_to(
2383
+				$this,
2384
+				$otherObjectModelObjectOrID,
2385
+				$relationName,
2386
+				$where_query
2387
+			);
2388
+			$this->clear_cache(
2389
+				$relationName,
2390
+				$otherObject
2391
+			);
2392
+		} else {
2393
+			// this doesn't exist in the DB, just remove it from the cache
2394
+			$otherObject = $this->clear_cache(
2395
+				$relationName,
2396
+				$otherObjectModelObjectOrID
2397
+			);
2398
+		}
2399
+		if ($otherObject instanceof EE_Base_Class) {
2400
+			$otherObject->clear_cache(
2401
+				$this->get_model()->get_this_model_name(),
2402
+				$this
2403
+			);
2404
+		}
2405
+		return $otherObject;
2406
+	}
2407
+
2408
+
2409
+	/**
2410
+	 * Removes ALL the related things for the $relationName.
2411
+	 *
2412
+	 * @param string $relationName
2413
+	 * @param array  $where_query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
2414
+	 * @return EE_Base_Class
2415
+	 * @throws ReflectionException
2416
+	 * @throws InvalidArgumentException
2417
+	 * @throws InvalidInterfaceException
2418
+	 * @throws InvalidDataTypeException
2419
+	 * @throws EE_Error
2420
+	 */
2421
+	public function _remove_relations($relationName, $where_query_params = array())
2422
+	{
2423
+		if ($this->ID()) {
2424
+			// if this exists in the DB, save the relation change to the DB too
2425
+			$otherObjects = $this->get_model()->remove_relations(
2426
+				$this,
2427
+				$relationName,
2428
+				$where_query_params
2429
+			);
2430
+			$this->clear_cache(
2431
+				$relationName,
2432
+				null,
2433
+				true
2434
+			);
2435
+		} else {
2436
+			// this doesn't exist in the DB, just remove it from the cache
2437
+			$otherObjects = $this->clear_cache(
2438
+				$relationName,
2439
+				null,
2440
+				true
2441
+			);
2442
+		}
2443
+		if (is_array($otherObjects)) {
2444
+			foreach ($otherObjects as $otherObject) {
2445
+				$otherObject->clear_cache(
2446
+					$this->get_model()->get_this_model_name(),
2447
+					$this
2448
+				);
2449
+			}
2450
+		}
2451
+		return $otherObjects;
2452
+	}
2453
+
2454
+
2455
+	/**
2456
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2457
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2458
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2459
+	 * because we want to get even deleted items etc.
2460
+	 *
2461
+	 * @param string $relationName key in the model's _model_relations array
2462
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
2463
+	 * @return EE_Base_Class[]     Results not necessarily indexed by IDs, because some results might not have primary
2464
+	 *                             keys or might not be saved yet. Consider using EEM_Base::get_IDs() on these
2465
+	 *                             results if you want IDs
2466
+	 * @throws ReflectionException
2467
+	 * @throws InvalidArgumentException
2468
+	 * @throws InvalidInterfaceException
2469
+	 * @throws InvalidDataTypeException
2470
+	 * @throws EE_Error
2471
+	 */
2472
+	public function get_many_related($relationName, $query_params = array())
2473
+	{
2474
+		if ($this->ID()) {
2475
+			// this exists in the DB, so get the related things from either the cache or the DB
2476
+			// if there are query parameters, forget about caching the related model objects.
2477
+			if ($query_params) {
2478
+				$related_model_objects = $this->get_model()->get_all_related(
2479
+					$this,
2480
+					$relationName,
2481
+					$query_params
2482
+				);
2483
+			} else {
2484
+				// did we already cache the result of this query?
2485
+				$cached_results = $this->get_all_from_cache($relationName);
2486
+				if (! $cached_results) {
2487
+					$related_model_objects = $this->get_model()->get_all_related(
2488
+						$this,
2489
+						$relationName,
2490
+						$query_params
2491
+					);
2492
+					// if no query parameters were passed, then we got all the related model objects
2493
+					// for that relation. We can cache them then.
2494
+					foreach ($related_model_objects as $related_model_object) {
2495
+						$this->cache($relationName, $related_model_object);
2496
+					}
2497
+				} else {
2498
+					$related_model_objects = $cached_results;
2499
+				}
2500
+			}
2501
+		} else {
2502
+			// this doesn't exist in the DB, so just get the related things from the cache
2503
+			$related_model_objects = $this->get_all_from_cache($relationName);
2504
+		}
2505
+		return $related_model_objects;
2506
+	}
2507
+
2508
+
2509
+	/**
2510
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2511
+	 * unless otherwise specified in the $query_params
2512
+	 *
2513
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2514
+	 * @param array  $query_params   @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2515
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2516
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2517
+	 *                               that by the setting $distinct to TRUE;
2518
+	 * @return int
2519
+	 * @throws ReflectionException
2520
+	 * @throws InvalidArgumentException
2521
+	 * @throws InvalidInterfaceException
2522
+	 * @throws InvalidDataTypeException
2523
+	 * @throws EE_Error
2524
+	 */
2525
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2526
+	{
2527
+		return $this->get_model()->count_related(
2528
+			$this,
2529
+			$relation_name,
2530
+			$query_params,
2531
+			$field_to_count,
2532
+			$distinct
2533
+		);
2534
+	}
2535
+
2536
+
2537
+	/**
2538
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2539
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2540
+	 *
2541
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2542
+	 * @param array  $query_params  @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2543
+	 * @param string $field_to_sum  name of field to count by.
2544
+	 *                              By default, uses primary key
2545
+	 *                              (which doesn't make much sense, so you should probably change it)
2546
+	 * @return int
2547
+	 * @throws ReflectionException
2548
+	 * @throws InvalidArgumentException
2549
+	 * @throws InvalidInterfaceException
2550
+	 * @throws InvalidDataTypeException
2551
+	 * @throws EE_Error
2552
+	 */
2553
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2554
+	{
2555
+		return $this->get_model()->sum_related(
2556
+			$this,
2557
+			$relation_name,
2558
+			$query_params,
2559
+			$field_to_sum
2560
+		);
2561
+	}
2562
+
2563
+
2564
+	/**
2565
+	 * Gets the first (ie, one) related model object of the specified type.
2566
+	 *
2567
+	 * @param string $relationName key in the model's _model_relations array
2568
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2569
+	 * @return EE_Base_Class (not an array, a single object)
2570
+	 * @throws ReflectionException
2571
+	 * @throws InvalidArgumentException
2572
+	 * @throws InvalidInterfaceException
2573
+	 * @throws InvalidDataTypeException
2574
+	 * @throws EE_Error
2575
+	 */
2576
+	public function get_first_related($relationName, $query_params = array())
2577
+	{
2578
+		$model = $this->get_model();
2579
+		if ($this->ID()) {// this exists in the DB, get from the cache OR the DB
2580
+			// if they've provided some query parameters, don't bother trying to cache the result
2581
+			// also make sure we're not caching the result of get_first_related
2582
+			// on a relation which should have an array of objects (because the cache might have an array of objects)
2583
+			if (
2584
+				$query_params
2585
+				|| ! $model->related_settings_for($relationName)
2586
+					 instanceof
2587
+					 EE_Belongs_To_Relation
2588
+			) {
2589
+				$related_model_object = $model->get_first_related(
2590
+					$this,
2591
+					$relationName,
2592
+					$query_params
2593
+				);
2594
+			} else {
2595
+				// first, check if we've already cached the result of this query
2596
+				$cached_result = $this->get_one_from_cache($relationName);
2597
+				if (! $cached_result) {
2598
+					$related_model_object = $model->get_first_related(
2599
+						$this,
2600
+						$relationName,
2601
+						$query_params
2602
+					);
2603
+					$this->cache($relationName, $related_model_object);
2604
+				} else {
2605
+					$related_model_object = $cached_result;
2606
+				}
2607
+			}
2608
+		} else {
2609
+			$related_model_object = null;
2610
+			// this doesn't exist in the Db,
2611
+			// but maybe the relation is of type belongs to, and so the related thing might
2612
+			if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2613
+				$related_model_object = $model->get_first_related(
2614
+					$this,
2615
+					$relationName,
2616
+					$query_params
2617
+				);
2618
+			}
2619
+			// this doesn't exist in the DB and apparently the thing it belongs to doesn't either,
2620
+			// just get what's cached on this object
2621
+			if (! $related_model_object) {
2622
+				$related_model_object = $this->get_one_from_cache($relationName);
2623
+			}
2624
+		}
2625
+		return $related_model_object;
2626
+	}
2627
+
2628
+
2629
+	/**
2630
+	 * Does a delete on all related objects of type $relationName and removes
2631
+	 * the current model object's relation to them. If they can't be deleted (because
2632
+	 * of blocking related model objects) does nothing. If the related model objects are
2633
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2634
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2635
+	 *
2636
+	 * @param string $relationName
2637
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2638
+	 * @return int how many deleted
2639
+	 * @throws ReflectionException
2640
+	 * @throws InvalidArgumentException
2641
+	 * @throws InvalidInterfaceException
2642
+	 * @throws InvalidDataTypeException
2643
+	 * @throws EE_Error
2644
+	 */
2645
+	public function delete_related($relationName, $query_params = array())
2646
+	{
2647
+		if ($this->ID()) {
2648
+			$count = $this->get_model()->delete_related(
2649
+				$this,
2650
+				$relationName,
2651
+				$query_params
2652
+			);
2653
+		} else {
2654
+			$count = count($this->get_all_from_cache($relationName));
2655
+			$this->clear_cache($relationName, null, true);
2656
+		}
2657
+		return $count;
2658
+	}
2659
+
2660
+
2661
+	/**
2662
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2663
+	 * the current model object's relation to them. If they can't be deleted (because
2664
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2665
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2666
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2667
+	 *
2668
+	 * @param string $relationName
2669
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
2670
+	 * @return int how many deleted (including those soft deleted)
2671
+	 * @throws ReflectionException
2672
+	 * @throws InvalidArgumentException
2673
+	 * @throws InvalidInterfaceException
2674
+	 * @throws InvalidDataTypeException
2675
+	 * @throws EE_Error
2676
+	 */
2677
+	public function delete_related_permanently($relationName, $query_params = array())
2678
+	{
2679
+		if ($this->ID()) {
2680
+			$count = $this->get_model()->delete_related_permanently(
2681
+				$this,
2682
+				$relationName,
2683
+				$query_params
2684
+			);
2685
+		} else {
2686
+			$count = count($this->get_all_from_cache($relationName));
2687
+		}
2688
+		$this->clear_cache($relationName, null, true);
2689
+		return $count;
2690
+	}
2691
+
2692
+
2693
+	/**
2694
+	 * is_set
2695
+	 * Just a simple utility function children can use for checking if property exists
2696
+	 *
2697
+	 * @access  public
2698
+	 * @param  string $field_name property to check
2699
+	 * @return bool                              TRUE if existing,FALSE if not.
2700
+	 */
2701
+	public function is_set($field_name)
2702
+	{
2703
+		return isset($this->_fields[ $field_name ]);
2704
+	}
2705
+
2706
+
2707
+	/**
2708
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2709
+	 * EE_Error exception if they don't
2710
+	 *
2711
+	 * @param  mixed (string|array) $properties properties to check
2712
+	 * @throws EE_Error
2713
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2714
+	 */
2715
+	protected function _property_exists($properties)
2716
+	{
2717
+		foreach ((array) $properties as $property_name) {
2718
+			// first make sure this property exists
2719
+			if (! $this->_fields[ $property_name ]) {
2720
+				throw new EE_Error(
2721
+					sprintf(
2722
+						esc_html__(
2723
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2724
+							'event_espresso'
2725
+						),
2726
+						$property_name
2727
+					)
2728
+				);
2729
+			}
2730
+		}
2731
+		return true;
2732
+	}
2733
+
2734
+
2735
+	/**
2736
+	 * This simply returns an array of model fields for this object
2737
+	 *
2738
+	 * @return array
2739
+	 * @throws ReflectionException
2740
+	 * @throws InvalidArgumentException
2741
+	 * @throws InvalidInterfaceException
2742
+	 * @throws InvalidDataTypeException
2743
+	 * @throws EE_Error
2744
+	 */
2745
+	public function model_field_array()
2746
+	{
2747
+		$fields = $this->get_model()->field_settings(false);
2748
+		$properties = array();
2749
+		// remove prepended underscore
2750
+		foreach ($fields as $field_name => $settings) {
2751
+			$properties[ $field_name ] = $this->get($field_name);
2752
+		}
2753
+		return $properties;
2754
+	}
2755
+
2756
+
2757
+	/**
2758
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2759
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2760
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments.
2761
+	 * Instead of requiring a plugin to extend the EE_Base_Class
2762
+	 * (which works fine is there's only 1 plugin, but when will that happen?)
2763
+	 * they can add a hook onto 'filters_hook_espresso__{className}__{methodName}'
2764
+	 * (eg, filters_hook_espresso__EE_Answer__my_great_function)
2765
+	 * and accepts 2 arguments: the object on which the function was called,
2766
+	 * and an array of the original arguments passed to the function.
2767
+	 * Whatever their callback function returns will be returned by this function.
2768
+	 * Example: in functions.php (or in a plugin):
2769
+	 *      add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3);
2770
+	 *      function my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2771
+	 *          $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2772
+	 *          return $previousReturnValue.$returnString;
2773
+	 *      }
2774
+	 * require('EE_Answer.class.php');
2775
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2776
+	 * echo $answer->my_callback('monkeys',100);
2777
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2778
+	 *
2779
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2780
+	 * @param array  $args       array of original arguments passed to the function
2781
+	 * @throws EE_Error
2782
+	 * @return mixed whatever the plugin which calls add_filter decides
2783
+	 */
2784
+	public function __call($methodName, $args)
2785
+	{
2786
+		$className = get_class($this);
2787
+		$tagName = "FHEE__{$className}__{$methodName}";
2788
+		if (! has_filter($tagName)) {
2789
+			throw new EE_Error(
2790
+				sprintf(
2791
+					esc_html__(
2792
+						"Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2793
+						'event_espresso'
2794
+					),
2795
+					$methodName,
2796
+					$className,
2797
+					$tagName
2798
+				)
2799
+			);
2800
+		}
2801
+		return apply_filters($tagName, null, $this, $args);
2802
+	}
2803
+
2804
+
2805
+	/**
2806
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2807
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2808
+	 *
2809
+	 * @param string $meta_key
2810
+	 * @param mixed  $meta_value
2811
+	 * @param mixed  $previous_value
2812
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2813
+	 *                  NOTE: if the values haven't changed, returns 0
2814
+	 * @throws InvalidArgumentException
2815
+	 * @throws InvalidInterfaceException
2816
+	 * @throws InvalidDataTypeException
2817
+	 * @throws EE_Error
2818
+	 * @throws ReflectionException
2819
+	 */
2820
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2821
+	{
2822
+		$query_params = array(
2823
+			array(
2824
+				'EXM_key'  => $meta_key,
2825
+				'OBJ_ID'   => $this->ID(),
2826
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2827
+			),
2828
+		);
2829
+		if ($previous_value !== null) {
2830
+			$query_params[0]['EXM_value'] = $meta_value;
2831
+		}
2832
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2833
+		if (! $existing_rows_like_that) {
2834
+			return $this->add_extra_meta($meta_key, $meta_value);
2835
+		}
2836
+		foreach ($existing_rows_like_that as $existing_row) {
2837
+			$existing_row->save(array('EXM_value' => $meta_value));
2838
+		}
2839
+		return count($existing_rows_like_that);
2840
+	}
2841
+
2842
+
2843
+	/**
2844
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2845
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2846
+	 * extra meta row was entered, false if not
2847
+	 *
2848
+	 * @param string  $meta_key
2849
+	 * @param mixed   $meta_value
2850
+	 * @param boolean $unique
2851
+	 * @return boolean
2852
+	 * @throws InvalidArgumentException
2853
+	 * @throws InvalidInterfaceException
2854
+	 * @throws InvalidDataTypeException
2855
+	 * @throws EE_Error
2856
+	 * @throws ReflectionException
2857
+	 * @throws ReflectionException
2858
+	 */
2859
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2860
+	{
2861
+		if ($unique) {
2862
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2863
+				array(
2864
+					array(
2865
+						'EXM_key'  => $meta_key,
2866
+						'OBJ_ID'   => $this->ID(),
2867
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2868
+					),
2869
+				)
2870
+			);
2871
+			if ($existing_extra_meta) {
2872
+				return false;
2873
+			}
2874
+		}
2875
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2876
+			array(
2877
+				'EXM_key'   => $meta_key,
2878
+				'EXM_value' => $meta_value,
2879
+				'OBJ_ID'    => $this->ID(),
2880
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2881
+			)
2882
+		);
2883
+		$new_extra_meta->save();
2884
+		return true;
2885
+	}
2886
+
2887
+
2888
+	/**
2889
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2890
+	 * is specified, only deletes extra meta records with that value.
2891
+	 *
2892
+	 * @param string $meta_key
2893
+	 * @param mixed  $meta_value
2894
+	 * @return int number of extra meta rows deleted
2895
+	 * @throws InvalidArgumentException
2896
+	 * @throws InvalidInterfaceException
2897
+	 * @throws InvalidDataTypeException
2898
+	 * @throws EE_Error
2899
+	 * @throws ReflectionException
2900
+	 */
2901
+	public function delete_extra_meta($meta_key, $meta_value = null)
2902
+	{
2903
+		$query_params = array(
2904
+			array(
2905
+				'EXM_key'  => $meta_key,
2906
+				'OBJ_ID'   => $this->ID(),
2907
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2908
+			),
2909
+		);
2910
+		if ($meta_value !== null) {
2911
+			$query_params[0]['EXM_value'] = $meta_value;
2912
+		}
2913
+		return EEM_Extra_Meta::instance()->delete($query_params);
2914
+	}
2915
+
2916
+
2917
+	/**
2918
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2919
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2920
+	 * You can specify $default is case you haven't found the extra meta
2921
+	 *
2922
+	 * @param string  $meta_key
2923
+	 * @param boolean $single
2924
+	 * @param mixed   $default if we don't find anything, what should we return?
2925
+	 * @return mixed single value if $single; array if ! $single
2926
+	 * @throws ReflectionException
2927
+	 * @throws InvalidArgumentException
2928
+	 * @throws InvalidInterfaceException
2929
+	 * @throws InvalidDataTypeException
2930
+	 * @throws EE_Error
2931
+	 */
2932
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2933
+	{
2934
+		if ($single) {
2935
+			$result = $this->get_first_related(
2936
+				'Extra_Meta',
2937
+				array(array('EXM_key' => $meta_key))
2938
+			);
2939
+			if ($result instanceof EE_Extra_Meta) {
2940
+				return $result->value();
2941
+			}
2942
+		} else {
2943
+			$results = $this->get_many_related(
2944
+				'Extra_Meta',
2945
+				array(array('EXM_key' => $meta_key))
2946
+			);
2947
+			if ($results) {
2948
+				$values = array();
2949
+				foreach ($results as $result) {
2950
+					if ($result instanceof EE_Extra_Meta) {
2951
+						$values[ $result->ID() ] = $result->value();
2952
+					}
2953
+				}
2954
+				return $values;
2955
+			}
2956
+		}
2957
+		// if nothing discovered yet return default.
2958
+		return apply_filters(
2959
+			'FHEE__EE_Base_Class__get_extra_meta__default_value',
2960
+			$default,
2961
+			$meta_key,
2962
+			$single,
2963
+			$this
2964
+		);
2965
+	}
2966
+
2967
+
2968
+	/**
2969
+	 * Returns a simple array of all the extra meta associated with this model object.
2970
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2971
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2972
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2973
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2974
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2975
+	 * finally the extra meta's value as each sub-value. (eg
2976
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2977
+	 *
2978
+	 * @param boolean $one_of_each_key
2979
+	 * @return array
2980
+	 * @throws ReflectionException
2981
+	 * @throws InvalidArgumentException
2982
+	 * @throws InvalidInterfaceException
2983
+	 * @throws InvalidDataTypeException
2984
+	 * @throws EE_Error
2985
+	 */
2986
+	public function all_extra_meta_array($one_of_each_key = true)
2987
+	{
2988
+		$return_array = array();
2989
+		if ($one_of_each_key) {
2990
+			$extra_meta_objs = $this->get_many_related(
2991
+				'Extra_Meta',
2992
+				array('group_by' => 'EXM_key')
2993
+			);
2994
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2995
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2996
+					$return_array[ $extra_meta_obj->key() ] = $extra_meta_obj->value();
2997
+				}
2998
+			}
2999
+		} else {
3000
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
3001
+			foreach ($extra_meta_objs as $extra_meta_obj) {
3002
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
3003
+					if (! isset($return_array[ $extra_meta_obj->key() ])) {
3004
+						$return_array[ $extra_meta_obj->key() ] = array();
3005
+					}
3006
+					$return_array[ $extra_meta_obj->key() ][ $extra_meta_obj->ID() ] = $extra_meta_obj->value();
3007
+				}
3008
+			}
3009
+		}
3010
+		return $return_array;
3011
+	}
3012
+
3013
+
3014
+	/**
3015
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
3016
+	 *
3017
+	 * @return string
3018
+	 * @throws ReflectionException
3019
+	 * @throws InvalidArgumentException
3020
+	 * @throws InvalidInterfaceException
3021
+	 * @throws InvalidDataTypeException
3022
+	 * @throws EE_Error
3023
+	 */
3024
+	public function name()
3025
+	{
3026
+		// find a field that's not a text field
3027
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
3028
+		if ($field_we_can_use) {
3029
+			return $this->get($field_we_can_use->get_name());
3030
+		}
3031
+		$first_few_properties = $this->model_field_array();
3032
+		$first_few_properties = array_slice($first_few_properties, 0, 3);
3033
+		$name_parts = array();
3034
+		foreach ($first_few_properties as $name => $value) {
3035
+			$name_parts[] = "$name:$value";
3036
+		}
3037
+		return implode(',', $name_parts);
3038
+	}
3039
+
3040
+
3041
+	/**
3042
+	 * in_entity_map
3043
+	 * Checks if this model object has been proven to already be in the entity map
3044
+	 *
3045
+	 * @return boolean
3046
+	 * @throws ReflectionException
3047
+	 * @throws InvalidArgumentException
3048
+	 * @throws InvalidInterfaceException
3049
+	 * @throws InvalidDataTypeException
3050
+	 * @throws EE_Error
3051
+	 */
3052
+	public function in_entity_map()
3053
+	{
3054
+		// well, if we looked, did we find it in the entity map?
3055
+		return $this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this;
3056
+	}
3057
+
3058
+
3059
+	/**
3060
+	 * refresh_from_db
3061
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
3062
+	 *
3063
+	 * @throws ReflectionException
3064
+	 * @throws InvalidArgumentException
3065
+	 * @throws InvalidInterfaceException
3066
+	 * @throws InvalidDataTypeException
3067
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
3068
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
3069
+	 */
3070
+	public function refresh_from_db()
3071
+	{
3072
+		if ($this->ID() && $this->in_entity_map()) {
3073
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
3074
+		} else {
3075
+			// if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
3076
+			// if it has an ID but it's not in the map, and you're asking me to refresh it
3077
+			// that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
3078
+			// absolutely nothing in it for this ID
3079
+			if (WP_DEBUG) {
3080
+				throw new EE_Error(
3081
+					sprintf(
3082
+						esc_html__(
3083
+							'Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
3084
+							'event_espresso'
3085
+						),
3086
+						$this->ID(),
3087
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
3088
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
3089
+					)
3090
+				);
3091
+			}
3092
+		}
3093
+	}
3094
+
3095
+
3096
+	/**
3097
+	 * Change $fields' values to $new_value_sql (which is a string of raw SQL)
3098
+	 *
3099
+	 * @since 4.9.80.p
3100
+	 * @param EE_Model_Field_Base[] $fields
3101
+	 * @param string $new_value_sql
3102
+	 *      example: 'column_name=123',
3103
+	 *      or 'column_name=column_name+1',
3104
+	 *      or 'column_name= CASE
3105
+	 *          WHEN (`column_name` + `other_column` + 5) <= `yet_another_column`
3106
+	 *          THEN `column_name` + 5
3107
+	 *          ELSE `column_name`
3108
+	 *      END'
3109
+	 *      Also updates $field on this model object with the latest value from the database.
3110
+	 * @return bool
3111
+	 * @throws EE_Error
3112
+	 * @throws InvalidArgumentException
3113
+	 * @throws InvalidDataTypeException
3114
+	 * @throws InvalidInterfaceException
3115
+	 * @throws ReflectionException
3116
+	 */
3117
+	protected function updateFieldsInDB($fields, $new_value_sql)
3118
+	{
3119
+		// First make sure this model object actually exists in the DB. It would be silly to try to update it in the DB
3120
+		// if it wasn't even there to start off.
3121
+		if (! $this->ID()) {
3122
+			$this->save();
3123
+		}
3124
+		global $wpdb;
3125
+		if (empty($fields)) {
3126
+			throw new InvalidArgumentException(
3127
+				esc_html__(
3128
+					'EE_Base_Class::updateFieldsInDB was passed an empty array of fields.',
3129
+					'event_espresso'
3130
+				)
3131
+			);
3132
+		}
3133
+		$first_field = reset($fields);
3134
+		$table_alias = $first_field->get_table_alias();
3135
+		foreach ($fields as $field) {
3136
+			if ($table_alias !== $field->get_table_alias()) {
3137
+				throw new InvalidArgumentException(
3138
+					sprintf(
3139
+						esc_html__(
3140
+							// @codingStandardsIgnoreStart
3141
+							'EE_Base_Class::updateFieldsInDB was passed fields for different tables ("%1$s" and "%2$s"), which is not supported. Instead, please call the method multiple times.',
3142
+							// @codingStandardsIgnoreEnd
3143
+							'event_espresso'
3144
+						),
3145
+						$table_alias,
3146
+						$field->get_table_alias()
3147
+					)
3148
+				);
3149
+			}
3150
+		}
3151
+		// Ok the fields are now known to all be for the same table. Proceed with creating the SQL to update it.
3152
+		$table_obj = $this->get_model()->get_table_obj_by_alias($table_alias);
3153
+		$table_pk_value = $this->ID();
3154
+		$table_name = $table_obj->get_table_name();
3155
+		if ($table_obj instanceof EE_Secondary_Table) {
3156
+			$table_pk_field_name = $table_obj->get_fk_on_table();
3157
+		} else {
3158
+			$table_pk_field_name = $table_obj->get_pk_column();
3159
+		}
3160
+
3161
+		$query =
3162
+			"UPDATE `{$table_name}`
3163 3163
             SET "
3164
-            . $new_value_sql
3165
-            . $wpdb->prepare(
3166
-                "
3164
+			. $new_value_sql
3165
+			. $wpdb->prepare(
3166
+				"
3167 3167
             WHERE `{$table_pk_field_name}` = %d;",
3168
-                $table_pk_value
3169
-            );
3170
-        $result = $wpdb->query($query);
3171
-        foreach ($fields as $field) {
3172
-            // If it was successful, we'd like to know the new value.
3173
-            // If it failed, we'd also like to know the new value.
3174
-            $new_value = $this->get_model()->get_var(
3175
-                $this->get_model()->alter_query_params_to_restrict_by_ID(
3176
-                    $this->get_model()->get_index_primary_key_string(
3177
-                        $this->model_field_array()
3178
-                    ),
3179
-                    array(
3180
-                        'default_where_conditions' => 'minimum',
3181
-                    )
3182
-                ),
3183
-                $field->get_name()
3184
-            );
3185
-            $this->set_from_db(
3186
-                $field->get_name(),
3187
-                $new_value
3188
-            );
3189
-        }
3190
-        return (bool) $result;
3191
-    }
3192
-
3193
-
3194
-    /**
3195
-     * Nudges $field_name's value by $quantity, without any conditionals (in comparison to bumpConditionally()).
3196
-     * Does not allow negative values, however.
3197
-     *
3198
-     * @since 4.9.80.p
3199
-     * @param array $fields_n_quantities keys are the field names, and values are the amount by which to bump them
3200
-     *                                   (positive or negative). One important gotcha: all these values must be
3201
-     *                                   on the same table (eg don't pass in one field for the posts table and
3202
-     *                                   another for the event meta table.)
3203
-     * @return bool
3204
-     * @throws EE_Error
3205
-     * @throws InvalidArgumentException
3206
-     * @throws InvalidDataTypeException
3207
-     * @throws InvalidInterfaceException
3208
-     * @throws ReflectionException
3209
-     */
3210
-    public function adjustNumericFieldsInDb(array $fields_n_quantities)
3211
-    {
3212
-        global $wpdb;
3213
-        if (empty($fields_n_quantities)) {
3214
-            // No fields to update? Well sure, we updated them to that value just fine.
3215
-            return true;
3216
-        }
3217
-        $fields = [];
3218
-        $set_sql_statements = [];
3219
-        foreach ($fields_n_quantities as $field_name => $quantity) {
3220
-            $field = $this->get_model()->field_settings_for($field_name, true);
3221
-            $fields[] = $field;
3222
-            $column_name = $field->get_table_column();
3223
-
3224
-            $abs_qty = absint($quantity);
3225
-            if ($quantity > 0) {
3226
-                // don't let the value be negative as often these fields are unsigned
3227
-                $set_sql_statements[] = $wpdb->prepare(
3228
-                    "`{$column_name}` = `{$column_name}` + %d",
3229
-                    $abs_qty
3230
-                );
3231
-            } else {
3232
-                $set_sql_statements[] = $wpdb->prepare(
3233
-                    "`{$column_name}` = CASE
3168
+				$table_pk_value
3169
+			);
3170
+		$result = $wpdb->query($query);
3171
+		foreach ($fields as $field) {
3172
+			// If it was successful, we'd like to know the new value.
3173
+			// If it failed, we'd also like to know the new value.
3174
+			$new_value = $this->get_model()->get_var(
3175
+				$this->get_model()->alter_query_params_to_restrict_by_ID(
3176
+					$this->get_model()->get_index_primary_key_string(
3177
+						$this->model_field_array()
3178
+					),
3179
+					array(
3180
+						'default_where_conditions' => 'minimum',
3181
+					)
3182
+				),
3183
+				$field->get_name()
3184
+			);
3185
+			$this->set_from_db(
3186
+				$field->get_name(),
3187
+				$new_value
3188
+			);
3189
+		}
3190
+		return (bool) $result;
3191
+	}
3192
+
3193
+
3194
+	/**
3195
+	 * Nudges $field_name's value by $quantity, without any conditionals (in comparison to bumpConditionally()).
3196
+	 * Does not allow negative values, however.
3197
+	 *
3198
+	 * @since 4.9.80.p
3199
+	 * @param array $fields_n_quantities keys are the field names, and values are the amount by which to bump them
3200
+	 *                                   (positive or negative). One important gotcha: all these values must be
3201
+	 *                                   on the same table (eg don't pass in one field for the posts table and
3202
+	 *                                   another for the event meta table.)
3203
+	 * @return bool
3204
+	 * @throws EE_Error
3205
+	 * @throws InvalidArgumentException
3206
+	 * @throws InvalidDataTypeException
3207
+	 * @throws InvalidInterfaceException
3208
+	 * @throws ReflectionException
3209
+	 */
3210
+	public function adjustNumericFieldsInDb(array $fields_n_quantities)
3211
+	{
3212
+		global $wpdb;
3213
+		if (empty($fields_n_quantities)) {
3214
+			// No fields to update? Well sure, we updated them to that value just fine.
3215
+			return true;
3216
+		}
3217
+		$fields = [];
3218
+		$set_sql_statements = [];
3219
+		foreach ($fields_n_quantities as $field_name => $quantity) {
3220
+			$field = $this->get_model()->field_settings_for($field_name, true);
3221
+			$fields[] = $field;
3222
+			$column_name = $field->get_table_column();
3223
+
3224
+			$abs_qty = absint($quantity);
3225
+			if ($quantity > 0) {
3226
+				// don't let the value be negative as often these fields are unsigned
3227
+				$set_sql_statements[] = $wpdb->prepare(
3228
+					"`{$column_name}` = `{$column_name}` + %d",
3229
+					$abs_qty
3230
+				);
3231
+			} else {
3232
+				$set_sql_statements[] = $wpdb->prepare(
3233
+					"`{$column_name}` = CASE
3234 3234
                        WHEN (`{$column_name}` >= %d)
3235 3235
                        THEN `{$column_name}` - %d
3236 3236
                        ELSE 0
3237 3237
                     END",
3238
-                    $abs_qty,
3239
-                    $abs_qty
3240
-                );
3241
-            }
3242
-        }
3243
-        return $this->updateFieldsInDB(
3244
-            $fields,
3245
-            implode(', ', $set_sql_statements)
3246
-        );
3247
-    }
3248
-
3249
-
3250
-    /**
3251
-     * Increases the value of the field $field_name_to_bump by $quantity, but only if the values of
3252
-     * $field_name_to_bump plus $field_name_affecting_total and $quantity won't exceed $limit_field_name's value.
3253
-     * For example, this is useful when bumping the value of TKT_reserved, TKT_sold, DTT_reserved or DTT_sold.
3254
-     * Returns true if the value was successfully bumped, and updates the value on this model object.
3255
-     * Otherwise returns false.
3256
-     *
3257
-     * @since 4.9.80.p
3258
-     * @param string $field_name_to_bump
3259
-     * @param string $field_name_affecting_total
3260
-     * @param string $limit_field_name
3261
-     * @param int    $quantity
3262
-     * @return bool
3263
-     * @throws EE_Error
3264
-     * @throws InvalidArgumentException
3265
-     * @throws InvalidDataTypeException
3266
-     * @throws InvalidInterfaceException
3267
-     * @throws ReflectionException
3268
-     */
3269
-    public function incrementFieldConditionallyInDb($field_name_to_bump, $field_name_affecting_total, $limit_field_name, $quantity)
3270
-    {
3271
-        global $wpdb;
3272
-        $field = $this->get_model()->field_settings_for($field_name_to_bump, true);
3273
-        $column_name = $field->get_table_column();
3274
-
3275
-        $field_affecting_total = $this->get_model()->field_settings_for($field_name_affecting_total, true);
3276
-        $column_affecting_total = $field_affecting_total->get_table_column();
3277
-
3278
-        $limiting_field = $this->get_model()->field_settings_for($limit_field_name, true);
3279
-        $limiting_column = $limiting_field->get_table_column();
3280
-        return $this->updateFieldsInDB(
3281
-            [$field],
3282
-            $wpdb->prepare(
3283
-                "`{$column_name}` =
3238
+					$abs_qty,
3239
+					$abs_qty
3240
+				);
3241
+			}
3242
+		}
3243
+		return $this->updateFieldsInDB(
3244
+			$fields,
3245
+			implode(', ', $set_sql_statements)
3246
+		);
3247
+	}
3248
+
3249
+
3250
+	/**
3251
+	 * Increases the value of the field $field_name_to_bump by $quantity, but only if the values of
3252
+	 * $field_name_to_bump plus $field_name_affecting_total and $quantity won't exceed $limit_field_name's value.
3253
+	 * For example, this is useful when bumping the value of TKT_reserved, TKT_sold, DTT_reserved or DTT_sold.
3254
+	 * Returns true if the value was successfully bumped, and updates the value on this model object.
3255
+	 * Otherwise returns false.
3256
+	 *
3257
+	 * @since 4.9.80.p
3258
+	 * @param string $field_name_to_bump
3259
+	 * @param string $field_name_affecting_total
3260
+	 * @param string $limit_field_name
3261
+	 * @param int    $quantity
3262
+	 * @return bool
3263
+	 * @throws EE_Error
3264
+	 * @throws InvalidArgumentException
3265
+	 * @throws InvalidDataTypeException
3266
+	 * @throws InvalidInterfaceException
3267
+	 * @throws ReflectionException
3268
+	 */
3269
+	public function incrementFieldConditionallyInDb($field_name_to_bump, $field_name_affecting_total, $limit_field_name, $quantity)
3270
+	{
3271
+		global $wpdb;
3272
+		$field = $this->get_model()->field_settings_for($field_name_to_bump, true);
3273
+		$column_name = $field->get_table_column();
3274
+
3275
+		$field_affecting_total = $this->get_model()->field_settings_for($field_name_affecting_total, true);
3276
+		$column_affecting_total = $field_affecting_total->get_table_column();
3277
+
3278
+		$limiting_field = $this->get_model()->field_settings_for($limit_field_name, true);
3279
+		$limiting_column = $limiting_field->get_table_column();
3280
+		return $this->updateFieldsInDB(
3281
+			[$field],
3282
+			$wpdb->prepare(
3283
+				"`{$column_name}` =
3284 3284
             CASE
3285 3285
                WHEN ((`{$column_name}` + `{$column_affecting_total}` + %d) <= `{$limiting_column}`) OR `{$limiting_column}` = %d
3286 3286
                THEN `{$column_name}` + %d
3287 3287
                ELSE `{$column_name}`
3288 3288
             END",
3289
-                $quantity,
3290
-                EE_INF_IN_DB,
3291
-                $quantity
3292
-            )
3293
-        );
3294
-    }
3295
-
3296
-
3297
-    /**
3298
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
3299
-     * (probably a bad assumption they have made, oh well)
3300
-     *
3301
-     * @return string
3302
-     */
3303
-    public function __toString()
3304
-    {
3305
-        try {
3306
-            return sprintf('%s (%s)', $this->name(), $this->ID());
3307
-        } catch (Exception $e) {
3308
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
3309
-            return '';
3310
-        }
3311
-    }
3312
-
3313
-
3314
-    /**
3315
-     * Clear related model objects if they're already in the DB, because otherwise when we
3316
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
3317
-     * This means if we have made changes to those related model objects, and want to unserialize
3318
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
3319
-     * Instead, those related model objects should be directly serialized and stored.
3320
-     * Eg, the following won't work:
3321
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
3322
-     * $att = $reg->attendee();
3323
-     * $att->set( 'ATT_fname', 'Dirk' );
3324
-     * update_option( 'my_option', serialize( $reg ) );
3325
-     * //END REQUEST
3326
-     * //START NEXT REQUEST
3327
-     * $reg = get_option( 'my_option' );
3328
-     * $reg->attendee()->save();
3329
-     * And would need to be replace with:
3330
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
3331
-     * $att = $reg->attendee();
3332
-     * $att->set( 'ATT_fname', 'Dirk' );
3333
-     * update_option( 'my_option', serialize( $reg ) );
3334
-     * //END REQUEST
3335
-     * //START NEXT REQUEST
3336
-     * $att = get_option( 'my_option' );
3337
-     * $att->save();
3338
-     *
3339
-     * @return array
3340
-     * @throws ReflectionException
3341
-     * @throws InvalidArgumentException
3342
-     * @throws InvalidInterfaceException
3343
-     * @throws InvalidDataTypeException
3344
-     * @throws EE_Error
3345
-     */
3346
-    public function __sleep()
3347
-    {
3348
-        $model = $this->get_model();
3349
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
3350
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
3351
-                $classname = 'EE_' . $model->get_this_model_name();
3352
-                if (
3353
-                    $this->get_one_from_cache($relation_name) instanceof $classname
3354
-                    && $this->get_one_from_cache($relation_name)->ID()
3355
-                ) {
3356
-                    $this->clear_cache(
3357
-                        $relation_name,
3358
-                        $this->get_one_from_cache($relation_name)->ID()
3359
-                    );
3360
-                }
3361
-            }
3362
-        }
3363
-        $this->_props_n_values_provided_in_constructor = array();
3364
-        $properties_to_serialize = get_object_vars($this);
3365
-        // don't serialize the model. It's big and that risks recursion
3366
-        unset($properties_to_serialize['_model']);
3367
-        return array_keys($properties_to_serialize);
3368
-    }
3369
-
3370
-
3371
-    /**
3372
-     * restore _props_n_values_provided_in_constructor
3373
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
3374
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
3375
-     * At best, you would only be able to detect if state change has occurred during THIS request.
3376
-     */
3377
-    public function __wakeup()
3378
-    {
3379
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
3380
-    }
3381
-
3382
-
3383
-    /**
3384
-     * Usage of this magic method is to ensure any internally cached references to object instances that must remain
3385
-     * distinct with the clone host instance are also cloned.
3386
-     */
3387
-    public function __clone()
3388
-    {
3389
-        // handle DateTimes (this is handled in here because there's no one specific child class that uses datetimes).
3390
-        foreach ($this->_fields as $field => $value) {
3391
-            if ($value instanceof DateTime) {
3392
-                $this->_fields[ $field ] = clone $value;
3393
-            }
3394
-        }
3395
-    }
3289
+				$quantity,
3290
+				EE_INF_IN_DB,
3291
+				$quantity
3292
+			)
3293
+		);
3294
+	}
3295
+
3296
+
3297
+	/**
3298
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
3299
+	 * (probably a bad assumption they have made, oh well)
3300
+	 *
3301
+	 * @return string
3302
+	 */
3303
+	public function __toString()
3304
+	{
3305
+		try {
3306
+			return sprintf('%s (%s)', $this->name(), $this->ID());
3307
+		} catch (Exception $e) {
3308
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
3309
+			return '';
3310
+		}
3311
+	}
3312
+
3313
+
3314
+	/**
3315
+	 * Clear related model objects if they're already in the DB, because otherwise when we
3316
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
3317
+	 * This means if we have made changes to those related model objects, and want to unserialize
3318
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
3319
+	 * Instead, those related model objects should be directly serialized and stored.
3320
+	 * Eg, the following won't work:
3321
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
3322
+	 * $att = $reg->attendee();
3323
+	 * $att->set( 'ATT_fname', 'Dirk' );
3324
+	 * update_option( 'my_option', serialize( $reg ) );
3325
+	 * //END REQUEST
3326
+	 * //START NEXT REQUEST
3327
+	 * $reg = get_option( 'my_option' );
3328
+	 * $reg->attendee()->save();
3329
+	 * And would need to be replace with:
3330
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
3331
+	 * $att = $reg->attendee();
3332
+	 * $att->set( 'ATT_fname', 'Dirk' );
3333
+	 * update_option( 'my_option', serialize( $reg ) );
3334
+	 * //END REQUEST
3335
+	 * //START NEXT REQUEST
3336
+	 * $att = get_option( 'my_option' );
3337
+	 * $att->save();
3338
+	 *
3339
+	 * @return array
3340
+	 * @throws ReflectionException
3341
+	 * @throws InvalidArgumentException
3342
+	 * @throws InvalidInterfaceException
3343
+	 * @throws InvalidDataTypeException
3344
+	 * @throws EE_Error
3345
+	 */
3346
+	public function __sleep()
3347
+	{
3348
+		$model = $this->get_model();
3349
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
3350
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
3351
+				$classname = 'EE_' . $model->get_this_model_name();
3352
+				if (
3353
+					$this->get_one_from_cache($relation_name) instanceof $classname
3354
+					&& $this->get_one_from_cache($relation_name)->ID()
3355
+				) {
3356
+					$this->clear_cache(
3357
+						$relation_name,
3358
+						$this->get_one_from_cache($relation_name)->ID()
3359
+					);
3360
+				}
3361
+			}
3362
+		}
3363
+		$this->_props_n_values_provided_in_constructor = array();
3364
+		$properties_to_serialize = get_object_vars($this);
3365
+		// don't serialize the model. It's big and that risks recursion
3366
+		unset($properties_to_serialize['_model']);
3367
+		return array_keys($properties_to_serialize);
3368
+	}
3369
+
3370
+
3371
+	/**
3372
+	 * restore _props_n_values_provided_in_constructor
3373
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
3374
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
3375
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
3376
+	 */
3377
+	public function __wakeup()
3378
+	{
3379
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
3380
+	}
3381
+
3382
+
3383
+	/**
3384
+	 * Usage of this magic method is to ensure any internally cached references to object instances that must remain
3385
+	 * distinct with the clone host instance are also cloned.
3386
+	 */
3387
+	public function __clone()
3388
+	{
3389
+		// handle DateTimes (this is handled in here because there's no one specific child class that uses datetimes).
3390
+		foreach ($this->_fields as $field => $value) {
3391
+			if ($value instanceof DateTime) {
3392
+				$this->_fields[ $field ] = clone $value;
3393
+			}
3394
+		}
3395
+	}
3396 3396
 }
Please login to merge, or discard this patch.
Spacing   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
         $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
147 147
         // verify client code has not passed any invalid field names
148 148
         foreach ($fieldValues as $field_name => $field_value) {
149
-            if (! isset($model_fields[ $field_name ])) {
149
+            if ( ! isset($model_fields[$field_name])) {
150 150
                 throw new EE_Error(
151 151
                     sprintf(
152 152
                         esc_html__(
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
             }
162 162
         }
163 163
         $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
164
-        if (! empty($date_formats) && is_array($date_formats)) {
164
+        if ( ! empty($date_formats) && is_array($date_formats)) {
165 165
             [$this->_dt_frmt, $this->_tm_frmt] = $date_formats;
166 166
         } else {
167 167
             // set default formats for date and time
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
             foreach ($model_fields as $fieldName => $field) {
175 175
                 $this->set_from_db(
176 176
                     $fieldName,
177
-                    isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null
177
+                    isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null
178 178
                 );
179 179
             }
180 180
         } else {
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
             foreach ($model_fields as $fieldName => $field) {
184 184
                 $this->set(
185 185
                     $fieldName,
186
-                    isset($fieldValues[ $fieldName ]) ? $fieldValues[ $fieldName ] : null,
186
+                    isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null,
187 187
                     true
188 188
                 );
189 189
             }
@@ -191,15 +191,15 @@  discard block
 block discarded – undo
191 191
         // remember what values were passed to this constructor
192 192
         $this->_props_n_values_provided_in_constructor = $fieldValues;
193 193
         // remember in entity mapper
194
-        if (! $bydb && $model->has_primary_key_field() && $this->ID()) {
194
+        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
195 195
             $model->add_to_entity_map($this);
196 196
         }
197 197
         // setup all the relations
198 198
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
199 199
             if ($relation_obj instanceof EE_Belongs_To_Relation) {
200
-                $this->_model_relations[ $relation_name ] = null;
200
+                $this->_model_relations[$relation_name] = null;
201 201
             } else {
202
-                $this->_model_relations[ $relation_name ] = array();
202
+                $this->_model_relations[$relation_name] = array();
203 203
             }
204 204
         }
205 205
         /**
@@ -251,10 +251,10 @@  discard block
 block discarded – undo
251 251
     public function get_original($field_name)
252 252
     {
253 253
         if (
254
-            isset($this->_props_n_values_provided_in_constructor[ $field_name ])
254
+            isset($this->_props_n_values_provided_in_constructor[$field_name])
255 255
             && $field_settings = $this->get_model()->field_settings_for($field_name)
256 256
         ) {
257
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[ $field_name ]);
257
+            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
258 258
         }
259 259
         return null;
260 260
     }
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
         // then don't do anything
292 292
         if (
293 293
             ! $use_default
294
-            && $this->_fields[ $field_name ] === $field_value
294
+            && $this->_fields[$field_name] === $field_value
295 295
             && $this->ID()
296 296
         ) {
297 297
             return;
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
             $holder_of_value = $field_obj->prepare_for_set($field_value);
310 310
             // should the value be null?
311 311
             if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
312
-                $this->_fields[ $field_name ] = $field_obj->get_default_value();
312
+                $this->_fields[$field_name] = $field_obj->get_default_value();
313 313
                 /**
314 314
                  * To save having to refactor all the models, if a default value is used for a
315 315
                  * EE_Datetime_Field, and that value is not null nor is it a DateTime
@@ -320,15 +320,15 @@  discard block
 block discarded – undo
320 320
                  */
321 321
                 if (
322 322
                     $field_obj instanceof EE_Datetime_Field
323
-                    && $this->_fields[ $field_name ] !== null
324
-                    && ! $this->_fields[ $field_name ] instanceof DateTime
323
+                    && $this->_fields[$field_name] !== null
324
+                    && ! $this->_fields[$field_name] instanceof DateTime
325 325
                 ) {
326
-                    empty($this->_fields[ $field_name ])
326
+                    empty($this->_fields[$field_name])
327 327
                         ? $this->set($field_name, time())
328
-                        : $this->set($field_name, $this->_fields[ $field_name ]);
328
+                        : $this->set($field_name, $this->_fields[$field_name]);
329 329
                 }
330 330
             } else {
331
-                $this->_fields[ $field_name ] = $holder_of_value;
331
+                $this->_fields[$field_name] = $holder_of_value;
332 332
             }
333 333
             // if we're not in the constructor...
334 334
             // now check if what we set was a primary key
@@ -391,8 +391,8 @@  discard block
 block discarded – undo
391 391
      */
392 392
     public function getCustomSelect($alias)
393 393
     {
394
-        return isset($this->custom_selection_results[ $alias ])
395
-            ? $this->custom_selection_results[ $alias ]
394
+        return isset($this->custom_selection_results[$alias])
395
+            ? $this->custom_selection_results[$alias]
396 396
             : null;
397 397
     }
398 398
 
@@ -479,8 +479,8 @@  discard block
 block discarded – undo
479 479
         foreach ($model_fields as $field_name => $field_obj) {
480 480
             if ($field_obj instanceof EE_Datetime_Field) {
481 481
                 $field_obj->set_timezone($this->_timezone);
482
-                if (isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime) {
483
-                    EEH_DTT_Helper::setTimezone($this->_fields[ $field_name ], new DateTimeZone($this->_timezone));
482
+                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
483
+                    EEH_DTT_Helper::setTimezone($this->_fields[$field_name], new DateTimeZone($this->_timezone));
484 484
                 }
485 485
             }
486 486
         }
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
      */
539 539
     public function get_format($full = true)
540 540
     {
541
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
541
+        return $full ? $this->_dt_frmt.' '.$this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
542 542
     }
543 543
 
544 544
 
@@ -564,11 +564,11 @@  discard block
 block discarded – undo
564 564
     public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
565 565
     {
566 566
         // its entirely possible that there IS no related object yet in which case there is nothing to cache.
567
-        if (! $object_to_cache instanceof EE_Base_Class) {
567
+        if ( ! $object_to_cache instanceof EE_Base_Class) {
568 568
             return false;
569 569
         }
570 570
         // also get "how" the object is related, or throw an error
571
-        if (! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
571
+        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
572 572
             throw new EE_Error(
573 573
                 sprintf(
574 574
                     esc_html__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
@@ -582,38 +582,38 @@  discard block
 block discarded – undo
582 582
             // if it's a "belongs to" relationship, then there's only one related model object
583 583
             // eg, if this is a registration, there's only 1 attendee for it
584 584
             // so for these model objects just set it to be cached
585
-            $this->_model_relations[ $relationName ] = $object_to_cache;
585
+            $this->_model_relations[$relationName] = $object_to_cache;
586 586
             $return = true;
587 587
         } else {
588 588
             // otherwise, this is the "many" side of a one to many relationship,
589 589
             // so we'll add the object to the array of related objects for that type.
590 590
             // eg: if this is an event, there are many registrations for that event,
591 591
             // so we cache the registrations in an array
592
-            if (! is_array($this->_model_relations[ $relationName ])) {
592
+            if ( ! is_array($this->_model_relations[$relationName])) {
593 593
                 // if for some reason, the cached item is a model object,
594 594
                 // then stick that in the array, otherwise start with an empty array
595
-                $this->_model_relations[ $relationName ] = $this->_model_relations[ $relationName ]
595
+                $this->_model_relations[$relationName] = $this->_model_relations[$relationName]
596 596
                                                            instanceof
597 597
                                                            EE_Base_Class
598
-                    ? array($this->_model_relations[ $relationName ]) : array();
598
+                    ? array($this->_model_relations[$relationName]) : array();
599 599
             }
600 600
             // first check for a cache_id which is normally empty
601
-            if (! empty($cache_id)) {
601
+            if ( ! empty($cache_id)) {
602 602
                 // if the cache_id exists, then it means we are purposely trying to cache this
603 603
                 // with a known key that can then be used to retrieve the object later on
604
-                $this->_model_relations[ $relationName ][ $cache_id ] = $object_to_cache;
604
+                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
605 605
                 $return = $cache_id;
606 606
             } elseif ($object_to_cache->ID()) {
607 607
                 // OR the cached object originally came from the db, so let's just use it's PK for an ID
608
-                $this->_model_relations[ $relationName ][ $object_to_cache->ID() ] = $object_to_cache;
608
+                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
609 609
                 $return = $object_to_cache->ID();
610 610
             } else {
611 611
                 // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
612
-                $this->_model_relations[ $relationName ][] = $object_to_cache;
612
+                $this->_model_relations[$relationName][] = $object_to_cache;
613 613
                 // move the internal pointer to the end of the array
614
-                end($this->_model_relations[ $relationName ]);
614
+                end($this->_model_relations[$relationName]);
615 615
                 // and grab the key so that we can return it
616
-                $return = key($this->_model_relations[ $relationName ]);
616
+                $return = key($this->_model_relations[$relationName]);
617 617
             }
618 618
         }
619 619
         return $return;
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
         // first make sure this property exists
640 640
         $this->get_model()->field_settings_for($fieldname);
641 641
         $cache_type = empty($cache_type) ? 'standard' : $cache_type;
642
-        $this->_cached_properties[ $fieldname ][ $cache_type ] = $value;
642
+        $this->_cached_properties[$fieldname][$cache_type] = $value;
643 643
     }
644 644
 
645 645
 
@@ -668,9 +668,9 @@  discard block
 block discarded – undo
668 668
         $model = $this->get_model();
669 669
         $model->field_settings_for($fieldname);
670 670
         $cache_type = $pretty ? 'pretty' : 'standard';
671
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
672
-        if (isset($this->_cached_properties[ $fieldname ][ $cache_type ])) {
673
-            return $this->_cached_properties[ $fieldname ][ $cache_type ];
671
+        $cache_type .= ! empty($extra_cache_ref) ? '_'.$extra_cache_ref : '';
672
+        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
673
+            return $this->_cached_properties[$fieldname][$cache_type];
674 674
         }
675 675
         $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
676 676
         $this->_set_cached_property($fieldname, $value, $cache_type);
@@ -698,12 +698,12 @@  discard block
 block discarded – undo
698 698
         if ($field_obj instanceof EE_Datetime_Field) {
699 699
             $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
700 700
         }
701
-        if (! isset($this->_fields[ $fieldname ])) {
702
-            $this->_fields[ $fieldname ] = null;
701
+        if ( ! isset($this->_fields[$fieldname])) {
702
+            $this->_fields[$fieldname] = null;
703 703
         }
704 704
         $value = $pretty
705
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[ $fieldname ], $extra_cache_ref)
706
-            : $field_obj->prepare_for_get($this->_fields[ $fieldname ]);
705
+            ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
706
+            : $field_obj->prepare_for_get($this->_fields[$fieldname]);
707 707
         return $value;
708 708
     }
709 709
 
@@ -761,8 +761,8 @@  discard block
 block discarded – undo
761 761
      */
762 762
     protected function _clear_cached_property($property_name)
763 763
     {
764
-        if (isset($this->_cached_properties[ $property_name ])) {
765
-            unset($this->_cached_properties[ $property_name ]);
764
+        if (isset($this->_cached_properties[$property_name])) {
765
+            unset($this->_cached_properties[$property_name]);
766 766
         }
767 767
     }
768 768
 
@@ -814,7 +814,7 @@  discard block
 block discarded – undo
814 814
     {
815 815
         $relationship_to_model = $this->get_model()->related_settings_for($relationName);
816 816
         $index_in_cache = '';
817
-        if (! $relationship_to_model) {
817
+        if ( ! $relationship_to_model) {
818 818
             throw new EE_Error(
819 819
                 sprintf(
820 820
                     esc_html__('There is no relationship to %s on a %s. Cannot clear that cache', 'event_espresso'),
@@ -825,10 +825,10 @@  discard block
 block discarded – undo
825 825
         }
826 826
         if ($clear_all) {
827 827
             $obj_removed = true;
828
-            $this->_model_relations[ $relationName ] = null;
828
+            $this->_model_relations[$relationName] = null;
829 829
         } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
830
-            $obj_removed = $this->_model_relations[ $relationName ];
831
-            $this->_model_relations[ $relationName ] = null;
830
+            $obj_removed = $this->_model_relations[$relationName];
831
+            $this->_model_relations[$relationName] = null;
832 832
         } else {
833 833
             if (
834 834
                 $object_to_remove_or_index_into_array instanceof EE_Base_Class
@@ -836,12 +836,12 @@  discard block
 block discarded – undo
836 836
             ) {
837 837
                 $index_in_cache = $object_to_remove_or_index_into_array->ID();
838 838
                 if (
839
-                    is_array($this->_model_relations[ $relationName ])
840
-                    && ! isset($this->_model_relations[ $relationName ][ $index_in_cache ])
839
+                    is_array($this->_model_relations[$relationName])
840
+                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
841 841
                 ) {
842 842
                     $index_found_at = null;
843 843
                     // find this object in the array even though it has a different key
844
-                    foreach ($this->_model_relations[ $relationName ] as $index => $obj) {
844
+                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
845 845
                         /** @noinspection TypeUnsafeComparisonInspection */
846 846
                         if (
847 847
                             $obj instanceof EE_Base_Class
@@ -875,9 +875,9 @@  discard block
 block discarded – undo
875 875
             }
876 876
             // supposedly we've found it. But it could just be that the client code
877 877
             // provided a bad index/object
878
-            if (isset($this->_model_relations[ $relationName ][ $index_in_cache ])) {
879
-                $obj_removed = $this->_model_relations[ $relationName ][ $index_in_cache ];
880
-                unset($this->_model_relations[ $relationName ][ $index_in_cache ]);
878
+            if (isset($this->_model_relations[$relationName][$index_in_cache])) {
879
+                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
880
+                unset($this->_model_relations[$relationName][$index_in_cache]);
881 881
             } else {
882 882
                 // that thing was never cached anyways.
883 883
                 $obj_removed = null;
@@ -908,7 +908,7 @@  discard block
 block discarded – undo
908 908
         $current_cache_id = ''
909 909
     ) {
910 910
         // verify that incoming object is of the correct type
911
-        $obj_class = 'EE_' . $relationName;
911
+        $obj_class = 'EE_'.$relationName;
912 912
         if ($newly_saved_object instanceof $obj_class) {
913 913
             /* @type EE_Base_Class $newly_saved_object */
914 914
             // now get the type of relation
@@ -916,18 +916,18 @@  discard block
 block discarded – undo
916 916
             // if this is a 1:1 relationship
917 917
             if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
918 918
                 // then just replace the cached object with the newly saved object
919
-                $this->_model_relations[ $relationName ] = $newly_saved_object;
919
+                $this->_model_relations[$relationName] = $newly_saved_object;
920 920
                 return true;
921 921
                 // or if it's some kind of sordid feral polyamorous relationship...
922 922
             }
923 923
             if (
924
-                is_array($this->_model_relations[ $relationName ])
925
-                && isset($this->_model_relations[ $relationName ][ $current_cache_id ])
924
+                is_array($this->_model_relations[$relationName])
925
+                && isset($this->_model_relations[$relationName][$current_cache_id])
926 926
             ) {
927 927
                 // then remove the current cached item
928
-                unset($this->_model_relations[ $relationName ][ $current_cache_id ]);
928
+                unset($this->_model_relations[$relationName][$current_cache_id]);
929 929
                 // and cache the newly saved object using it's new ID
930
-                $this->_model_relations[ $relationName ][ $newly_saved_object->ID() ] = $newly_saved_object;
930
+                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
931 931
                 return true;
932 932
             }
933 933
         }
@@ -944,8 +944,8 @@  discard block
 block discarded – undo
944 944
      */
945 945
     public function get_one_from_cache($relationName)
946 946
     {
947
-        $cached_array_or_object = isset($this->_model_relations[ $relationName ])
948
-            ? $this->_model_relations[ $relationName ]
947
+        $cached_array_or_object = isset($this->_model_relations[$relationName])
948
+            ? $this->_model_relations[$relationName]
949 949
             : null;
950 950
         if (is_array($cached_array_or_object)) {
951 951
             return array_shift($cached_array_or_object);
@@ -968,7 +968,7 @@  discard block
 block discarded – undo
968 968
      */
969 969
     public function get_all_from_cache($relationName)
970 970
     {
971
-        $objects = isset($this->_model_relations[ $relationName ]) ? $this->_model_relations[ $relationName ] : array();
971
+        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
972 972
         // if the result is not an array, but exists, make it an array
973 973
         $objects = is_array($objects) ? $objects : array($objects);
974 974
         // bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
@@ -1152,7 +1152,7 @@  discard block
 block discarded – undo
1152 1152
             } else {
1153 1153
                 $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1154 1154
             }
1155
-            $this->_fields[ $field_name ] = $field_value;
1155
+            $this->_fields[$field_name] = $field_value;
1156 1156
             $this->_clear_cached_property($field_name);
1157 1157
         }
1158 1158
     }
@@ -1192,9 +1192,9 @@  discard block
 block discarded – undo
1192 1192
     public function get_raw($field_name)
1193 1193
     {
1194 1194
         $field_settings = $this->get_model()->field_settings_for($field_name);
1195
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[ $field_name ] instanceof DateTime
1196
-            ? $this->_fields[ $field_name ]->format('U')
1197
-            : $this->_fields[ $field_name ];
1195
+        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1196
+            ? $this->_fields[$field_name]->format('U')
1197
+            : $this->_fields[$field_name];
1198 1198
     }
1199 1199
 
1200 1200
 
@@ -1216,7 +1216,7 @@  discard block
 block discarded – undo
1216 1216
     public function get_DateTime_object($field_name)
1217 1217
     {
1218 1218
         $field_settings = $this->get_model()->field_settings_for($field_name);
1219
-        if (! $field_settings instanceof EE_Datetime_Field) {
1219
+        if ( ! $field_settings instanceof EE_Datetime_Field) {
1220 1220
             EE_Error::add_error(
1221 1221
                 sprintf(
1222 1222
                     esc_html__(
@@ -1231,8 +1231,8 @@  discard block
 block discarded – undo
1231 1231
             );
1232 1232
             return false;
1233 1233
         }
1234
-        return isset($this->_fields[ $field_name ]) && $this->_fields[ $field_name ] instanceof DateTime
1235
-            ? clone $this->_fields[ $field_name ]
1234
+        return isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime
1235
+            ? clone $this->_fields[$field_name]
1236 1236
             : null;
1237 1237
     }
1238 1238
 
@@ -1474,7 +1474,7 @@  discard block
 block discarded – undo
1474 1474
      */
1475 1475
     public function get_i18n_datetime($field_name, $format = '')
1476 1476
     {
1477
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1477
+        $format = empty($format) ? $this->_dt_frmt.' '.$this->_tm_frmt : $format;
1478 1478
         return date_i18n(
1479 1479
             $format,
1480 1480
             EEH_DTT_Helper::get_timestamp_with_offset(
@@ -1586,21 +1586,21 @@  discard block
 block discarded – undo
1586 1586
         $field->set_time_format($this->_tm_frmt);
1587 1587
         switch ($what) {
1588 1588
             case 'T':
1589
-                $this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_time(
1589
+                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1590 1590
                     $datetime_value,
1591
-                    $this->_fields[ $fieldname ]
1591
+                    $this->_fields[$fieldname]
1592 1592
                 );
1593 1593
                 $this->_has_changes = true;
1594 1594
                 break;
1595 1595
             case 'D':
1596
-                $this->_fields[ $fieldname ] = $field->prepare_for_set_with_new_date(
1596
+                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1597 1597
                     $datetime_value,
1598
-                    $this->_fields[ $fieldname ]
1598
+                    $this->_fields[$fieldname]
1599 1599
                 );
1600 1600
                 $this->_has_changes = true;
1601 1601
                 break;
1602 1602
             case 'B':
1603
-                $this->_fields[ $fieldname ] = $field->prepare_for_set($datetime_value);
1603
+                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1604 1604
                 $this->_has_changes = true;
1605 1605
                 break;
1606 1606
         }
@@ -1643,7 +1643,7 @@  discard block
 block discarded – undo
1643 1643
         $this->set_timezone($timezone);
1644 1644
         $fn = (array) $field_name;
1645 1645
         $args = array_merge($fn, (array) $args);
1646
-        if (! method_exists($this, $callback)) {
1646
+        if ( ! method_exists($this, $callback)) {
1647 1647
             throw new EE_Error(
1648 1648
                 sprintf(
1649 1649
                     esc_html__(
@@ -1655,7 +1655,7 @@  discard block
 block discarded – undo
1655 1655
             );
1656 1656
         }
1657 1657
         $args = (array) $args;
1658
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1658
+        $return = $prepend.call_user_func_array(array($this, $callback), $args).$append;
1659 1659
         $this->set_timezone($original_timezone);
1660 1660
         return $return;
1661 1661
     }
@@ -1770,8 +1770,8 @@  discard block
 block discarded – undo
1770 1770
     {
1771 1771
         $model = $this->get_model();
1772 1772
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1773
-            if (! empty($this->_model_relations[ $relation_name ])) {
1774
-                $related_objects = $this->_model_relations[ $relation_name ];
1773
+            if ( ! empty($this->_model_relations[$relation_name])) {
1774
+                $related_objects = $this->_model_relations[$relation_name];
1775 1775
                 if ($relation_obj instanceof EE_Belongs_To_Relation) {
1776 1776
                     // this relation only stores a single model object, not an array
1777 1777
                     // but let's make it consistent
@@ -1830,7 +1830,7 @@  discard block
 block discarded – undo
1830 1830
             $this->set($column, $value);
1831 1831
         }
1832 1832
         // no changes ? then don't do anything
1833
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1833
+        if ( ! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1834 1834
             return 0;
1835 1835
         }
1836 1836
         /**
@@ -1840,7 +1840,7 @@  discard block
 block discarded – undo
1840 1840
          * @param EE_Base_Class $model_object the model object about to be saved.
1841 1841
          */
1842 1842
         do_action('AHEE__EE_Base_Class__save__begin', $this);
1843
-        if (! $this->allow_persist()) {
1843
+        if ( ! $this->allow_persist()) {
1844 1844
             return 0;
1845 1845
         }
1846 1846
         // now get current attribute values
@@ -1855,10 +1855,10 @@  discard block
 block discarded – undo
1855 1855
         if ($model->has_primary_key_field()) {
1856 1856
             if ($model->get_primary_key_field()->is_auto_increment()) {
1857 1857
                 // ok check if it's set, if so: update; if not, insert
1858
-                if (! empty($save_cols_n_values[ $model->primary_key_name() ])) {
1858
+                if ( ! empty($save_cols_n_values[$model->primary_key_name()])) {
1859 1859
                     $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1860 1860
                 } else {
1861
-                    unset($save_cols_n_values[ $model->primary_key_name() ]);
1861
+                    unset($save_cols_n_values[$model->primary_key_name()]);
1862 1862
                     $results = $model->insert($save_cols_n_values);
1863 1863
                     if ($results) {
1864 1864
                         // if successful, set the primary key
@@ -1868,7 +1868,7 @@  discard block
 block discarded – undo
1868 1868
                         // will get added to the mapper before we can add this one!
1869 1869
                         // but if we just avoid using the SET method, all that headache can be avoided
1870 1870
                         $pk_field_name = $model->primary_key_name();
1871
-                        $this->_fields[ $pk_field_name ] = $results;
1871
+                        $this->_fields[$pk_field_name] = $results;
1872 1872
                         $this->_clear_cached_property($pk_field_name);
1873 1873
                         $model->add_to_entity_map($this);
1874 1874
                         $this->_update_cached_related_model_objs_fks();
@@ -1885,8 +1885,8 @@  discard block
 block discarded – undo
1885 1885
                                     'event_espresso'
1886 1886
                                 ),
1887 1887
                                 get_class($this),
1888
-                                get_class($model) . '::instance()->add_to_entity_map()',
1889
-                                get_class($model) . '::instance()->get_one_by_ID()',
1888
+                                get_class($model).'::instance()->add_to_entity_map()',
1889
+                                get_class($model).'::instance()->get_one_by_ID()',
1890 1890
                                 '<br />'
1891 1891
                             )
1892 1892
                         );
@@ -1988,27 +1988,27 @@  discard block
 block discarded – undo
1988 1988
     public function save_new_cached_related_model_objs()
1989 1989
     {
1990 1990
         // make sure this has been saved
1991
-        if (! $this->ID()) {
1991
+        if ( ! $this->ID()) {
1992 1992
             $id = $this->save();
1993 1993
         } else {
1994 1994
             $id = $this->ID();
1995 1995
         }
1996 1996
         // now save all the NEW cached model objects  (ie they don't exist in the DB)
1997 1997
         foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1998
-            if ($this->_model_relations[ $relationName ]) {
1998
+            if ($this->_model_relations[$relationName]) {
1999 1999
                 // is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
2000 2000
                 // or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
2001 2001
                 /* @var $related_model_obj EE_Base_Class */
2002 2002
                 if ($relationObj instanceof EE_Belongs_To_Relation) {
2003 2003
                     // add a relation to that relation type (which saves the appropriate thing in the process)
2004 2004
                     // but ONLY if it DOES NOT exist in the DB
2005
-                    $related_model_obj = $this->_model_relations[ $relationName ];
2005
+                    $related_model_obj = $this->_model_relations[$relationName];
2006 2006
                     // if( ! $related_model_obj->ID()){
2007 2007
                     $this->_add_relation_to($related_model_obj, $relationName);
2008 2008
                     $related_model_obj->save_new_cached_related_model_objs();
2009 2009
                     // }
2010 2010
                 } else {
2011
-                    foreach ($this->_model_relations[ $relationName ] as $related_model_obj) {
2011
+                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
2012 2012
                         // add a relation to that relation type (which saves the appropriate thing in the process)
2013 2013
                         // but ONLY if it DOES NOT exist in the DB
2014 2014
                         // if( ! $related_model_obj->ID()){
@@ -2035,7 +2035,7 @@  discard block
 block discarded – undo
2035 2035
      */
2036 2036
     public function get_model()
2037 2037
     {
2038
-        if (! $this->_model) {
2038
+        if ( ! $this->_model) {
2039 2039
             $modelName = self::_get_model_classname(get_class($this));
2040 2040
             $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
2041 2041
         } else {
@@ -2061,9 +2061,9 @@  discard block
 block discarded – undo
2061 2061
         $primary_id_ref = self::_get_primary_key_name($classname);
2062 2062
         if (
2063 2063
             array_key_exists($primary_id_ref, $props_n_values)
2064
-            && ! empty($props_n_values[ $primary_id_ref ])
2064
+            && ! empty($props_n_values[$primary_id_ref])
2065 2065
         ) {
2066
-            $id = $props_n_values[ $primary_id_ref ];
2066
+            $id = $props_n_values[$primary_id_ref];
2067 2067
             return self::_get_model($classname)->get_from_entity_map($id);
2068 2068
         }
2069 2069
         return false;
@@ -2098,10 +2098,10 @@  discard block
 block discarded – undo
2098 2098
             $primary_id_ref = self::_get_primary_key_name($classname);
2099 2099
             if (
2100 2100
                 array_key_exists($primary_id_ref, $props_n_values)
2101
-                && ! empty($props_n_values[ $primary_id_ref ])
2101
+                && ! empty($props_n_values[$primary_id_ref])
2102 2102
             ) {
2103 2103
                 $existing = $model->get_one_by_ID(
2104
-                    $props_n_values[ $primary_id_ref ]
2104
+                    $props_n_values[$primary_id_ref]
2105 2105
                 );
2106 2106
             }
2107 2107
         } elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
@@ -2113,7 +2113,7 @@  discard block
 block discarded – undo
2113 2113
         }
2114 2114
         if ($existing) {
2115 2115
             // set date formats if present before setting values
2116
-            if (! empty($date_formats) && is_array($date_formats)) {
2116
+            if ( ! empty($date_formats) && is_array($date_formats)) {
2117 2117
                 $existing->set_date_format($date_formats[0]);
2118 2118
                 $existing->set_time_format($date_formats[1]);
2119 2119
             } else {
@@ -2146,7 +2146,7 @@  discard block
 block discarded – undo
2146 2146
     protected static function _get_model($classname, $timezone = null)
2147 2147
     {
2148 2148
         // find model for this class
2149
-        if (! $classname) {
2149
+        if ( ! $classname) {
2150 2150
             throw new EE_Error(
2151 2151
                 sprintf(
2152 2152
                     esc_html__(
@@ -2195,7 +2195,7 @@  discard block
 block discarded – undo
2195 2195
         if (strpos($model_name, 'EE_') === 0) {
2196 2196
             $model_classname = str_replace('EE_', 'EEM_', $model_name);
2197 2197
         } else {
2198
-            $model_classname = 'EEM_' . $model_name;
2198
+            $model_classname = 'EEM_'.$model_name;
2199 2199
         }
2200 2200
         return $model_classname;
2201 2201
     }
@@ -2214,7 +2214,7 @@  discard block
 block discarded – undo
2214 2214
      */
2215 2215
     protected static function _get_primary_key_name($classname = null)
2216 2216
     {
2217
-        if (! $classname) {
2217
+        if ( ! $classname) {
2218 2218
             throw new EE_Error(
2219 2219
                 sprintf(
2220 2220
                     esc_html__('What were you thinking calling _get_primary_key_name(%s)', 'event_espresso'),
@@ -2244,7 +2244,7 @@  discard block
 block discarded – undo
2244 2244
         $model = $this->get_model();
2245 2245
         // now that we know the name of the variable, use a variable variable to get its value and return its
2246 2246
         if ($model->has_primary_key_field()) {
2247
-            return $this->_fields[ $model->primary_key_name() ];
2247
+            return $this->_fields[$model->primary_key_name()];
2248 2248
         }
2249 2249
         return $model->get_index_primary_key_string($this->_fields);
2250 2250
     }
@@ -2318,7 +2318,7 @@  discard block
 block discarded – undo
2318 2318
             }
2319 2319
         } else {
2320 2320
             // this thing doesn't exist in the DB,  so just cache it
2321
-            if (! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2321
+            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2322 2322
                 throw new EE_Error(
2323 2323
                     sprintf(
2324 2324
                         esc_html__(
@@ -2483,7 +2483,7 @@  discard block
 block discarded – undo
2483 2483
             } else {
2484 2484
                 // did we already cache the result of this query?
2485 2485
                 $cached_results = $this->get_all_from_cache($relationName);
2486
-                if (! $cached_results) {
2486
+                if ( ! $cached_results) {
2487 2487
                     $related_model_objects = $this->get_model()->get_all_related(
2488 2488
                         $this,
2489 2489
                         $relationName,
@@ -2594,7 +2594,7 @@  discard block
 block discarded – undo
2594 2594
             } else {
2595 2595
                 // first, check if we've already cached the result of this query
2596 2596
                 $cached_result = $this->get_one_from_cache($relationName);
2597
-                if (! $cached_result) {
2597
+                if ( ! $cached_result) {
2598 2598
                     $related_model_object = $model->get_first_related(
2599 2599
                         $this,
2600 2600
                         $relationName,
@@ -2618,7 +2618,7 @@  discard block
 block discarded – undo
2618 2618
             }
2619 2619
             // this doesn't exist in the DB and apparently the thing it belongs to doesn't either,
2620 2620
             // just get what's cached on this object
2621
-            if (! $related_model_object) {
2621
+            if ( ! $related_model_object) {
2622 2622
                 $related_model_object = $this->get_one_from_cache($relationName);
2623 2623
             }
2624 2624
         }
@@ -2700,7 +2700,7 @@  discard block
 block discarded – undo
2700 2700
      */
2701 2701
     public function is_set($field_name)
2702 2702
     {
2703
-        return isset($this->_fields[ $field_name ]);
2703
+        return isset($this->_fields[$field_name]);
2704 2704
     }
2705 2705
 
2706 2706
 
@@ -2716,7 +2716,7 @@  discard block
 block discarded – undo
2716 2716
     {
2717 2717
         foreach ((array) $properties as $property_name) {
2718 2718
             // first make sure this property exists
2719
-            if (! $this->_fields[ $property_name ]) {
2719
+            if ( ! $this->_fields[$property_name]) {
2720 2720
                 throw new EE_Error(
2721 2721
                     sprintf(
2722 2722
                         esc_html__(
@@ -2748,7 +2748,7 @@  discard block
 block discarded – undo
2748 2748
         $properties = array();
2749 2749
         // remove prepended underscore
2750 2750
         foreach ($fields as $field_name => $settings) {
2751
-            $properties[ $field_name ] = $this->get($field_name);
2751
+            $properties[$field_name] = $this->get($field_name);
2752 2752
         }
2753 2753
         return $properties;
2754 2754
     }
@@ -2785,7 +2785,7 @@  discard block
 block discarded – undo
2785 2785
     {
2786 2786
         $className = get_class($this);
2787 2787
         $tagName = "FHEE__{$className}__{$methodName}";
2788
-        if (! has_filter($tagName)) {
2788
+        if ( ! has_filter($tagName)) {
2789 2789
             throw new EE_Error(
2790 2790
                 sprintf(
2791 2791
                     esc_html__(
@@ -2830,7 +2830,7 @@  discard block
 block discarded – undo
2830 2830
             $query_params[0]['EXM_value'] = $meta_value;
2831 2831
         }
2832 2832
         $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2833
-        if (! $existing_rows_like_that) {
2833
+        if ( ! $existing_rows_like_that) {
2834 2834
             return $this->add_extra_meta($meta_key, $meta_value);
2835 2835
         }
2836 2836
         foreach ($existing_rows_like_that as $existing_row) {
@@ -2948,7 +2948,7 @@  discard block
 block discarded – undo
2948 2948
                 $values = array();
2949 2949
                 foreach ($results as $result) {
2950 2950
                     if ($result instanceof EE_Extra_Meta) {
2951
-                        $values[ $result->ID() ] = $result->value();
2951
+                        $values[$result->ID()] = $result->value();
2952 2952
                     }
2953 2953
                 }
2954 2954
                 return $values;
@@ -2993,17 +2993,17 @@  discard block
 block discarded – undo
2993 2993
             );
2994 2994
             foreach ($extra_meta_objs as $extra_meta_obj) {
2995 2995
                 if ($extra_meta_obj instanceof EE_Extra_Meta) {
2996
-                    $return_array[ $extra_meta_obj->key() ] = $extra_meta_obj->value();
2996
+                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2997 2997
                 }
2998 2998
             }
2999 2999
         } else {
3000 3000
             $extra_meta_objs = $this->get_many_related('Extra_Meta');
3001 3001
             foreach ($extra_meta_objs as $extra_meta_obj) {
3002 3002
                 if ($extra_meta_obj instanceof EE_Extra_Meta) {
3003
-                    if (! isset($return_array[ $extra_meta_obj->key() ])) {
3004
-                        $return_array[ $extra_meta_obj->key() ] = array();
3003
+                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
3004
+                        $return_array[$extra_meta_obj->key()] = array();
3005 3005
                     }
3006
-                    $return_array[ $extra_meta_obj->key() ][ $extra_meta_obj->ID() ] = $extra_meta_obj->value();
3006
+                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
3007 3007
                 }
3008 3008
             }
3009 3009
         }
@@ -3084,8 +3084,8 @@  discard block
 block discarded – undo
3084 3084
                             'event_espresso'
3085 3085
                         ),
3086 3086
                         $this->ID(),
3087
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
3088
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
3087
+                        get_class($this->get_model()).'::instance()->add_to_entity_map()',
3088
+                        get_class($this->get_model()).'::instance()->refresh_entity_map()'
3089 3089
                     )
3090 3090
                 );
3091 3091
             }
@@ -3118,7 +3118,7 @@  discard block
 block discarded – undo
3118 3118
     {
3119 3119
         // First make sure this model object actually exists in the DB. It would be silly to try to update it in the DB
3120 3120
         // if it wasn't even there to start off.
3121
-        if (! $this->ID()) {
3121
+        if ( ! $this->ID()) {
3122 3122
             $this->save();
3123 3123
         }
3124 3124
         global $wpdb;
@@ -3348,7 +3348,7 @@  discard block
 block discarded – undo
3348 3348
         $model = $this->get_model();
3349 3349
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
3350 3350
             if ($relation_obj instanceof EE_Belongs_To_Relation) {
3351
-                $classname = 'EE_' . $model->get_this_model_name();
3351
+                $classname = 'EE_'.$model->get_this_model_name();
3352 3352
                 if (
3353 3353
                     $this->get_one_from_cache($relation_name) instanceof $classname
3354 3354
                     && $this->get_one_from_cache($relation_name)->ID()
@@ -3389,7 +3389,7 @@  discard block
 block discarded – undo
3389 3389
         // handle DateTimes (this is handled in here because there's no one specific child class that uses datetimes).
3390 3390
         foreach ($this->_fields as $field => $value) {
3391 3391
             if ($value instanceof DateTime) {
3392
-                $this->_fields[ $field ] = clone $value;
3392
+                $this->_fields[$field] = clone $value;
3393 3393
             }
3394 3394
         }
3395 3395
     }
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket.class.php 1 patch
Indentation   +2086 added lines, -2086 removed lines patch added patch discarded remove patch
@@ -14,2094 +14,2094 @@
 block discarded – undo
14 14
 class EE_Ticket extends EE_Soft_Delete_Base_Class implements EEI_Line_Item_Object, EEI_Event_Relation, EEI_Has_Icon
15 15
 {
16 16
 
17
-    /**
18
-     * TicKet Sold out:
19
-     * constant used by ticket_status() to indicate that a ticket is sold out
20
-     * and no longer available for purchases
21
-     */
22
-    const sold_out = 'TKS';
23
-
24
-    /**
25
-     * TicKet Expired:
26
-     * constant used by ticket_status() to indicate that a ticket is expired
27
-     * and no longer available for purchase
28
-     */
29
-    const expired = 'TKE';
30
-
31
-    /**
32
-     * TicKet Archived:
33
-     * constant used by ticket_status() to indicate that a ticket is archived
34
-     * and no longer available for purchase
35
-     */
36
-    const archived = 'TKA';
37
-
38
-    /**
39
-     * TicKet Pending:
40
-     * constant used by ticket_status() to indicate that a ticket is pending
41
-     * and is NOT YET available for purchase
42
-     */
43
-    const pending = 'TKP';
44
-
45
-    /**
46
-     * TicKet On sale:
47
-     * constant used by ticket_status() to indicate that a ticket is On Sale
48
-     * and IS available for purchase
49
-     */
50
-    const onsale = 'TKO';
51
-
52
-    /**
53
-     * extra meta key for tracking ticket reservations
54
-     *
55
-     * @type string
56
-     */
57
-    const META_KEY_TICKET_RESERVATIONS = 'ticket_reservations';
58
-
59
-    /**
60
-     * override of parent property
61
-     *
62
-     * @var EEM_Ticket
63
-     */
64
-    protected $_model;
65
-
66
-    /**
67
-     * cached result from method of the same name
68
-     *
69
-     * @var float $_ticket_total_with_taxes
70
-     */
71
-    private $_ticket_total_with_taxes;
72
-
73
-
74
-    /**
75
-     * @param array  $props_n_values          incoming values
76
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
77
-     *                                        used.)
78
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
79
-     *                                        date_format and the second value is the time format
80
-     * @return EE_Ticket
81
-     * @throws EE_Error
82
-     * @throws ReflectionException
83
-     */
84
-    public static function new_instance($props_n_values = [], $timezone = null, $date_formats = [])
85
-    {
86
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
87
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
88
-    }
89
-
90
-
91
-    /**
92
-     * @param array  $props_n_values  incoming values from the database
93
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
94
-     *                                the website will be used.
95
-     * @return EE_Ticket
96
-     * @throws EE_Error
97
-     * @throws ReflectionException
98
-     */
99
-    public static function new_instance_from_db($props_n_values = [], $timezone = null)
100
-    {
101
-        return new self($props_n_values, true, $timezone);
102
-    }
103
-
104
-
105
-    /**
106
-     * @return bool
107
-     * @throws EE_Error
108
-     * @throws ReflectionException
109
-     */
110
-    public function parent()
111
-    {
112
-        return $this->get('TKT_parent');
113
-    }
114
-
115
-
116
-    /**
117
-     * return if a ticket has quantities available for purchase
118
-     *
119
-     * @param int $DTT_ID the primary key for a particular datetime
120
-     * @return boolean
121
-     * @throws EE_Error
122
-     * @throws ReflectionException
123
-     */
124
-    public function available($DTT_ID = 0)
125
-    {
126
-        // are we checking availability for a particular datetime ?
127
-        if ($DTT_ID) {
128
-            // get that datetime object
129
-            $datetime = $this->get_first_related('Datetime', [['DTT_ID' => $DTT_ID]]);
130
-            // if  ticket sales for this datetime have exceeded the reg limit...
131
-            if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
132
-                return false;
133
-            }
134
-        }
135
-        // datetime is still open for registration, but is this ticket sold out ?
136
-        return $this->qty() < 1 || $this->qty() > $this->sold();
137
-    }
138
-
139
-
140
-    /**
141
-     * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
142
-     *
143
-     * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the
144
-     *                               relevant status const
145
-     * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save
146
-     *                               further processing
147
-     * @return mixed status int if the display string isn't requested
148
-     * @throws EE_Error
149
-     * @throws ReflectionException
150
-     */
151
-    public function ticket_status($display = false, $remaining = null)
152
-    {
153
-        $remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
154
-        if (! $remaining) {
155
-            return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out;
156
-        }
157
-        if ($this->get('TKT_deleted')) {
158
-            return $display ? EEH_Template::pretty_status(EE_Ticket::archived, false, 'sentence') : EE_Ticket::archived;
159
-        }
160
-        if ($this->is_expired()) {
161
-            return $display ? EEH_Template::pretty_status(EE_Ticket::expired, false, 'sentence') : EE_Ticket::expired;
162
-        }
163
-        if ($this->is_pending()) {
164
-            return $display ? EEH_Template::pretty_status(EE_Ticket::pending, false, 'sentence') : EE_Ticket::pending;
165
-        }
166
-        if ($this->is_on_sale()) {
167
-            return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence') : EE_Ticket::onsale;
168
-        }
169
-        return '';
170
-    }
171
-
172
-
173
-    /**
174
-     * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale
175
-     * considering ALL the factors used for figuring that out.
176
-     *
177
-     * @access public
178
-     * @param int $DTT_ID if an int above 0 is included here then we get a specific dtt.
179
-     * @return boolean         true = tickets remaining, false not.
180
-     * @throws EE_Error
181
-     * @throws ReflectionException
182
-     */
183
-    public function is_remaining($DTT_ID = 0)
184
-    {
185
-        $num_remaining = $this->remaining($DTT_ID);
186
-        if ($num_remaining === 0) {
187
-            return false;
188
-        }
189
-        if ($num_remaining > 0 && $num_remaining < $this->min()) {
190
-            return false;
191
-        }
192
-        return true;
193
-    }
194
-
195
-
196
-    /**
197
-     * return the total number of tickets available for purchase
198
-     *
199
-     * @param int $DTT_ID  the primary key for a particular datetime.
200
-     *                     set to 0 for all related datetimes
201
-     * @return int
202
-     * @throws EE_Error
203
-     * @throws ReflectionException
204
-     */
205
-    public function remaining($DTT_ID = 0)
206
-    {
207
-        return $this->real_quantity_on_ticket('saleable', $DTT_ID);
208
-    }
209
-
210
-
211
-    /**
212
-     * Gets min
213
-     *
214
-     * @return int
215
-     * @throws EE_Error
216
-     * @throws ReflectionException
217
-     */
218
-    public function min()
219
-    {
220
-        return $this->get('TKT_min');
221
-    }
222
-
223
-
224
-    /**
225
-     * return if a ticket is no longer available cause its available dates have expired.
226
-     *
227
-     * @return boolean
228
-     * @throws EE_Error
229
-     * @throws ReflectionException
230
-     */
231
-    public function is_expired()
232
-    {
233
-        return ($this->get_raw('TKT_end_date') < time());
234
-    }
235
-
236
-
237
-    /**
238
-     * Return if a ticket is yet to go on sale or not
239
-     *
240
-     * @return boolean
241
-     * @throws EE_Error
242
-     * @throws ReflectionException
243
-     */
244
-    public function is_pending()
245
-    {
246
-        return ($this->get_raw('TKT_start_date') >= time());
247
-    }
248
-
249
-
250
-    /**
251
-     * Return if a ticket is on sale or not
252
-     *
253
-     * @return boolean
254
-     * @throws EE_Error
255
-     * @throws ReflectionException
256
-     */
257
-    public function is_on_sale()
258
-    {
259
-        return ($this->get_raw('TKT_start_date') <= time() && $this->get_raw('TKT_end_date') >= time());
260
-    }
261
-
262
-
263
-    /**
264
-     * This returns the chronologically last datetime that this ticket is associated with
265
-     *
266
-     * @param string $date_format
267
-     * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with
268
-     *                            the end date ie: Jan 01 "to" Dec 31
269
-     * @return string
270
-     * @throws EE_Error
271
-     * @throws ReflectionException
272
-     */
273
-    public function date_range($date_format = '', $conjunction = ' - ')
274
-    {
275
-        $date_format = ! empty($date_format) ? $date_format : $this->_dt_frmt;
276
-        $first_date  = $this->first_datetime() instanceof EE_Datetime
277
-            ? $this->first_datetime()->get_i18n_datetime('DTT_EVT_start', $date_format)
278
-            : '';
279
-        $last_date   = $this->last_datetime() instanceof EE_Datetime
280
-            ? $this->last_datetime()->get_i18n_datetime('DTT_EVT_end', $date_format)
281
-            : '';
282
-
283
-        return $first_date && $last_date ? $first_date . $conjunction . $last_date : '';
284
-    }
285
-
286
-
287
-    /**
288
-     * This returns the chronologically first datetime that this ticket is associated with
289
-     *
290
-     * @return EE_Datetime
291
-     * @throws EE_Error
292
-     * @throws ReflectionException
293
-     */
294
-    public function first_datetime()
295
-    {
296
-        $datetimes = $this->datetimes(['limit' => 1]);
297
-        return reset($datetimes);
298
-    }
299
-
300
-
301
-    /**
302
-     * Gets all the datetimes this ticket can be used for attending.
303
-     * Unless otherwise specified, orders datetimes by start date.
304
-     *
305
-     * @param array $query_params @see
306
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
307
-     * @return EE_Datetime[]|EE_Base_Class[]
308
-     * @throws EE_Error
309
-     * @throws ReflectionException
310
-     */
311
-    public function datetimes($query_params = [])
312
-    {
313
-        if (! isset($query_params['order_by'])) {
314
-            $query_params['order_by']['DTT_order'] = 'ASC';
315
-        }
316
-        return $this->get_many_related('Datetime', $query_params);
317
-    }
318
-
319
-
320
-    /**
321
-     * This returns the chronologically last datetime that this ticket is associated with
322
-     *
323
-     * @return EE_Datetime
324
-     * @throws EE_Error
325
-     * @throws ReflectionException
326
-     */
327
-    public function last_datetime()
328
-    {
329
-        $datetimes = $this->datetimes(['limit' => 1, 'order_by' => ['DTT_EVT_start' => 'DESC']]);
330
-        return end($datetimes);
331
-    }
332
-
333
-
334
-    /**
335
-     * This returns the total tickets sold depending on the given parameters.
336
-     *
337
-     * @param string $what    Can be one of two options: 'ticket', 'datetime'.
338
-     *                        'ticket' = total ticket sales for all datetimes this ticket is related to
339
-     *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
340
-     *                        'datetime' = total ticket sales in the datetime_ticket table.
341
-     *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
342
-     *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
343
-     * @param int    $dtt_id  [optional] include the dtt_id with $what = 'datetime'.
344
-     * @return mixed (array|int)          how many tickets have sold
345
-     * @throws EE_Error
346
-     * @throws ReflectionException
347
-     */
348
-    public function tickets_sold($what = 'ticket', $dtt_id = null)
349
-    {
350
-        $total        = 0;
351
-        $tickets_sold = $this->_all_tickets_sold();
352
-        switch ($what) {
353
-            case 'ticket':
354
-                return $tickets_sold['ticket'];
355
-                break;
356
-            case 'datetime':
357
-                if (empty($tickets_sold['datetime'])) {
358
-                    return $total;
359
-                }
360
-                if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) {
361
-                    EE_Error::add_error(
362
-                        __(
363
-                            'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?',
364
-                            'event_espresso'
365
-                        ),
366
-                        __FILE__,
367
-                        __FUNCTION__,
368
-                        __LINE__
369
-                    );
370
-                    return $total;
371
-                }
372
-                return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ];
373
-                break;
374
-            default:
375
-                return $total;
376
-        }
377
-    }
378
-
379
-
380
-    /**
381
-     * This returns an array indexed by datetime_id for tickets sold with this ticket.
382
-     *
383
-     * @return EE_Ticket[]
384
-     * @throws EE_Error
385
-     * @throws ReflectionException
386
-     */
387
-    protected function _all_tickets_sold()
388
-    {
389
-        $datetimes    = $this->get_many_related('Datetime');
390
-        $tickets_sold = [];
391
-        if (! empty($datetimes)) {
392
-            foreach ($datetimes as $datetime) {
393
-                $tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold');
394
-            }
395
-        }
396
-        // Tickets sold
397
-        $tickets_sold['ticket'] = $this->sold();
398
-        return $tickets_sold;
399
-    }
400
-
401
-
402
-    /**
403
-     * This returns the base price object for the ticket.
404
-     *
405
-     * @param bool $return_array whether to return as an array indexed by price id or just the object.
406
-     * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
407
-     * @throws EE_Error
408
-     * @throws ReflectionException
409
-     */
410
-    public function base_price($return_array = false)
411
-    {
412
-        $_where = ['Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price];
413
-        return $return_array
414
-            ? $this->get_many_related('Price', [$_where])
415
-            : $this->get_first_related('Price', [$_where]);
416
-    }
417
-
418
-
419
-    /**
420
-     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
421
-     *
422
-     * @access public
423
-     * @return EE_Price[]
424
-     * @throws EE_Error
425
-     * @throws ReflectionException
426
-     */
427
-    public function price_modifiers()
428
-    {
429
-        $query_params = [
430
-            0 => [
431
-                'Price_Type.PBT_ID' => [
432
-                    'NOT IN',
433
-                    [EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax],
434
-                ],
435
-            ],
436
-        ];
437
-        return $this->prices($query_params);
438
-    }
439
-
440
-
441
-    /**
442
-     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
443
-     *
444
-     * @access public
445
-     * @return EE_Price[]
446
-     * @throws EE_Error
447
-     * @throws ReflectionException
448
-     */
449
-    public function tax_price_modifiers()
450
-    {
451
-        $query_params = [
452
-            0 => [
453
-                'Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax,
454
-            ],
455
-        ];
456
-        return $this->prices($query_params);
457
-    }
458
-
459
-
460
-    /**
461
-     * Gets all the prices that combine to form the final price of this ticket
462
-     *
463
-     * @param array $query_params @see
464
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
465
-     * @return EE_Price[]|EE_Base_Class[]
466
-     * @throws EE_Error
467
-     * @throws ReflectionException
468
-     */
469
-    public function prices($query_params = [])
470
-    {
471
-        return $this->get_many_related('Price', $query_params);
472
-    }
473
-
474
-
475
-    /**
476
-     * Gets all the ticket datetimes (ie, relations between datetimes and tickets)
477
-     *
478
-     * @param array $query_params @see
479
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
480
-     * @return EE_Datetime_Ticket|EE_Base_Class[]
481
-     * @throws EE_Error
482
-     * @throws ReflectionException
483
-     */
484
-    public function datetime_tickets($query_params = [])
485
-    {
486
-        return $this->get_many_related('Datetime_Ticket', $query_params);
487
-    }
488
-
489
-
490
-    /**
491
-     * Gets all the datetimes from the db ordered by DTT_order
492
-     *
493
-     * @param boolean $show_expired
494
-     * @param boolean $show_deleted
495
-     * @return EE_Datetime[]
496
-     * @throws EE_Error
497
-     * @throws ReflectionException
498
-     */
499
-    public function datetimes_ordered($show_expired = true, $show_deleted = false)
500
-    {
501
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order(
502
-            $this->ID(),
503
-            $show_expired,
504
-            $show_deleted
505
-        );
506
-    }
507
-
508
-
509
-    /**
510
-     * Gets ID
511
-     *
512
-     * @return int
513
-     * @throws EE_Error
514
-     * @throws ReflectionException
515
-     */
516
-    public function ID()
517
-    {
518
-        return $this->get('TKT_ID');
519
-    }
520
-
521
-
522
-    /**
523
-     * get the author of the ticket.
524
-     *
525
-     * @return int
526
-     * @throws EE_Error
527
-     * @throws ReflectionException
528
-     * @since 4.5.0
529
-     */
530
-    public function wp_user()
531
-    {
532
-        return $this->get('TKT_wp_user');
533
-    }
534
-
535
-
536
-    /**
537
-     * Gets the template for the ticket
538
-     *
539
-     * @return EE_Ticket_Template|EE_Base_Class
540
-     * @throws EE_Error
541
-     * @throws ReflectionException
542
-     */
543
-    public function template()
544
-    {
545
-        return $this->get_first_related('Ticket_Template');
546
-    }
547
-
548
-
549
-    /**
550
-     * Simply returns an array of EE_Price objects that are taxes.
551
-     *
552
-     * @return EE_Price[]
553
-     * @throws EE_Error
554
-     */
555
-    public function get_ticket_taxes_for_admin()
556
-    {
557
-        return EE_Taxes::get_taxes_for_admin();
558
-    }
559
-
560
-
561
-    /**
562
-     * @return float
563
-     * @throws EE_Error
564
-     * @throws ReflectionException
565
-     */
566
-    public function ticket_price()
567
-    {
568
-        return $this->get('TKT_price');
569
-    }
570
-
571
-
572
-    /**
573
-     * @return mixed
574
-     * @throws EE_Error
575
-     * @throws ReflectionException
576
-     */
577
-    public function pretty_price()
578
-    {
579
-        return $this->get_pretty('TKT_price');
580
-    }
581
-
582
-
583
-    /**
584
-     * @return bool
585
-     * @throws EE_Error
586
-     * @throws ReflectionException
587
-     */
588
-    public function is_free()
589
-    {
590
-        return $this->get_ticket_total_with_taxes() === (float) 0;
591
-    }
592
-
593
-
594
-    /**
595
-     * get_ticket_total_with_taxes
596
-     *
597
-     * @param bool $no_cache
598
-     * @return float
599
-     * @throws EE_Error
600
-     * @throws ReflectionException
601
-     */
602
-    public function get_ticket_total_with_taxes($no_cache = false)
603
-    {
604
-        if ($this->_ticket_total_with_taxes === null || $no_cache) {
605
-            $this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
606
-        }
607
-        return (float) $this->_ticket_total_with_taxes;
608
-    }
609
-
610
-
611
-    /**
612
-     * @throws EE_Error
613
-     * @throws ReflectionException
614
-     */
615
-    public function ensure_TKT_Price_correct()
616
-    {
617
-        $this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
618
-        $this->save();
619
-    }
620
-
621
-
622
-    /**
623
-     * @return float
624
-     * @throws EE_Error
625
-     * @throws ReflectionException
626
-     */
627
-    public function get_ticket_subtotal()
628
-    {
629
-        return EE_Taxes::get_subtotal_for_admin($this);
630
-    }
631
-
632
-
633
-    /**
634
-     * Returns the total taxes applied to this ticket
635
-     *
636
-     * @return float
637
-     * @throws EE_Error
638
-     * @throws ReflectionException
639
-     */
640
-    public function get_ticket_taxes_total_for_admin()
641
-    {
642
-        return EE_Taxes::get_total_taxes_for_admin($this);
643
-    }
644
-
645
-
646
-    /**
647
-     * Sets name
648
-     *
649
-     * @param string $name
650
-     * @throws EE_Error
651
-     * @throws ReflectionException
652
-     */
653
-    public function set_name($name)
654
-    {
655
-        $this->set('TKT_name', $name);
656
-    }
657
-
658
-
659
-    /**
660
-     * Gets description
661
-     *
662
-     * @return string
663
-     * @throws EE_Error
664
-     * @throws ReflectionException
665
-     */
666
-    public function description()
667
-    {
668
-        return $this->get('TKT_description');
669
-    }
670
-
671
-
672
-    /**
673
-     * Sets description
674
-     *
675
-     * @param string $description
676
-     * @throws EE_Error
677
-     * @throws ReflectionException
678
-     */
679
-    public function set_description($description)
680
-    {
681
-        $this->set('TKT_description', $description);
682
-    }
683
-
684
-
685
-    /**
686
-     * Gets start_date
687
-     *
688
-     * @param string $date_format
689
-     * @param string $time_format
690
-     * @return string
691
-     * @throws EE_Error
692
-     * @throws ReflectionException
693
-     */
694
-    public function start_date($date_format = '', $time_format = '')
695
-    {
696
-        return $this->_get_datetime('TKT_start_date', $date_format, $time_format);
697
-    }
698
-
699
-
700
-    /**
701
-     * Sets start_date
702
-     *
703
-     * @param string $start_date
704
-     * @return void
705
-     * @throws EE_Error
706
-     * @throws ReflectionException
707
-     */
708
-    public function set_start_date($start_date)
709
-    {
710
-        $this->_set_date_time('B', $start_date, 'TKT_start_date');
711
-    }
712
-
713
-
714
-    /**
715
-     * Gets end_date
716
-     *
717
-     * @param string $date_format
718
-     * @param string $time_format
719
-     * @return string
720
-     * @throws EE_Error
721
-     * @throws ReflectionException
722
-     */
723
-    public function end_date($date_format = '', $time_format = '')
724
-    {
725
-        return $this->_get_datetime('TKT_end_date', $date_format, $time_format);
726
-    }
727
-
728
-
729
-    /**
730
-     * Sets end_date
731
-     *
732
-     * @param string $end_date
733
-     * @return void
734
-     * @throws EE_Error
735
-     * @throws ReflectionException
736
-     */
737
-    public function set_end_date($end_date)
738
-    {
739
-        $this->_set_date_time('B', $end_date, 'TKT_end_date');
740
-    }
741
-
742
-
743
-    /**
744
-     * Sets sell until time
745
-     *
746
-     * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
747
-     * @throws EE_Error
748
-     * @throws ReflectionException
749
-     * @since 4.5.0
750
-     */
751
-    public function set_end_time($time)
752
-    {
753
-        $this->_set_time_for($time, 'TKT_end_date');
754
-    }
755
-
756
-
757
-    /**
758
-     * Sets min
759
-     *
760
-     * @param int $min
761
-     * @return void
762
-     * @throws EE_Error
763
-     * @throws ReflectionException
764
-     */
765
-    public function set_min($min)
766
-    {
767
-        $this->set('TKT_min', $min);
768
-    }
769
-
770
-
771
-    /**
772
-     * Gets max
773
-     *
774
-     * @return int
775
-     * @throws EE_Error
776
-     * @throws ReflectionException
777
-     */
778
-    public function max()
779
-    {
780
-        return $this->get('TKT_max');
781
-    }
782
-
783
-
784
-    /**
785
-     * Sets max
786
-     *
787
-     * @param int $max
788
-     * @return void
789
-     * @throws EE_Error
790
-     * @throws ReflectionException
791
-     */
792
-    public function set_max($max)
793
-    {
794
-        $this->set('TKT_max', $max);
795
-    }
796
-
797
-
798
-    /**
799
-     * Sets price
800
-     *
801
-     * @param float $price
802
-     * @return void
803
-     * @throws EE_Error
804
-     * @throws ReflectionException
805
-     */
806
-    public function set_price($price)
807
-    {
808
-        $this->set('TKT_price', $price);
809
-    }
810
-
811
-
812
-    /**
813
-     * Gets sold
814
-     *
815
-     * @return int
816
-     * @throws EE_Error
817
-     * @throws ReflectionException
818
-     */
819
-    public function sold()
820
-    {
821
-        return $this->get_raw('TKT_sold');
822
-    }
823
-
824
-
825
-    /**
826
-     * Sets sold
827
-     *
828
-     * @param int $sold
829
-     * @return void
830
-     * @throws EE_Error
831
-     * @throws ReflectionException
832
-     */
833
-    public function set_sold($sold)
834
-    {
835
-        // sold can not go below zero
836
-        $sold = max(0, $sold);
837
-        $this->set('TKT_sold', $sold);
838
-    }
839
-
840
-
841
-    /**
842
-     * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
843
-     * associated datetimes.
844
-     *
845
-     * @param int $qty
846
-     * @return boolean
847
-     * @throws EE_Error
848
-     * @throws InvalidArgumentException
849
-     * @throws InvalidDataTypeException
850
-     * @throws InvalidInterfaceException
851
-     * @throws ReflectionException
852
-     * @since 4.9.80.p
853
-     */
854
-    public function increaseSold($qty = 1)
855
-    {
856
-        $qty = absint($qty);
857
-        // increment sold and decrement reserved datetime quantities simultaneously
858
-        // don't worry about failures, because they must have already had a spot reserved
859
-        $this->increaseSoldForDatetimes($qty);
860
-        // Increment and decrement ticket quantities simultaneously
861
-        $success = $this->adjustNumericFieldsInDb(
862
-            [
863
-                'TKT_reserved' => $qty * -1,
864
-                'TKT_sold'     => $qty,
865
-            ]
866
-        );
867
-        do_action(
868
-            'AHEE__EE_Ticket__increase_sold',
869
-            $this,
870
-            $qty,
871
-            $this->sold(),
872
-            $success
873
-        );
874
-        return $success;
875
-    }
876
-
877
-
878
-    /**
879
-     * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
880
-     *
881
-     * @param int           $qty positive or negative. Positive means to increase sold counts (and decrease reserved
882
-     *                           counts), Negative means to decreases old counts (and increase reserved counts).
883
-     * @param EE_Datetime[] $datetimes
884
-     * @throws EE_Error
885
-     * @throws InvalidArgumentException
886
-     * @throws InvalidDataTypeException
887
-     * @throws InvalidInterfaceException
888
-     * @throws ReflectionException
889
-     * @since 4.9.80.p
890
-     */
891
-    protected function increaseSoldForDatetimes($qty, array $datetimes = [])
892
-    {
893
-        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
894
-        foreach ($datetimes as $datetime) {
895
-            $datetime->increaseSold($qty);
896
-        }
897
-    }
898
-
899
-
900
-    /**
901
-     * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
902
-     * DB and then updates the model objects.
903
-     * Does not affect the reserved counts.
904
-     *
905
-     * @param int $qty
906
-     * @return boolean
907
-     * @throws EE_Error
908
-     * @throws InvalidArgumentException
909
-     * @throws InvalidDataTypeException
910
-     * @throws InvalidInterfaceException
911
-     * @throws ReflectionException
912
-     * @since 4.9.80.p
913
-     */
914
-    public function decreaseSold($qty = 1)
915
-    {
916
-        $qty = absint($qty);
917
-        $this->decreaseSoldForDatetimes($qty);
918
-        $success = $this->adjustNumericFieldsInDb(
919
-            [
920
-                'TKT_sold' => $qty * -1,
921
-            ]
922
-        );
923
-        do_action(
924
-            'AHEE__EE_Ticket__decrease_sold',
925
-            $this,
926
-            $qty,
927
-            $this->sold(),
928
-            $success
929
-        );
930
-        return $success;
931
-    }
932
-
933
-
934
-    /**
935
-     * Decreases sold on related datetimes
936
-     *
937
-     * @param int           $qty
938
-     * @param EE_Datetime[] $datetimes
939
-     * @return void
940
-     * @throws EE_Error
941
-     * @throws InvalidArgumentException
942
-     * @throws InvalidDataTypeException
943
-     * @throws InvalidInterfaceException
944
-     * @throws ReflectionException
945
-     * @since 4.9.80.p
946
-     */
947
-    protected function decreaseSoldForDatetimes($qty = 1, array $datetimes = [])
948
-    {
949
-        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
950
-        if (is_array($datetimes)) {
951
-            foreach ($datetimes as $datetime) {
952
-                if ($datetime instanceof EE_Datetime) {
953
-                    $datetime->decreaseSold($qty);
954
-                }
955
-            }
956
-        }
957
-    }
958
-
959
-
960
-    /**
961
-     * Gets qty of reserved tickets
962
-     *
963
-     * @return int
964
-     * @throws EE_Error
965
-     * @throws ReflectionException
966
-     */
967
-    public function reserved()
968
-    {
969
-        return $this->get_raw('TKT_reserved');
970
-    }
971
-
972
-
973
-    /**
974
-     * Sets reserved
975
-     *
976
-     * @param int $reserved
977
-     * @return void
978
-     * @throws EE_Error
979
-     * @throws ReflectionException
980
-     */
981
-    public function set_reserved($reserved)
982
-    {
983
-        // reserved can not go below zero
984
-        $reserved = max(0, (int) $reserved);
985
-        $this->set('TKT_reserved', $reserved);
986
-    }
987
-
988
-
989
-    /**
990
-     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
991
-     *
992
-     * @param int    $qty
993
-     * @param string $source
994
-     * @return bool whether we successfully reserved the ticket or not.
995
-     * @throws EE_Error
996
-     * @throws InvalidArgumentException
997
-     * @throws ReflectionException
998
-     * @throws InvalidDataTypeException
999
-     * @throws InvalidInterfaceException
1000
-     * @since 4.9.80.p
1001
-     */
1002
-    public function increaseReserved($qty = 1, $source = 'unknown')
1003
-    {
1004
-        $qty = absint($qty);
1005
-        do_action(
1006
-            'AHEE__EE_Ticket__increase_reserved__begin',
1007
-            $this,
1008
-            $qty,
1009
-            $source
1010
-        );
1011
-        $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "{$qty} from {$source}");
1012
-        $success                         = false;
1013
-        $datetimes_adjusted_successfully = $this->increaseReservedForDatetimes($qty);
1014
-        if ($datetimes_adjusted_successfully) {
1015
-            $success = $this->incrementFieldConditionallyInDb(
1016
-                'TKT_reserved',
1017
-                'TKT_sold',
1018
-                'TKT_qty',
1019
-                $qty
1020
-            );
1021
-            if (! $success) {
1022
-                // The datetimes were successfully bumped, but not the
1023
-                // ticket. So we need to manually rollback the datetimes.
1024
-                $this->decreaseReservedForDatetimes($qty);
1025
-            }
1026
-        }
1027
-        do_action(
1028
-            'AHEE__EE_Ticket__increase_reserved',
1029
-            $this,
1030
-            $qty,
1031
-            $this->reserved(),
1032
-            $success
1033
-        );
1034
-        return $success;
1035
-    }
1036
-
1037
-
1038
-    /**
1039
-     * Increases reserved counts on related datetimes
1040
-     *
1041
-     * @param int           $qty
1042
-     * @param EE_Datetime[] $datetimes
1043
-     * @return boolean indicating success
1044
-     * @throws EE_Error
1045
-     * @throws InvalidArgumentException
1046
-     * @throws InvalidDataTypeException
1047
-     * @throws InvalidInterfaceException
1048
-     * @throws ReflectionException
1049
-     * @since 4.9.80.p
1050
-     */
1051
-    protected function increaseReservedForDatetimes($qty = 1, array $datetimes = [])
1052
-    {
1053
-        $datetimes         = ! empty($datetimes) ? $datetimes : $this->datetimes();
1054
-        $datetimes_updated = [];
1055
-        $limit_exceeded    = false;
1056
-        if (is_array($datetimes)) {
1057
-            foreach ($datetimes as $datetime) {
1058
-                if ($datetime instanceof EE_Datetime) {
1059
-                    if ($datetime->increaseReserved($qty)) {
1060
-                        $datetimes_updated[] = $datetime;
1061
-                    } else {
1062
-                        $limit_exceeded = true;
1063
-                        break;
1064
-                    }
1065
-                }
1066
-            }
1067
-            // If somewhere along the way we detected a datetime whose
1068
-            // limit was exceeded, do a manual rollback.
1069
-            if ($limit_exceeded) {
1070
-                $this->decreaseReservedForDatetimes($qty, $datetimes_updated);
1071
-                return false;
1072
-            }
1073
-        }
1074
-        return true;
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
1080
-     *
1081
-     * @param int    $qty
1082
-     * @param bool   $adjust_datetimes
1083
-     * @param string $source
1084
-     * @return boolean
1085
-     * @throws EE_Error
1086
-     * @throws InvalidArgumentException
1087
-     * @throws ReflectionException
1088
-     * @throws InvalidDataTypeException
1089
-     * @throws InvalidInterfaceException
1090
-     * @since 4.9.80.p
1091
-     */
1092
-    public function decreaseReserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
1093
-    {
1094
-        $qty = absint($qty);
1095
-        $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "-{$qty} from {$source}");
1096
-        if ($adjust_datetimes) {
1097
-            $this->decreaseReservedForDatetimes($qty);
1098
-        }
1099
-        $success = $this->adjustNumericFieldsInDb(
1100
-            [
1101
-                'TKT_reserved' => $qty * -1,
1102
-            ]
1103
-        );
1104
-        do_action(
1105
-            'AHEE__EE_Ticket__decrease_reserved',
1106
-            $this,
1107
-            $qty,
1108
-            $this->reserved(),
1109
-            $success
1110
-        );
1111
-        return $success;
1112
-    }
1113
-
1114
-
1115
-    /**
1116
-     * Decreases the reserved count on the specified datetimes.
1117
-     *
1118
-     * @param int           $qty
1119
-     * @param EE_Datetime[] $datetimes
1120
-     * @throws EE_Error
1121
-     * @throws InvalidArgumentException
1122
-     * @throws ReflectionException
1123
-     * @throws InvalidDataTypeException
1124
-     * @throws InvalidInterfaceException
1125
-     * @since 4.9.80.p
1126
-     */
1127
-    protected function decreaseReservedForDatetimes($qty = 1, array $datetimes = [])
1128
-    {
1129
-        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
1130
-        foreach ($datetimes as $datetime) {
1131
-            if ($datetime instanceof EE_Datetime) {
1132
-                $datetime->decreaseReserved($qty);
1133
-            }
1134
-        }
1135
-    }
1136
-
1137
-
1138
-    /**
1139
-     * Gets ticket quantity
1140
-     *
1141
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1142
-     *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
1143
-     *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
1144
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1145
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1146
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
1147
-     * @return int
1148
-     * @throws EE_Error
1149
-     * @throws ReflectionException
1150
-     */
1151
-    public function qty($context = '')
1152
-    {
1153
-        switch ($context) {
1154
-            case 'reg_limit':
1155
-                return $this->real_quantity_on_ticket();
1156
-            case 'saleable':
1157
-                return $this->real_quantity_on_ticket('saleable');
1158
-            default:
1159
-                return $this->get_raw('TKT_qty');
1160
-        }
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * Gets ticket quantity
1166
-     *
1167
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1168
-     *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
1169
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1170
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1171
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
1172
-     * @param int    $DTT_ID      the primary key for a particular datetime.
1173
-     *                            set to 0 for all related datetimes
1174
-     * @return int
1175
-     * @throws EE_Error
1176
-     * @throws ReflectionException
1177
-     */
1178
-    public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0)
1179
-    {
1180
-        $raw = $this->get_raw('TKT_qty');
1181
-        // return immediately if it's zero
1182
-        if ($raw === 0) {
1183
-            return $raw;
1184
-        }
1185
-        // echo "\n\n<br />Ticket: " . $this->name() . '<br />';
1186
-        // ensure qty doesn't exceed raw value for THIS ticket
1187
-        $qty = min(EE_INF, $raw);
1188
-        // echo "\n . qty: " . $qty . '<br />';
1189
-        // calculate this ticket's total sales and reservations
1190
-        $sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
1191
-        // echo "\n . sold: " . $this->sold() . '<br />';
1192
-        // echo "\n . reserved: " . $this->reserved() . '<br />';
1193
-        // echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
1194
-        // first we need to calculate the maximum number of tickets available for the datetime
1195
-        // do we want data for one datetime or all of them ?
1196
-        $query_params = $DTT_ID ? [['DTT_ID' => $DTT_ID]] : [];
1197
-        $datetimes    = $this->datetimes($query_params);
1198
-        if (is_array($datetimes) && ! empty($datetimes)) {
1199
-            foreach ($datetimes as $datetime) {
1200
-                if ($datetime instanceof EE_Datetime) {
1201
-                    $datetime->refresh_from_db();
1202
-                    // echo "\n . . datetime name: " . $datetime->name() . '<br />';
1203
-                    // echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
1204
-                    // initialize with no restrictions for each datetime
1205
-                    // but adjust datetime qty based on datetime reg limit
1206
-                    $datetime_qty = min(EE_INF, $datetime->reg_limit());
1207
-                    // echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
1208
-                    // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1209
-                    // if we want the actual saleable amount, then we need to consider OTHER ticket sales
1210
-                    // and reservations for this datetime, that do NOT include sales and reservations
1211
-                    // for this ticket (so we add $this->sold() and $this->reserved() back in)
1212
-                    if ($context === 'saleable') {
1213
-                        $datetime_qty = max(
1214
-                            $datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
1215
-                            0
1216
-                        );
1217
-                        // echo "\n . . . datetime sold: " . $datetime->sold() . '<br />';
1218
-                        // echo "\n . . . datetime reserved: " . $datetime->reserved() . '<br />';
1219
-                        // echo "\n . . . datetime sold_and_reserved: " . $datetime->sold_and_reserved() . '<br />';
1220
-                        // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1221
-                        $datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
1222
-                        // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1223
-                    }
1224
-                    $qty = min($datetime_qty, $qty);
1225
-                    // echo "\n . . qty: " . $qty . '<br />';
1226
-                }
1227
-            }
1228
-        }
1229
-        // NOW that we know the  maximum number of tickets available for the datetime
1230
-        // we can finally factor in the details for this specific ticket
1231
-        if ($qty > 0 && $context === 'saleable') {
1232
-            // and subtract the sales for THIS ticket
1233
-            $qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1234
-            // echo "\n . qty: " . $qty . '<br />';
1235
-        }
1236
-        // echo "\nFINAL QTY: " . $qty . "<br /><br />";
1237
-        return $qty;
1238
-    }
1239
-
1240
-
1241
-    /**
1242
-     * Sets qty - IMPORTANT!!! Does NOT allow QTY to be set higher than the lowest reg limit of any related datetimes
1243
-     *
1244
-     * @param int $qty
1245
-     * @return void
1246
-     * @throws EE_Error
1247
-     * @throws ReflectionException
1248
-     */
1249
-    public function set_qty($qty)
1250
-    {
1251
-        $datetimes = $this->datetimes();
1252
-        foreach ($datetimes as $datetime) {
1253
-            if ($datetime instanceof EE_Datetime) {
1254
-                $qty = min($qty, $datetime->reg_limit());
1255
-            }
1256
-        }
1257
-        $this->set('TKT_qty', $qty);
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * Gets uses
1263
-     *
1264
-     * @return int
1265
-     * @throws EE_Error
1266
-     * @throws ReflectionException
1267
-     */
1268
-    public function uses()
1269
-    {
1270
-        return $this->get('TKT_uses');
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * Sets uses
1276
-     *
1277
-     * @param int $uses
1278
-     * @return void
1279
-     * @throws EE_Error
1280
-     * @throws ReflectionException
1281
-     */
1282
-    public function set_uses($uses)
1283
-    {
1284
-        $this->set('TKT_uses', $uses);
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * returns whether ticket is required or not.
1290
-     *
1291
-     * @return boolean
1292
-     * @throws EE_Error
1293
-     * @throws ReflectionException
1294
-     */
1295
-    public function required()
1296
-    {
1297
-        return $this->get('TKT_required');
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     * sets the TKT_required property
1303
-     *
1304
-     * @param boolean $required
1305
-     * @return void
1306
-     * @throws EE_Error
1307
-     * @throws ReflectionException
1308
-     */
1309
-    public function set_required($required)
1310
-    {
1311
-        $this->set('TKT_required', $required);
1312
-    }
1313
-
1314
-
1315
-    /**
1316
-     * Gets taxable
1317
-     *
1318
-     * @return boolean
1319
-     * @throws EE_Error
1320
-     * @throws ReflectionException
1321
-     */
1322
-    public function taxable()
1323
-    {
1324
-        return $this->get('TKT_taxable');
1325
-    }
1326
-
1327
-
1328
-    /**
1329
-     * Sets taxable
1330
-     *
1331
-     * @param boolean $taxable
1332
-     * @return void
1333
-     * @throws EE_Error
1334
-     * @throws ReflectionException
1335
-     */
1336
-    public function set_taxable($taxable)
1337
-    {
1338
-        $this->set('TKT_taxable', $taxable);
1339
-    }
1340
-
1341
-
1342
-    /**
1343
-     * Gets is_default
1344
-     *
1345
-     * @return boolean
1346
-     * @throws EE_Error
1347
-     * @throws ReflectionException
1348
-     */
1349
-    public function is_default()
1350
-    {
1351
-        return $this->get('TKT_is_default');
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     * Sets is_default
1357
-     *
1358
-     * @param boolean $is_default
1359
-     * @return void
1360
-     * @throws EE_Error
1361
-     * @throws ReflectionException
1362
-     */
1363
-    public function set_is_default($is_default)
1364
-    {
1365
-        $this->set('TKT_is_default', $is_default);
1366
-    }
1367
-
1368
-
1369
-    /**
1370
-     * Gets order
1371
-     *
1372
-     * @return int
1373
-     * @throws EE_Error
1374
-     * @throws ReflectionException
1375
-     */
1376
-    public function order()
1377
-    {
1378
-        return $this->get('TKT_order');
1379
-    }
1380
-
1381
-
1382
-    /**
1383
-     * Sets order
1384
-     *
1385
-     * @param int $order
1386
-     * @return void
1387
-     * @throws EE_Error
1388
-     * @throws ReflectionException
1389
-     */
1390
-    public function set_order($order)
1391
-    {
1392
-        $this->set('TKT_order', $order);
1393
-    }
1394
-
1395
-
1396
-    /**
1397
-     * Gets row
1398
-     *
1399
-     * @return int
1400
-     * @throws EE_Error
1401
-     * @throws ReflectionException
1402
-     */
1403
-    public function row()
1404
-    {
1405
-        return $this->get('TKT_row');
1406
-    }
1407
-
1408
-
1409
-    /**
1410
-     * Sets row
1411
-     *
1412
-     * @param int $row
1413
-     * @return void
1414
-     * @throws EE_Error
1415
-     * @throws ReflectionException
1416
-     */
1417
-    public function set_row($row)
1418
-    {
1419
-        $this->set('TKT_row', $row);
1420
-    }
1421
-
1422
-
1423
-    /**
1424
-     * Gets deleted
1425
-     *
1426
-     * @return boolean
1427
-     * @throws EE_Error
1428
-     * @throws ReflectionException
1429
-     */
1430
-    public function deleted()
1431
-    {
1432
-        return $this->get('TKT_deleted');
1433
-    }
1434
-
1435
-
1436
-    /**
1437
-     * Sets deleted
1438
-     *
1439
-     * @param boolean $deleted
1440
-     * @return void
1441
-     * @throws EE_Error
1442
-     * @throws ReflectionException
1443
-     */
1444
-    public function set_deleted($deleted)
1445
-    {
1446
-        $this->set('TKT_deleted', $deleted);
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * Gets parent
1452
-     *
1453
-     * @return int
1454
-     * @throws EE_Error
1455
-     * @throws ReflectionException
1456
-     */
1457
-    public function parent_ID()
1458
-    {
1459
-        return $this->get('TKT_parent');
1460
-    }
1461
-
1462
-
1463
-    /**
1464
-     * Sets parent
1465
-     *
1466
-     * @param int $parent
1467
-     * @return void
1468
-     * @throws EE_Error
1469
-     * @throws ReflectionException
1470
-     */
1471
-    public function set_parent_ID($parent)
1472
-    {
1473
-        $this->set('TKT_parent', $parent);
1474
-    }
1475
-
1476
-
1477
-    /**
1478
-     * @return boolean
1479
-     * @throws EE_Error
1480
-     * @throws InvalidArgumentException
1481
-     * @throws InvalidDataTypeException
1482
-     * @throws InvalidInterfaceException
1483
-     * @throws ReflectionException
1484
-     */
1485
-    public function reverse_calculate()
1486
-    {
1487
-        return $this->get('TKT_reverse_calculate');
1488
-    }
1489
-
1490
-
1491
-    /**
1492
-     * @param boolean $reverse_calculate
1493
-     * @throws EE_Error
1494
-     * @throws InvalidArgumentException
1495
-     * @throws InvalidDataTypeException
1496
-     * @throws InvalidInterfaceException
1497
-     * @throws ReflectionException
1498
-     */
1499
-    public function set_reverse_calculate($reverse_calculate)
1500
-    {
1501
-        $this->set('TKT_reverse_calculate', $reverse_calculate);
1502
-    }
1503
-
1504
-
1505
-    /**
1506
-     * Gets a string which is handy for showing in gateways etc that describes the ticket.
1507
-     *
1508
-     * @return string
1509
-     * @throws EE_Error
1510
-     * @throws ReflectionException
1511
-     */
1512
-    public function name_and_info()
1513
-    {
1514
-        $times = [];
1515
-        foreach ($this->datetimes() as $datetime) {
1516
-            $times[] = $datetime->start_date_and_time();
1517
-        }
1518
-        return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price();
1519
-    }
1520
-
1521
-
1522
-    /**
1523
-     * Gets name
1524
-     *
1525
-     * @return string
1526
-     * @throws EE_Error
1527
-     * @throws ReflectionException
1528
-     */
1529
-    public function name()
1530
-    {
1531
-        return $this->get('TKT_name');
1532
-    }
1533
-
1534
-
1535
-    /**
1536
-     * Gets price
1537
-     *
1538
-     * @return float
1539
-     * @throws EE_Error
1540
-     * @throws ReflectionException
1541
-     */
1542
-    public function price()
1543
-    {
1544
-        return $this->get('TKT_price');
1545
-    }
1546
-
1547
-
1548
-    /**
1549
-     * Gets all the registrations for this ticket
1550
-     *
1551
-     * @param array $query_params @see
1552
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1553
-     * @return EE_Registration[]|EE_Base_Class[]
1554
-     * @throws EE_Error
1555
-     * @throws ReflectionException
1556
-     */
1557
-    public function registrations($query_params = [])
1558
-    {
1559
-        return $this->get_many_related('Registration', $query_params);
1560
-    }
1561
-
1562
-
1563
-    /**
1564
-     * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1565
-     *
1566
-     * @return int
1567
-     * @throws EE_Error
1568
-     * @throws ReflectionException
1569
-     */
1570
-    public function update_tickets_sold()
1571
-    {
1572
-        $count_regs_for_this_ticket = $this->count_registrations(
1573
-            [
1574
-                [
1575
-                    'STS_ID'      => EEM_Registration::status_id_approved,
1576
-                    'REG_deleted' => 0,
1577
-                ],
1578
-            ]
1579
-        );
1580
-        $this->set_sold($count_regs_for_this_ticket);
1581
-        $this->save();
1582
-        return $count_regs_for_this_ticket;
1583
-    }
1584
-
1585
-
1586
-    /**
1587
-     * Counts the registrations for this ticket
1588
-     *
1589
-     * @param array $query_params @see
1590
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1591
-     * @return int
1592
-     * @throws EE_Error
1593
-     * @throws ReflectionException
1594
-     */
1595
-    public function count_registrations($query_params = [])
1596
-    {
1597
-        return $this->count_related('Registration', $query_params);
1598
-    }
1599
-
1600
-
1601
-    /**
1602
-     * Implementation for EEI_Has_Icon interface method.
1603
-     *
1604
-     * @return string
1605
-     * @see EEI_Visual_Representation for comments
1606
-     */
1607
-    public function get_icon()
1608
-    {
1609
-        return '<span class="dashicons dashicons-tickets-alt"/>';
1610
-    }
1611
-
1612
-
1613
-    /**
1614
-     * Implementation of the EEI_Event_Relation interface method
1615
-     *
1616
-     * @return EE_Event
1617
-     * @throws EE_Error
1618
-     * @throws UnexpectedEntityException
1619
-     * @throws ReflectionException
1620
-     * @see EEI_Event_Relation for comments
1621
-     */
1622
-    public function get_related_event()
1623
-    {
1624
-        // get one datetime to use for getting the event
1625
-        $datetime = $this->first_datetime();
1626
-        if (! $datetime instanceof EE_Datetime) {
1627
-            throw new UnexpectedEntityException(
1628
-                $datetime,
1629
-                'EE_Datetime',
1630
-                sprintf(
1631
-                    __('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1632
-                    $this->name()
1633
-                )
1634
-            );
1635
-        }
1636
-        $event = $datetime->event();
1637
-        if (! $event instanceof EE_Event) {
1638
-            throw new UnexpectedEntityException(
1639
-                $event,
1640
-                'EE_Event',
1641
-                sprintf(
1642
-                    __('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1643
-                    $this->name()
1644
-                )
1645
-            );
1646
-        }
1647
-        return $event;
1648
-    }
1649
-
1650
-
1651
-    /**
1652
-     * Implementation of the EEI_Event_Relation interface method
1653
-     *
1654
-     * @return string
1655
-     * @throws UnexpectedEntityException
1656
-     * @throws EE_Error
1657
-     * @throws ReflectionException
1658
-     * @see EEI_Event_Relation for comments
1659
-     */
1660
-    public function get_event_name()
1661
-    {
1662
-        $event = $this->get_related_event();
1663
-        return $event instanceof EE_Event ? $event->name() : '';
1664
-    }
1665
-
1666
-
1667
-    /**
1668
-     * Implementation of the EEI_Event_Relation interface method
1669
-     *
1670
-     * @return int
1671
-     * @throws UnexpectedEntityException
1672
-     * @throws EE_Error
1673
-     * @throws ReflectionException
1674
-     * @see EEI_Event_Relation for comments
1675
-     */
1676
-    public function get_event_ID()
1677
-    {
1678
-        $event = $this->get_related_event();
1679
-        return $event instanceof EE_Event ? $event->ID() : 0;
1680
-    }
1681
-
1682
-
1683
-    /**
1684
-     * This simply returns whether a ticket can be permanently deleted or not.
1685
-     * The criteria for determining this is whether the ticket has any related registrations.
1686
-     * If there are none then it can be permanently deleted.
1687
-     *
1688
-     * @return bool
1689
-     * @throws EE_Error
1690
-     * @throws ReflectionException
1691
-     */
1692
-    public function is_permanently_deleteable()
1693
-    {
1694
-        return $this->count_registrations() === 0;
1695
-    }
1696
-
1697
-
1698
-    /**
1699
-     * @return int
1700
-     * @throws EE_Error
1701
-     * @throws ReflectionException
1702
-     * @since   $VID:$
1703
-     */
1704
-    public function visibility(): int
1705
-    {
1706
-        return $this->get('TKT_visibility');
1707
-    }
1708
-
1709
-
1710
-    /**
1711
-     * @return int
1712
-     * @throws EE_Error
1713
-     * @throws ReflectionException
1714
-     * @since   $VID:$
1715
-     */
1716
-    public function isHidden(): int
1717
-    {
1718
-        return $this->visibility() === EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE;
1719
-    }
1720
-
1721
-
1722
-    /**
1723
-     * @return int
1724
-     * @throws EE_Error
1725
-     * @throws ReflectionException
1726
-     * @since   $VID:$
1727
-     */
1728
-    public function isNotHidden(): int
1729
-    {
1730
-        return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE;
1731
-    }
1732
-
1733
-
1734
-    /**
1735
-     * @return int
1736
-     * @throws EE_Error
1737
-     * @throws ReflectionException
1738
-     * @since   $VID:$
1739
-     */
1740
-    public function isPublicOnly(): int
1741
-    {
1742
-        return $this->isNotHidden() && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE;
1743
-    }
1744
-
1745
-
1746
-    /**
1747
-     * @return int
1748
-     * @throws EE_Error
1749
-     * @throws ReflectionException
1750
-     * @since   $VID:$
1751
-     */
1752
-    public function isMembersOnly(): int
1753
-    {
1754
-        return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE
1755
-               && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE;
1756
-    }
1757
-
1758
-
1759
-    /**
1760
-     * @return int
1761
-     * @throws EE_Error
1762
-     * @throws ReflectionException
1763
-     * @since   $VID:$
1764
-     */
1765
-    public function isAdminsOnly(): int
1766
-    {
1767
-        return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE
1768
-               && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE;
1769
-    }
1770
-
1771
-
1772
-    /**
1773
-     * @return int
1774
-     * @throws EE_Error
1775
-     * @throws ReflectionException
1776
-     * @since   $VID:$
1777
-     */
1778
-    public function isAdminUiOnly(): int
1779
-    {
1780
-        return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE
1781
-               && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE;
1782
-    }
1783
-
1784
-
1785
-    /**
1786
-     * @param int $visibility
1787
-     * @throws EE_Error
1788
-     * @throws ReflectionException
1789
-     * @since   $VID:$
1790
-     */
1791
-    public function set_visibility(int $visibility)
1792
-    {
1793
-
1794
-        $ticket_visibility_options = $this->_model->ticketVisibilityOptions();
1795
-        $ticket_visibility         = -1;
1796
-        foreach ($ticket_visibility_options as $ticket_visibility_option) {
1797
-            if ($visibility === $ticket_visibility_option) {
1798
-                $ticket_visibility = $visibility;
1799
-            }
1800
-        }
1801
-        if ($ticket_visibility === -1) {
1802
-            throw new DomainException(
1803
-                sprintf(
1804
-                    esc_html__(
1805
-                        'The supplied ticket visibility setting of "%1$s" is not valid. It needs to match one of the keys in the following array:%2$s %3$s ',
1806
-                        'event_espresso'
1807
-                    ),
1808
-                    $visibility,
1809
-                    '<br />',
1810
-                    var_export($ticket_visibility_options, true)
1811
-                )
1812
-            );
1813
-        }
1814
-        $this->set('TKT_visibility', $ticket_visibility);
1815
-    }
1816
-
1817
-
1818
-    /**
1819
-     * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1820
-     * @param string                   $relationName
1821
-     * @param array                    $extra_join_model_fields_n_values
1822
-     * @param string|null              $cache_id
1823
-     * @return EE_Base_Class
1824
-     * @throws EE_Error
1825
-     * @throws ReflectionException
1826
-     * @since   $VID:$
1827
-     */
1828
-    public function _add_relation_to(
1829
-        $otherObjectModelObjectOrID,
1830
-        $relationName,
1831
-        $extra_join_model_fields_n_values = [],
1832
-        $cache_id = null
1833
-    ) {
1834
-        if ($relationName === 'Datetime' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1835
-            /** @var EE_Datetime $datetime */
1836
-            $datetime = EEM_Datetime::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1837
-            $datetime->increaseSold($this->sold(), false);
1838
-            $datetime->increaseReserved($this->reserved());
1839
-            $datetime->save();
1840
-            $otherObjectModelObjectOrID = $datetime;
1841
-        }
1842
-        return parent::_add_relation_to(
1843
-            $otherObjectModelObjectOrID,
1844
-            $relationName,
1845
-            $extra_join_model_fields_n_values,
1846
-            $cache_id
1847
-        );
1848
-    }
1849
-
1850
-
1851
-    /**
1852
-     * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1853
-     * @param string                   $relationName
1854
-     * @param array                    $where_query
1855
-     * @return bool|EE_Base_Class|null
1856
-     * @throws EE_Error
1857
-     * @throws ReflectionException
1858
-     * @since   $VID:$
1859
-     */
1860
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = [])
1861
-    {
1862
-        // if we're adding a new relation to a datetime
1863
-        if ($relationName === 'Datetime' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1864
-            /** @var EE_Datetime $datetime */
1865
-            $datetime = EEM_Datetime::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1866
-            $datetime->decreaseSold($this->sold());
1867
-            $datetime->decreaseReserved($this->reserved());
1868
-            $datetime->save();
1869
-            $otherObjectModelObjectOrID = $datetime;
1870
-        }
1871
-        return parent::_remove_relation_to(
1872
-            $otherObjectModelObjectOrID,
1873
-            $relationName,
1874
-            $where_query
1875
-        );
1876
-    }
1877
-
1878
-
1879
-    /**
1880
-     * Removes ALL the related things for the $relationName.
1881
-     *
1882
-     * @param string $relationName
1883
-     * @param array  $where_query_params
1884
-     * @return EE_Base_Class
1885
-     * @throws ReflectionException
1886
-     * @throws InvalidArgumentException
1887
-     * @throws InvalidInterfaceException
1888
-     * @throws InvalidDataTypeException
1889
-     * @throws EE_Error
1890
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
1891
-     */
1892
-    public function _remove_relations($relationName, $where_query_params = [])
1893
-    {
1894
-        if ($relationName === 'Datetime') {
1895
-            $datetimes = $this->datetimes();
1896
-            foreach ($datetimes as $datetime) {
1897
-                $datetime->decreaseSold($this->sold());
1898
-                $datetime->decreaseReserved($this->reserved());
1899
-                $datetime->save();
1900
-            }
1901
-        }
1902
-        return parent::_remove_relations($relationName, $where_query_params);
1903
-    }
1904
-
1905
-
1906
-    /*******************************************************************
17
+	/**
18
+	 * TicKet Sold out:
19
+	 * constant used by ticket_status() to indicate that a ticket is sold out
20
+	 * and no longer available for purchases
21
+	 */
22
+	const sold_out = 'TKS';
23
+
24
+	/**
25
+	 * TicKet Expired:
26
+	 * constant used by ticket_status() to indicate that a ticket is expired
27
+	 * and no longer available for purchase
28
+	 */
29
+	const expired = 'TKE';
30
+
31
+	/**
32
+	 * TicKet Archived:
33
+	 * constant used by ticket_status() to indicate that a ticket is archived
34
+	 * and no longer available for purchase
35
+	 */
36
+	const archived = 'TKA';
37
+
38
+	/**
39
+	 * TicKet Pending:
40
+	 * constant used by ticket_status() to indicate that a ticket is pending
41
+	 * and is NOT YET available for purchase
42
+	 */
43
+	const pending = 'TKP';
44
+
45
+	/**
46
+	 * TicKet On sale:
47
+	 * constant used by ticket_status() to indicate that a ticket is On Sale
48
+	 * and IS available for purchase
49
+	 */
50
+	const onsale = 'TKO';
51
+
52
+	/**
53
+	 * extra meta key for tracking ticket reservations
54
+	 *
55
+	 * @type string
56
+	 */
57
+	const META_KEY_TICKET_RESERVATIONS = 'ticket_reservations';
58
+
59
+	/**
60
+	 * override of parent property
61
+	 *
62
+	 * @var EEM_Ticket
63
+	 */
64
+	protected $_model;
65
+
66
+	/**
67
+	 * cached result from method of the same name
68
+	 *
69
+	 * @var float $_ticket_total_with_taxes
70
+	 */
71
+	private $_ticket_total_with_taxes;
72
+
73
+
74
+	/**
75
+	 * @param array  $props_n_values          incoming values
76
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
77
+	 *                                        used.)
78
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
79
+	 *                                        date_format and the second value is the time format
80
+	 * @return EE_Ticket
81
+	 * @throws EE_Error
82
+	 * @throws ReflectionException
83
+	 */
84
+	public static function new_instance($props_n_values = [], $timezone = null, $date_formats = [])
85
+	{
86
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
87
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
88
+	}
89
+
90
+
91
+	/**
92
+	 * @param array  $props_n_values  incoming values from the database
93
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
94
+	 *                                the website will be used.
95
+	 * @return EE_Ticket
96
+	 * @throws EE_Error
97
+	 * @throws ReflectionException
98
+	 */
99
+	public static function new_instance_from_db($props_n_values = [], $timezone = null)
100
+	{
101
+		return new self($props_n_values, true, $timezone);
102
+	}
103
+
104
+
105
+	/**
106
+	 * @return bool
107
+	 * @throws EE_Error
108
+	 * @throws ReflectionException
109
+	 */
110
+	public function parent()
111
+	{
112
+		return $this->get('TKT_parent');
113
+	}
114
+
115
+
116
+	/**
117
+	 * return if a ticket has quantities available for purchase
118
+	 *
119
+	 * @param int $DTT_ID the primary key for a particular datetime
120
+	 * @return boolean
121
+	 * @throws EE_Error
122
+	 * @throws ReflectionException
123
+	 */
124
+	public function available($DTT_ID = 0)
125
+	{
126
+		// are we checking availability for a particular datetime ?
127
+		if ($DTT_ID) {
128
+			// get that datetime object
129
+			$datetime = $this->get_first_related('Datetime', [['DTT_ID' => $DTT_ID]]);
130
+			// if  ticket sales for this datetime have exceeded the reg limit...
131
+			if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
132
+				return false;
133
+			}
134
+		}
135
+		// datetime is still open for registration, but is this ticket sold out ?
136
+		return $this->qty() < 1 || $this->qty() > $this->sold();
137
+	}
138
+
139
+
140
+	/**
141
+	 * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
142
+	 *
143
+	 * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the
144
+	 *                               relevant status const
145
+	 * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save
146
+	 *                               further processing
147
+	 * @return mixed status int if the display string isn't requested
148
+	 * @throws EE_Error
149
+	 * @throws ReflectionException
150
+	 */
151
+	public function ticket_status($display = false, $remaining = null)
152
+	{
153
+		$remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
154
+		if (! $remaining) {
155
+			return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out;
156
+		}
157
+		if ($this->get('TKT_deleted')) {
158
+			return $display ? EEH_Template::pretty_status(EE_Ticket::archived, false, 'sentence') : EE_Ticket::archived;
159
+		}
160
+		if ($this->is_expired()) {
161
+			return $display ? EEH_Template::pretty_status(EE_Ticket::expired, false, 'sentence') : EE_Ticket::expired;
162
+		}
163
+		if ($this->is_pending()) {
164
+			return $display ? EEH_Template::pretty_status(EE_Ticket::pending, false, 'sentence') : EE_Ticket::pending;
165
+		}
166
+		if ($this->is_on_sale()) {
167
+			return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence') : EE_Ticket::onsale;
168
+		}
169
+		return '';
170
+	}
171
+
172
+
173
+	/**
174
+	 * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale
175
+	 * considering ALL the factors used for figuring that out.
176
+	 *
177
+	 * @access public
178
+	 * @param int $DTT_ID if an int above 0 is included here then we get a specific dtt.
179
+	 * @return boolean         true = tickets remaining, false not.
180
+	 * @throws EE_Error
181
+	 * @throws ReflectionException
182
+	 */
183
+	public function is_remaining($DTT_ID = 0)
184
+	{
185
+		$num_remaining = $this->remaining($DTT_ID);
186
+		if ($num_remaining === 0) {
187
+			return false;
188
+		}
189
+		if ($num_remaining > 0 && $num_remaining < $this->min()) {
190
+			return false;
191
+		}
192
+		return true;
193
+	}
194
+
195
+
196
+	/**
197
+	 * return the total number of tickets available for purchase
198
+	 *
199
+	 * @param int $DTT_ID  the primary key for a particular datetime.
200
+	 *                     set to 0 for all related datetimes
201
+	 * @return int
202
+	 * @throws EE_Error
203
+	 * @throws ReflectionException
204
+	 */
205
+	public function remaining($DTT_ID = 0)
206
+	{
207
+		return $this->real_quantity_on_ticket('saleable', $DTT_ID);
208
+	}
209
+
210
+
211
+	/**
212
+	 * Gets min
213
+	 *
214
+	 * @return int
215
+	 * @throws EE_Error
216
+	 * @throws ReflectionException
217
+	 */
218
+	public function min()
219
+	{
220
+		return $this->get('TKT_min');
221
+	}
222
+
223
+
224
+	/**
225
+	 * return if a ticket is no longer available cause its available dates have expired.
226
+	 *
227
+	 * @return boolean
228
+	 * @throws EE_Error
229
+	 * @throws ReflectionException
230
+	 */
231
+	public function is_expired()
232
+	{
233
+		return ($this->get_raw('TKT_end_date') < time());
234
+	}
235
+
236
+
237
+	/**
238
+	 * Return if a ticket is yet to go on sale or not
239
+	 *
240
+	 * @return boolean
241
+	 * @throws EE_Error
242
+	 * @throws ReflectionException
243
+	 */
244
+	public function is_pending()
245
+	{
246
+		return ($this->get_raw('TKT_start_date') >= time());
247
+	}
248
+
249
+
250
+	/**
251
+	 * Return if a ticket is on sale or not
252
+	 *
253
+	 * @return boolean
254
+	 * @throws EE_Error
255
+	 * @throws ReflectionException
256
+	 */
257
+	public function is_on_sale()
258
+	{
259
+		return ($this->get_raw('TKT_start_date') <= time() && $this->get_raw('TKT_end_date') >= time());
260
+	}
261
+
262
+
263
+	/**
264
+	 * This returns the chronologically last datetime that this ticket is associated with
265
+	 *
266
+	 * @param string $date_format
267
+	 * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with
268
+	 *                            the end date ie: Jan 01 "to" Dec 31
269
+	 * @return string
270
+	 * @throws EE_Error
271
+	 * @throws ReflectionException
272
+	 */
273
+	public function date_range($date_format = '', $conjunction = ' - ')
274
+	{
275
+		$date_format = ! empty($date_format) ? $date_format : $this->_dt_frmt;
276
+		$first_date  = $this->first_datetime() instanceof EE_Datetime
277
+			? $this->first_datetime()->get_i18n_datetime('DTT_EVT_start', $date_format)
278
+			: '';
279
+		$last_date   = $this->last_datetime() instanceof EE_Datetime
280
+			? $this->last_datetime()->get_i18n_datetime('DTT_EVT_end', $date_format)
281
+			: '';
282
+
283
+		return $first_date && $last_date ? $first_date . $conjunction . $last_date : '';
284
+	}
285
+
286
+
287
+	/**
288
+	 * This returns the chronologically first datetime that this ticket is associated with
289
+	 *
290
+	 * @return EE_Datetime
291
+	 * @throws EE_Error
292
+	 * @throws ReflectionException
293
+	 */
294
+	public function first_datetime()
295
+	{
296
+		$datetimes = $this->datetimes(['limit' => 1]);
297
+		return reset($datetimes);
298
+	}
299
+
300
+
301
+	/**
302
+	 * Gets all the datetimes this ticket can be used for attending.
303
+	 * Unless otherwise specified, orders datetimes by start date.
304
+	 *
305
+	 * @param array $query_params @see
306
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
307
+	 * @return EE_Datetime[]|EE_Base_Class[]
308
+	 * @throws EE_Error
309
+	 * @throws ReflectionException
310
+	 */
311
+	public function datetimes($query_params = [])
312
+	{
313
+		if (! isset($query_params['order_by'])) {
314
+			$query_params['order_by']['DTT_order'] = 'ASC';
315
+		}
316
+		return $this->get_many_related('Datetime', $query_params);
317
+	}
318
+
319
+
320
+	/**
321
+	 * This returns the chronologically last datetime that this ticket is associated with
322
+	 *
323
+	 * @return EE_Datetime
324
+	 * @throws EE_Error
325
+	 * @throws ReflectionException
326
+	 */
327
+	public function last_datetime()
328
+	{
329
+		$datetimes = $this->datetimes(['limit' => 1, 'order_by' => ['DTT_EVT_start' => 'DESC']]);
330
+		return end($datetimes);
331
+	}
332
+
333
+
334
+	/**
335
+	 * This returns the total tickets sold depending on the given parameters.
336
+	 *
337
+	 * @param string $what    Can be one of two options: 'ticket', 'datetime'.
338
+	 *                        'ticket' = total ticket sales for all datetimes this ticket is related to
339
+	 *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
340
+	 *                        'datetime' = total ticket sales in the datetime_ticket table.
341
+	 *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
342
+	 *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
343
+	 * @param int    $dtt_id  [optional] include the dtt_id with $what = 'datetime'.
344
+	 * @return mixed (array|int)          how many tickets have sold
345
+	 * @throws EE_Error
346
+	 * @throws ReflectionException
347
+	 */
348
+	public function tickets_sold($what = 'ticket', $dtt_id = null)
349
+	{
350
+		$total        = 0;
351
+		$tickets_sold = $this->_all_tickets_sold();
352
+		switch ($what) {
353
+			case 'ticket':
354
+				return $tickets_sold['ticket'];
355
+				break;
356
+			case 'datetime':
357
+				if (empty($tickets_sold['datetime'])) {
358
+					return $total;
359
+				}
360
+				if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) {
361
+					EE_Error::add_error(
362
+						__(
363
+							'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?',
364
+							'event_espresso'
365
+						),
366
+						__FILE__,
367
+						__FUNCTION__,
368
+						__LINE__
369
+					);
370
+					return $total;
371
+				}
372
+				return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ];
373
+				break;
374
+			default:
375
+				return $total;
376
+		}
377
+	}
378
+
379
+
380
+	/**
381
+	 * This returns an array indexed by datetime_id for tickets sold with this ticket.
382
+	 *
383
+	 * @return EE_Ticket[]
384
+	 * @throws EE_Error
385
+	 * @throws ReflectionException
386
+	 */
387
+	protected function _all_tickets_sold()
388
+	{
389
+		$datetimes    = $this->get_many_related('Datetime');
390
+		$tickets_sold = [];
391
+		if (! empty($datetimes)) {
392
+			foreach ($datetimes as $datetime) {
393
+				$tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold');
394
+			}
395
+		}
396
+		// Tickets sold
397
+		$tickets_sold['ticket'] = $this->sold();
398
+		return $tickets_sold;
399
+	}
400
+
401
+
402
+	/**
403
+	 * This returns the base price object for the ticket.
404
+	 *
405
+	 * @param bool $return_array whether to return as an array indexed by price id or just the object.
406
+	 * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
407
+	 * @throws EE_Error
408
+	 * @throws ReflectionException
409
+	 */
410
+	public function base_price($return_array = false)
411
+	{
412
+		$_where = ['Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price];
413
+		return $return_array
414
+			? $this->get_many_related('Price', [$_where])
415
+			: $this->get_first_related('Price', [$_where]);
416
+	}
417
+
418
+
419
+	/**
420
+	 * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
421
+	 *
422
+	 * @access public
423
+	 * @return EE_Price[]
424
+	 * @throws EE_Error
425
+	 * @throws ReflectionException
426
+	 */
427
+	public function price_modifiers()
428
+	{
429
+		$query_params = [
430
+			0 => [
431
+				'Price_Type.PBT_ID' => [
432
+					'NOT IN',
433
+					[EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax],
434
+				],
435
+			],
436
+		];
437
+		return $this->prices($query_params);
438
+	}
439
+
440
+
441
+	/**
442
+	 * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
443
+	 *
444
+	 * @access public
445
+	 * @return EE_Price[]
446
+	 * @throws EE_Error
447
+	 * @throws ReflectionException
448
+	 */
449
+	public function tax_price_modifiers()
450
+	{
451
+		$query_params = [
452
+			0 => [
453
+				'Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax,
454
+			],
455
+		];
456
+		return $this->prices($query_params);
457
+	}
458
+
459
+
460
+	/**
461
+	 * Gets all the prices that combine to form the final price of this ticket
462
+	 *
463
+	 * @param array $query_params @see
464
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
465
+	 * @return EE_Price[]|EE_Base_Class[]
466
+	 * @throws EE_Error
467
+	 * @throws ReflectionException
468
+	 */
469
+	public function prices($query_params = [])
470
+	{
471
+		return $this->get_many_related('Price', $query_params);
472
+	}
473
+
474
+
475
+	/**
476
+	 * Gets all the ticket datetimes (ie, relations between datetimes and tickets)
477
+	 *
478
+	 * @param array $query_params @see
479
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
480
+	 * @return EE_Datetime_Ticket|EE_Base_Class[]
481
+	 * @throws EE_Error
482
+	 * @throws ReflectionException
483
+	 */
484
+	public function datetime_tickets($query_params = [])
485
+	{
486
+		return $this->get_many_related('Datetime_Ticket', $query_params);
487
+	}
488
+
489
+
490
+	/**
491
+	 * Gets all the datetimes from the db ordered by DTT_order
492
+	 *
493
+	 * @param boolean $show_expired
494
+	 * @param boolean $show_deleted
495
+	 * @return EE_Datetime[]
496
+	 * @throws EE_Error
497
+	 * @throws ReflectionException
498
+	 */
499
+	public function datetimes_ordered($show_expired = true, $show_deleted = false)
500
+	{
501
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order(
502
+			$this->ID(),
503
+			$show_expired,
504
+			$show_deleted
505
+		);
506
+	}
507
+
508
+
509
+	/**
510
+	 * Gets ID
511
+	 *
512
+	 * @return int
513
+	 * @throws EE_Error
514
+	 * @throws ReflectionException
515
+	 */
516
+	public function ID()
517
+	{
518
+		return $this->get('TKT_ID');
519
+	}
520
+
521
+
522
+	/**
523
+	 * get the author of the ticket.
524
+	 *
525
+	 * @return int
526
+	 * @throws EE_Error
527
+	 * @throws ReflectionException
528
+	 * @since 4.5.0
529
+	 */
530
+	public function wp_user()
531
+	{
532
+		return $this->get('TKT_wp_user');
533
+	}
534
+
535
+
536
+	/**
537
+	 * Gets the template for the ticket
538
+	 *
539
+	 * @return EE_Ticket_Template|EE_Base_Class
540
+	 * @throws EE_Error
541
+	 * @throws ReflectionException
542
+	 */
543
+	public function template()
544
+	{
545
+		return $this->get_first_related('Ticket_Template');
546
+	}
547
+
548
+
549
+	/**
550
+	 * Simply returns an array of EE_Price objects that are taxes.
551
+	 *
552
+	 * @return EE_Price[]
553
+	 * @throws EE_Error
554
+	 */
555
+	public function get_ticket_taxes_for_admin()
556
+	{
557
+		return EE_Taxes::get_taxes_for_admin();
558
+	}
559
+
560
+
561
+	/**
562
+	 * @return float
563
+	 * @throws EE_Error
564
+	 * @throws ReflectionException
565
+	 */
566
+	public function ticket_price()
567
+	{
568
+		return $this->get('TKT_price');
569
+	}
570
+
571
+
572
+	/**
573
+	 * @return mixed
574
+	 * @throws EE_Error
575
+	 * @throws ReflectionException
576
+	 */
577
+	public function pretty_price()
578
+	{
579
+		return $this->get_pretty('TKT_price');
580
+	}
581
+
582
+
583
+	/**
584
+	 * @return bool
585
+	 * @throws EE_Error
586
+	 * @throws ReflectionException
587
+	 */
588
+	public function is_free()
589
+	{
590
+		return $this->get_ticket_total_with_taxes() === (float) 0;
591
+	}
592
+
593
+
594
+	/**
595
+	 * get_ticket_total_with_taxes
596
+	 *
597
+	 * @param bool $no_cache
598
+	 * @return float
599
+	 * @throws EE_Error
600
+	 * @throws ReflectionException
601
+	 */
602
+	public function get_ticket_total_with_taxes($no_cache = false)
603
+	{
604
+		if ($this->_ticket_total_with_taxes === null || $no_cache) {
605
+			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
606
+		}
607
+		return (float) $this->_ticket_total_with_taxes;
608
+	}
609
+
610
+
611
+	/**
612
+	 * @throws EE_Error
613
+	 * @throws ReflectionException
614
+	 */
615
+	public function ensure_TKT_Price_correct()
616
+	{
617
+		$this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
618
+		$this->save();
619
+	}
620
+
621
+
622
+	/**
623
+	 * @return float
624
+	 * @throws EE_Error
625
+	 * @throws ReflectionException
626
+	 */
627
+	public function get_ticket_subtotal()
628
+	{
629
+		return EE_Taxes::get_subtotal_for_admin($this);
630
+	}
631
+
632
+
633
+	/**
634
+	 * Returns the total taxes applied to this ticket
635
+	 *
636
+	 * @return float
637
+	 * @throws EE_Error
638
+	 * @throws ReflectionException
639
+	 */
640
+	public function get_ticket_taxes_total_for_admin()
641
+	{
642
+		return EE_Taxes::get_total_taxes_for_admin($this);
643
+	}
644
+
645
+
646
+	/**
647
+	 * Sets name
648
+	 *
649
+	 * @param string $name
650
+	 * @throws EE_Error
651
+	 * @throws ReflectionException
652
+	 */
653
+	public function set_name($name)
654
+	{
655
+		$this->set('TKT_name', $name);
656
+	}
657
+
658
+
659
+	/**
660
+	 * Gets description
661
+	 *
662
+	 * @return string
663
+	 * @throws EE_Error
664
+	 * @throws ReflectionException
665
+	 */
666
+	public function description()
667
+	{
668
+		return $this->get('TKT_description');
669
+	}
670
+
671
+
672
+	/**
673
+	 * Sets description
674
+	 *
675
+	 * @param string $description
676
+	 * @throws EE_Error
677
+	 * @throws ReflectionException
678
+	 */
679
+	public function set_description($description)
680
+	{
681
+		$this->set('TKT_description', $description);
682
+	}
683
+
684
+
685
+	/**
686
+	 * Gets start_date
687
+	 *
688
+	 * @param string $date_format
689
+	 * @param string $time_format
690
+	 * @return string
691
+	 * @throws EE_Error
692
+	 * @throws ReflectionException
693
+	 */
694
+	public function start_date($date_format = '', $time_format = '')
695
+	{
696
+		return $this->_get_datetime('TKT_start_date', $date_format, $time_format);
697
+	}
698
+
699
+
700
+	/**
701
+	 * Sets start_date
702
+	 *
703
+	 * @param string $start_date
704
+	 * @return void
705
+	 * @throws EE_Error
706
+	 * @throws ReflectionException
707
+	 */
708
+	public function set_start_date($start_date)
709
+	{
710
+		$this->_set_date_time('B', $start_date, 'TKT_start_date');
711
+	}
712
+
713
+
714
+	/**
715
+	 * Gets end_date
716
+	 *
717
+	 * @param string $date_format
718
+	 * @param string $time_format
719
+	 * @return string
720
+	 * @throws EE_Error
721
+	 * @throws ReflectionException
722
+	 */
723
+	public function end_date($date_format = '', $time_format = '')
724
+	{
725
+		return $this->_get_datetime('TKT_end_date', $date_format, $time_format);
726
+	}
727
+
728
+
729
+	/**
730
+	 * Sets end_date
731
+	 *
732
+	 * @param string $end_date
733
+	 * @return void
734
+	 * @throws EE_Error
735
+	 * @throws ReflectionException
736
+	 */
737
+	public function set_end_date($end_date)
738
+	{
739
+		$this->_set_date_time('B', $end_date, 'TKT_end_date');
740
+	}
741
+
742
+
743
+	/**
744
+	 * Sets sell until time
745
+	 *
746
+	 * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
747
+	 * @throws EE_Error
748
+	 * @throws ReflectionException
749
+	 * @since 4.5.0
750
+	 */
751
+	public function set_end_time($time)
752
+	{
753
+		$this->_set_time_for($time, 'TKT_end_date');
754
+	}
755
+
756
+
757
+	/**
758
+	 * Sets min
759
+	 *
760
+	 * @param int $min
761
+	 * @return void
762
+	 * @throws EE_Error
763
+	 * @throws ReflectionException
764
+	 */
765
+	public function set_min($min)
766
+	{
767
+		$this->set('TKT_min', $min);
768
+	}
769
+
770
+
771
+	/**
772
+	 * Gets max
773
+	 *
774
+	 * @return int
775
+	 * @throws EE_Error
776
+	 * @throws ReflectionException
777
+	 */
778
+	public function max()
779
+	{
780
+		return $this->get('TKT_max');
781
+	}
782
+
783
+
784
+	/**
785
+	 * Sets max
786
+	 *
787
+	 * @param int $max
788
+	 * @return void
789
+	 * @throws EE_Error
790
+	 * @throws ReflectionException
791
+	 */
792
+	public function set_max($max)
793
+	{
794
+		$this->set('TKT_max', $max);
795
+	}
796
+
797
+
798
+	/**
799
+	 * Sets price
800
+	 *
801
+	 * @param float $price
802
+	 * @return void
803
+	 * @throws EE_Error
804
+	 * @throws ReflectionException
805
+	 */
806
+	public function set_price($price)
807
+	{
808
+		$this->set('TKT_price', $price);
809
+	}
810
+
811
+
812
+	/**
813
+	 * Gets sold
814
+	 *
815
+	 * @return int
816
+	 * @throws EE_Error
817
+	 * @throws ReflectionException
818
+	 */
819
+	public function sold()
820
+	{
821
+		return $this->get_raw('TKT_sold');
822
+	}
823
+
824
+
825
+	/**
826
+	 * Sets sold
827
+	 *
828
+	 * @param int $sold
829
+	 * @return void
830
+	 * @throws EE_Error
831
+	 * @throws ReflectionException
832
+	 */
833
+	public function set_sold($sold)
834
+	{
835
+		// sold can not go below zero
836
+		$sold = max(0, $sold);
837
+		$this->set('TKT_sold', $sold);
838
+	}
839
+
840
+
841
+	/**
842
+	 * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
843
+	 * associated datetimes.
844
+	 *
845
+	 * @param int $qty
846
+	 * @return boolean
847
+	 * @throws EE_Error
848
+	 * @throws InvalidArgumentException
849
+	 * @throws InvalidDataTypeException
850
+	 * @throws InvalidInterfaceException
851
+	 * @throws ReflectionException
852
+	 * @since 4.9.80.p
853
+	 */
854
+	public function increaseSold($qty = 1)
855
+	{
856
+		$qty = absint($qty);
857
+		// increment sold and decrement reserved datetime quantities simultaneously
858
+		// don't worry about failures, because they must have already had a spot reserved
859
+		$this->increaseSoldForDatetimes($qty);
860
+		// Increment and decrement ticket quantities simultaneously
861
+		$success = $this->adjustNumericFieldsInDb(
862
+			[
863
+				'TKT_reserved' => $qty * -1,
864
+				'TKT_sold'     => $qty,
865
+			]
866
+		);
867
+		do_action(
868
+			'AHEE__EE_Ticket__increase_sold',
869
+			$this,
870
+			$qty,
871
+			$this->sold(),
872
+			$success
873
+		);
874
+		return $success;
875
+	}
876
+
877
+
878
+	/**
879
+	 * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
880
+	 *
881
+	 * @param int           $qty positive or negative. Positive means to increase sold counts (and decrease reserved
882
+	 *                           counts), Negative means to decreases old counts (and increase reserved counts).
883
+	 * @param EE_Datetime[] $datetimes
884
+	 * @throws EE_Error
885
+	 * @throws InvalidArgumentException
886
+	 * @throws InvalidDataTypeException
887
+	 * @throws InvalidInterfaceException
888
+	 * @throws ReflectionException
889
+	 * @since 4.9.80.p
890
+	 */
891
+	protected function increaseSoldForDatetimes($qty, array $datetimes = [])
892
+	{
893
+		$datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
894
+		foreach ($datetimes as $datetime) {
895
+			$datetime->increaseSold($qty);
896
+		}
897
+	}
898
+
899
+
900
+	/**
901
+	 * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
902
+	 * DB and then updates the model objects.
903
+	 * Does not affect the reserved counts.
904
+	 *
905
+	 * @param int $qty
906
+	 * @return boolean
907
+	 * @throws EE_Error
908
+	 * @throws InvalidArgumentException
909
+	 * @throws InvalidDataTypeException
910
+	 * @throws InvalidInterfaceException
911
+	 * @throws ReflectionException
912
+	 * @since 4.9.80.p
913
+	 */
914
+	public function decreaseSold($qty = 1)
915
+	{
916
+		$qty = absint($qty);
917
+		$this->decreaseSoldForDatetimes($qty);
918
+		$success = $this->adjustNumericFieldsInDb(
919
+			[
920
+				'TKT_sold' => $qty * -1,
921
+			]
922
+		);
923
+		do_action(
924
+			'AHEE__EE_Ticket__decrease_sold',
925
+			$this,
926
+			$qty,
927
+			$this->sold(),
928
+			$success
929
+		);
930
+		return $success;
931
+	}
932
+
933
+
934
+	/**
935
+	 * Decreases sold on related datetimes
936
+	 *
937
+	 * @param int           $qty
938
+	 * @param EE_Datetime[] $datetimes
939
+	 * @return void
940
+	 * @throws EE_Error
941
+	 * @throws InvalidArgumentException
942
+	 * @throws InvalidDataTypeException
943
+	 * @throws InvalidInterfaceException
944
+	 * @throws ReflectionException
945
+	 * @since 4.9.80.p
946
+	 */
947
+	protected function decreaseSoldForDatetimes($qty = 1, array $datetimes = [])
948
+	{
949
+		$datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
950
+		if (is_array($datetimes)) {
951
+			foreach ($datetimes as $datetime) {
952
+				if ($datetime instanceof EE_Datetime) {
953
+					$datetime->decreaseSold($qty);
954
+				}
955
+			}
956
+		}
957
+	}
958
+
959
+
960
+	/**
961
+	 * Gets qty of reserved tickets
962
+	 *
963
+	 * @return int
964
+	 * @throws EE_Error
965
+	 * @throws ReflectionException
966
+	 */
967
+	public function reserved()
968
+	{
969
+		return $this->get_raw('TKT_reserved');
970
+	}
971
+
972
+
973
+	/**
974
+	 * Sets reserved
975
+	 *
976
+	 * @param int $reserved
977
+	 * @return void
978
+	 * @throws EE_Error
979
+	 * @throws ReflectionException
980
+	 */
981
+	public function set_reserved($reserved)
982
+	{
983
+		// reserved can not go below zero
984
+		$reserved = max(0, (int) $reserved);
985
+		$this->set('TKT_reserved', $reserved);
986
+	}
987
+
988
+
989
+	/**
990
+	 * Increments reserved by amount passed by $qty, and persists it immediately to the database.
991
+	 *
992
+	 * @param int    $qty
993
+	 * @param string $source
994
+	 * @return bool whether we successfully reserved the ticket or not.
995
+	 * @throws EE_Error
996
+	 * @throws InvalidArgumentException
997
+	 * @throws ReflectionException
998
+	 * @throws InvalidDataTypeException
999
+	 * @throws InvalidInterfaceException
1000
+	 * @since 4.9.80.p
1001
+	 */
1002
+	public function increaseReserved($qty = 1, $source = 'unknown')
1003
+	{
1004
+		$qty = absint($qty);
1005
+		do_action(
1006
+			'AHEE__EE_Ticket__increase_reserved__begin',
1007
+			$this,
1008
+			$qty,
1009
+			$source
1010
+		);
1011
+		$this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "{$qty} from {$source}");
1012
+		$success                         = false;
1013
+		$datetimes_adjusted_successfully = $this->increaseReservedForDatetimes($qty);
1014
+		if ($datetimes_adjusted_successfully) {
1015
+			$success = $this->incrementFieldConditionallyInDb(
1016
+				'TKT_reserved',
1017
+				'TKT_sold',
1018
+				'TKT_qty',
1019
+				$qty
1020
+			);
1021
+			if (! $success) {
1022
+				// The datetimes were successfully bumped, but not the
1023
+				// ticket. So we need to manually rollback the datetimes.
1024
+				$this->decreaseReservedForDatetimes($qty);
1025
+			}
1026
+		}
1027
+		do_action(
1028
+			'AHEE__EE_Ticket__increase_reserved',
1029
+			$this,
1030
+			$qty,
1031
+			$this->reserved(),
1032
+			$success
1033
+		);
1034
+		return $success;
1035
+	}
1036
+
1037
+
1038
+	/**
1039
+	 * Increases reserved counts on related datetimes
1040
+	 *
1041
+	 * @param int           $qty
1042
+	 * @param EE_Datetime[] $datetimes
1043
+	 * @return boolean indicating success
1044
+	 * @throws EE_Error
1045
+	 * @throws InvalidArgumentException
1046
+	 * @throws InvalidDataTypeException
1047
+	 * @throws InvalidInterfaceException
1048
+	 * @throws ReflectionException
1049
+	 * @since 4.9.80.p
1050
+	 */
1051
+	protected function increaseReservedForDatetimes($qty = 1, array $datetimes = [])
1052
+	{
1053
+		$datetimes         = ! empty($datetimes) ? $datetimes : $this->datetimes();
1054
+		$datetimes_updated = [];
1055
+		$limit_exceeded    = false;
1056
+		if (is_array($datetimes)) {
1057
+			foreach ($datetimes as $datetime) {
1058
+				if ($datetime instanceof EE_Datetime) {
1059
+					if ($datetime->increaseReserved($qty)) {
1060
+						$datetimes_updated[] = $datetime;
1061
+					} else {
1062
+						$limit_exceeded = true;
1063
+						break;
1064
+					}
1065
+				}
1066
+			}
1067
+			// If somewhere along the way we detected a datetime whose
1068
+			// limit was exceeded, do a manual rollback.
1069
+			if ($limit_exceeded) {
1070
+				$this->decreaseReservedForDatetimes($qty, $datetimes_updated);
1071
+				return false;
1072
+			}
1073
+		}
1074
+		return true;
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
1080
+	 *
1081
+	 * @param int    $qty
1082
+	 * @param bool   $adjust_datetimes
1083
+	 * @param string $source
1084
+	 * @return boolean
1085
+	 * @throws EE_Error
1086
+	 * @throws InvalidArgumentException
1087
+	 * @throws ReflectionException
1088
+	 * @throws InvalidDataTypeException
1089
+	 * @throws InvalidInterfaceException
1090
+	 * @since 4.9.80.p
1091
+	 */
1092
+	public function decreaseReserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
1093
+	{
1094
+		$qty = absint($qty);
1095
+		$this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "-{$qty} from {$source}");
1096
+		if ($adjust_datetimes) {
1097
+			$this->decreaseReservedForDatetimes($qty);
1098
+		}
1099
+		$success = $this->adjustNumericFieldsInDb(
1100
+			[
1101
+				'TKT_reserved' => $qty * -1,
1102
+			]
1103
+		);
1104
+		do_action(
1105
+			'AHEE__EE_Ticket__decrease_reserved',
1106
+			$this,
1107
+			$qty,
1108
+			$this->reserved(),
1109
+			$success
1110
+		);
1111
+		return $success;
1112
+	}
1113
+
1114
+
1115
+	/**
1116
+	 * Decreases the reserved count on the specified datetimes.
1117
+	 *
1118
+	 * @param int           $qty
1119
+	 * @param EE_Datetime[] $datetimes
1120
+	 * @throws EE_Error
1121
+	 * @throws InvalidArgumentException
1122
+	 * @throws ReflectionException
1123
+	 * @throws InvalidDataTypeException
1124
+	 * @throws InvalidInterfaceException
1125
+	 * @since 4.9.80.p
1126
+	 */
1127
+	protected function decreaseReservedForDatetimes($qty = 1, array $datetimes = [])
1128
+	{
1129
+		$datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
1130
+		foreach ($datetimes as $datetime) {
1131
+			if ($datetime instanceof EE_Datetime) {
1132
+				$datetime->decreaseReserved($qty);
1133
+			}
1134
+		}
1135
+	}
1136
+
1137
+
1138
+	/**
1139
+	 * Gets ticket quantity
1140
+	 *
1141
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1142
+	 *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
1143
+	 *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
1144
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1145
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1146
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
1147
+	 * @return int
1148
+	 * @throws EE_Error
1149
+	 * @throws ReflectionException
1150
+	 */
1151
+	public function qty($context = '')
1152
+	{
1153
+		switch ($context) {
1154
+			case 'reg_limit':
1155
+				return $this->real_quantity_on_ticket();
1156
+			case 'saleable':
1157
+				return $this->real_quantity_on_ticket('saleable');
1158
+			default:
1159
+				return $this->get_raw('TKT_qty');
1160
+		}
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * Gets ticket quantity
1166
+	 *
1167
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1168
+	 *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
1169
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1170
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1171
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
1172
+	 * @param int    $DTT_ID      the primary key for a particular datetime.
1173
+	 *                            set to 0 for all related datetimes
1174
+	 * @return int
1175
+	 * @throws EE_Error
1176
+	 * @throws ReflectionException
1177
+	 */
1178
+	public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0)
1179
+	{
1180
+		$raw = $this->get_raw('TKT_qty');
1181
+		// return immediately if it's zero
1182
+		if ($raw === 0) {
1183
+			return $raw;
1184
+		}
1185
+		// echo "\n\n<br />Ticket: " . $this->name() . '<br />';
1186
+		// ensure qty doesn't exceed raw value for THIS ticket
1187
+		$qty = min(EE_INF, $raw);
1188
+		// echo "\n . qty: " . $qty . '<br />';
1189
+		// calculate this ticket's total sales and reservations
1190
+		$sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
1191
+		// echo "\n . sold: " . $this->sold() . '<br />';
1192
+		// echo "\n . reserved: " . $this->reserved() . '<br />';
1193
+		// echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
1194
+		// first we need to calculate the maximum number of tickets available for the datetime
1195
+		// do we want data for one datetime or all of them ?
1196
+		$query_params = $DTT_ID ? [['DTT_ID' => $DTT_ID]] : [];
1197
+		$datetimes    = $this->datetimes($query_params);
1198
+		if (is_array($datetimes) && ! empty($datetimes)) {
1199
+			foreach ($datetimes as $datetime) {
1200
+				if ($datetime instanceof EE_Datetime) {
1201
+					$datetime->refresh_from_db();
1202
+					// echo "\n . . datetime name: " . $datetime->name() . '<br />';
1203
+					// echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
1204
+					// initialize with no restrictions for each datetime
1205
+					// but adjust datetime qty based on datetime reg limit
1206
+					$datetime_qty = min(EE_INF, $datetime->reg_limit());
1207
+					// echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
1208
+					// echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1209
+					// if we want the actual saleable amount, then we need to consider OTHER ticket sales
1210
+					// and reservations for this datetime, that do NOT include sales and reservations
1211
+					// for this ticket (so we add $this->sold() and $this->reserved() back in)
1212
+					if ($context === 'saleable') {
1213
+						$datetime_qty = max(
1214
+							$datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
1215
+							0
1216
+						);
1217
+						// echo "\n . . . datetime sold: " . $datetime->sold() . '<br />';
1218
+						// echo "\n . . . datetime reserved: " . $datetime->reserved() . '<br />';
1219
+						// echo "\n . . . datetime sold_and_reserved: " . $datetime->sold_and_reserved() . '<br />';
1220
+						// echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1221
+						$datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
1222
+						// echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1223
+					}
1224
+					$qty = min($datetime_qty, $qty);
1225
+					// echo "\n . . qty: " . $qty . '<br />';
1226
+				}
1227
+			}
1228
+		}
1229
+		// NOW that we know the  maximum number of tickets available for the datetime
1230
+		// we can finally factor in the details for this specific ticket
1231
+		if ($qty > 0 && $context === 'saleable') {
1232
+			// and subtract the sales for THIS ticket
1233
+			$qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1234
+			// echo "\n . qty: " . $qty . '<br />';
1235
+		}
1236
+		// echo "\nFINAL QTY: " . $qty . "<br /><br />";
1237
+		return $qty;
1238
+	}
1239
+
1240
+
1241
+	/**
1242
+	 * Sets qty - IMPORTANT!!! Does NOT allow QTY to be set higher than the lowest reg limit of any related datetimes
1243
+	 *
1244
+	 * @param int $qty
1245
+	 * @return void
1246
+	 * @throws EE_Error
1247
+	 * @throws ReflectionException
1248
+	 */
1249
+	public function set_qty($qty)
1250
+	{
1251
+		$datetimes = $this->datetimes();
1252
+		foreach ($datetimes as $datetime) {
1253
+			if ($datetime instanceof EE_Datetime) {
1254
+				$qty = min($qty, $datetime->reg_limit());
1255
+			}
1256
+		}
1257
+		$this->set('TKT_qty', $qty);
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * Gets uses
1263
+	 *
1264
+	 * @return int
1265
+	 * @throws EE_Error
1266
+	 * @throws ReflectionException
1267
+	 */
1268
+	public function uses()
1269
+	{
1270
+		return $this->get('TKT_uses');
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * Sets uses
1276
+	 *
1277
+	 * @param int $uses
1278
+	 * @return void
1279
+	 * @throws EE_Error
1280
+	 * @throws ReflectionException
1281
+	 */
1282
+	public function set_uses($uses)
1283
+	{
1284
+		$this->set('TKT_uses', $uses);
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * returns whether ticket is required or not.
1290
+	 *
1291
+	 * @return boolean
1292
+	 * @throws EE_Error
1293
+	 * @throws ReflectionException
1294
+	 */
1295
+	public function required()
1296
+	{
1297
+		return $this->get('TKT_required');
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 * sets the TKT_required property
1303
+	 *
1304
+	 * @param boolean $required
1305
+	 * @return void
1306
+	 * @throws EE_Error
1307
+	 * @throws ReflectionException
1308
+	 */
1309
+	public function set_required($required)
1310
+	{
1311
+		$this->set('TKT_required', $required);
1312
+	}
1313
+
1314
+
1315
+	/**
1316
+	 * Gets taxable
1317
+	 *
1318
+	 * @return boolean
1319
+	 * @throws EE_Error
1320
+	 * @throws ReflectionException
1321
+	 */
1322
+	public function taxable()
1323
+	{
1324
+		return $this->get('TKT_taxable');
1325
+	}
1326
+
1327
+
1328
+	/**
1329
+	 * Sets taxable
1330
+	 *
1331
+	 * @param boolean $taxable
1332
+	 * @return void
1333
+	 * @throws EE_Error
1334
+	 * @throws ReflectionException
1335
+	 */
1336
+	public function set_taxable($taxable)
1337
+	{
1338
+		$this->set('TKT_taxable', $taxable);
1339
+	}
1340
+
1341
+
1342
+	/**
1343
+	 * Gets is_default
1344
+	 *
1345
+	 * @return boolean
1346
+	 * @throws EE_Error
1347
+	 * @throws ReflectionException
1348
+	 */
1349
+	public function is_default()
1350
+	{
1351
+		return $this->get('TKT_is_default');
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 * Sets is_default
1357
+	 *
1358
+	 * @param boolean $is_default
1359
+	 * @return void
1360
+	 * @throws EE_Error
1361
+	 * @throws ReflectionException
1362
+	 */
1363
+	public function set_is_default($is_default)
1364
+	{
1365
+		$this->set('TKT_is_default', $is_default);
1366
+	}
1367
+
1368
+
1369
+	/**
1370
+	 * Gets order
1371
+	 *
1372
+	 * @return int
1373
+	 * @throws EE_Error
1374
+	 * @throws ReflectionException
1375
+	 */
1376
+	public function order()
1377
+	{
1378
+		return $this->get('TKT_order');
1379
+	}
1380
+
1381
+
1382
+	/**
1383
+	 * Sets order
1384
+	 *
1385
+	 * @param int $order
1386
+	 * @return void
1387
+	 * @throws EE_Error
1388
+	 * @throws ReflectionException
1389
+	 */
1390
+	public function set_order($order)
1391
+	{
1392
+		$this->set('TKT_order', $order);
1393
+	}
1394
+
1395
+
1396
+	/**
1397
+	 * Gets row
1398
+	 *
1399
+	 * @return int
1400
+	 * @throws EE_Error
1401
+	 * @throws ReflectionException
1402
+	 */
1403
+	public function row()
1404
+	{
1405
+		return $this->get('TKT_row');
1406
+	}
1407
+
1408
+
1409
+	/**
1410
+	 * Sets row
1411
+	 *
1412
+	 * @param int $row
1413
+	 * @return void
1414
+	 * @throws EE_Error
1415
+	 * @throws ReflectionException
1416
+	 */
1417
+	public function set_row($row)
1418
+	{
1419
+		$this->set('TKT_row', $row);
1420
+	}
1421
+
1422
+
1423
+	/**
1424
+	 * Gets deleted
1425
+	 *
1426
+	 * @return boolean
1427
+	 * @throws EE_Error
1428
+	 * @throws ReflectionException
1429
+	 */
1430
+	public function deleted()
1431
+	{
1432
+		return $this->get('TKT_deleted');
1433
+	}
1434
+
1435
+
1436
+	/**
1437
+	 * Sets deleted
1438
+	 *
1439
+	 * @param boolean $deleted
1440
+	 * @return void
1441
+	 * @throws EE_Error
1442
+	 * @throws ReflectionException
1443
+	 */
1444
+	public function set_deleted($deleted)
1445
+	{
1446
+		$this->set('TKT_deleted', $deleted);
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * Gets parent
1452
+	 *
1453
+	 * @return int
1454
+	 * @throws EE_Error
1455
+	 * @throws ReflectionException
1456
+	 */
1457
+	public function parent_ID()
1458
+	{
1459
+		return $this->get('TKT_parent');
1460
+	}
1461
+
1462
+
1463
+	/**
1464
+	 * Sets parent
1465
+	 *
1466
+	 * @param int $parent
1467
+	 * @return void
1468
+	 * @throws EE_Error
1469
+	 * @throws ReflectionException
1470
+	 */
1471
+	public function set_parent_ID($parent)
1472
+	{
1473
+		$this->set('TKT_parent', $parent);
1474
+	}
1475
+
1476
+
1477
+	/**
1478
+	 * @return boolean
1479
+	 * @throws EE_Error
1480
+	 * @throws InvalidArgumentException
1481
+	 * @throws InvalidDataTypeException
1482
+	 * @throws InvalidInterfaceException
1483
+	 * @throws ReflectionException
1484
+	 */
1485
+	public function reverse_calculate()
1486
+	{
1487
+		return $this->get('TKT_reverse_calculate');
1488
+	}
1489
+
1490
+
1491
+	/**
1492
+	 * @param boolean $reverse_calculate
1493
+	 * @throws EE_Error
1494
+	 * @throws InvalidArgumentException
1495
+	 * @throws InvalidDataTypeException
1496
+	 * @throws InvalidInterfaceException
1497
+	 * @throws ReflectionException
1498
+	 */
1499
+	public function set_reverse_calculate($reverse_calculate)
1500
+	{
1501
+		$this->set('TKT_reverse_calculate', $reverse_calculate);
1502
+	}
1503
+
1504
+
1505
+	/**
1506
+	 * Gets a string which is handy for showing in gateways etc that describes the ticket.
1507
+	 *
1508
+	 * @return string
1509
+	 * @throws EE_Error
1510
+	 * @throws ReflectionException
1511
+	 */
1512
+	public function name_and_info()
1513
+	{
1514
+		$times = [];
1515
+		foreach ($this->datetimes() as $datetime) {
1516
+			$times[] = $datetime->start_date_and_time();
1517
+		}
1518
+		return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price();
1519
+	}
1520
+
1521
+
1522
+	/**
1523
+	 * Gets name
1524
+	 *
1525
+	 * @return string
1526
+	 * @throws EE_Error
1527
+	 * @throws ReflectionException
1528
+	 */
1529
+	public function name()
1530
+	{
1531
+		return $this->get('TKT_name');
1532
+	}
1533
+
1534
+
1535
+	/**
1536
+	 * Gets price
1537
+	 *
1538
+	 * @return float
1539
+	 * @throws EE_Error
1540
+	 * @throws ReflectionException
1541
+	 */
1542
+	public function price()
1543
+	{
1544
+		return $this->get('TKT_price');
1545
+	}
1546
+
1547
+
1548
+	/**
1549
+	 * Gets all the registrations for this ticket
1550
+	 *
1551
+	 * @param array $query_params @see
1552
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1553
+	 * @return EE_Registration[]|EE_Base_Class[]
1554
+	 * @throws EE_Error
1555
+	 * @throws ReflectionException
1556
+	 */
1557
+	public function registrations($query_params = [])
1558
+	{
1559
+		return $this->get_many_related('Registration', $query_params);
1560
+	}
1561
+
1562
+
1563
+	/**
1564
+	 * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1565
+	 *
1566
+	 * @return int
1567
+	 * @throws EE_Error
1568
+	 * @throws ReflectionException
1569
+	 */
1570
+	public function update_tickets_sold()
1571
+	{
1572
+		$count_regs_for_this_ticket = $this->count_registrations(
1573
+			[
1574
+				[
1575
+					'STS_ID'      => EEM_Registration::status_id_approved,
1576
+					'REG_deleted' => 0,
1577
+				],
1578
+			]
1579
+		);
1580
+		$this->set_sold($count_regs_for_this_ticket);
1581
+		$this->save();
1582
+		return $count_regs_for_this_ticket;
1583
+	}
1584
+
1585
+
1586
+	/**
1587
+	 * Counts the registrations for this ticket
1588
+	 *
1589
+	 * @param array $query_params @see
1590
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1591
+	 * @return int
1592
+	 * @throws EE_Error
1593
+	 * @throws ReflectionException
1594
+	 */
1595
+	public function count_registrations($query_params = [])
1596
+	{
1597
+		return $this->count_related('Registration', $query_params);
1598
+	}
1599
+
1600
+
1601
+	/**
1602
+	 * Implementation for EEI_Has_Icon interface method.
1603
+	 *
1604
+	 * @return string
1605
+	 * @see EEI_Visual_Representation for comments
1606
+	 */
1607
+	public function get_icon()
1608
+	{
1609
+		return '<span class="dashicons dashicons-tickets-alt"/>';
1610
+	}
1611
+
1612
+
1613
+	/**
1614
+	 * Implementation of the EEI_Event_Relation interface method
1615
+	 *
1616
+	 * @return EE_Event
1617
+	 * @throws EE_Error
1618
+	 * @throws UnexpectedEntityException
1619
+	 * @throws ReflectionException
1620
+	 * @see EEI_Event_Relation for comments
1621
+	 */
1622
+	public function get_related_event()
1623
+	{
1624
+		// get one datetime to use for getting the event
1625
+		$datetime = $this->first_datetime();
1626
+		if (! $datetime instanceof EE_Datetime) {
1627
+			throw new UnexpectedEntityException(
1628
+				$datetime,
1629
+				'EE_Datetime',
1630
+				sprintf(
1631
+					__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1632
+					$this->name()
1633
+				)
1634
+			);
1635
+		}
1636
+		$event = $datetime->event();
1637
+		if (! $event instanceof EE_Event) {
1638
+			throw new UnexpectedEntityException(
1639
+				$event,
1640
+				'EE_Event',
1641
+				sprintf(
1642
+					__('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1643
+					$this->name()
1644
+				)
1645
+			);
1646
+		}
1647
+		return $event;
1648
+	}
1649
+
1650
+
1651
+	/**
1652
+	 * Implementation of the EEI_Event_Relation interface method
1653
+	 *
1654
+	 * @return string
1655
+	 * @throws UnexpectedEntityException
1656
+	 * @throws EE_Error
1657
+	 * @throws ReflectionException
1658
+	 * @see EEI_Event_Relation for comments
1659
+	 */
1660
+	public function get_event_name()
1661
+	{
1662
+		$event = $this->get_related_event();
1663
+		return $event instanceof EE_Event ? $event->name() : '';
1664
+	}
1665
+
1666
+
1667
+	/**
1668
+	 * Implementation of the EEI_Event_Relation interface method
1669
+	 *
1670
+	 * @return int
1671
+	 * @throws UnexpectedEntityException
1672
+	 * @throws EE_Error
1673
+	 * @throws ReflectionException
1674
+	 * @see EEI_Event_Relation for comments
1675
+	 */
1676
+	public function get_event_ID()
1677
+	{
1678
+		$event = $this->get_related_event();
1679
+		return $event instanceof EE_Event ? $event->ID() : 0;
1680
+	}
1681
+
1682
+
1683
+	/**
1684
+	 * This simply returns whether a ticket can be permanently deleted or not.
1685
+	 * The criteria for determining this is whether the ticket has any related registrations.
1686
+	 * If there are none then it can be permanently deleted.
1687
+	 *
1688
+	 * @return bool
1689
+	 * @throws EE_Error
1690
+	 * @throws ReflectionException
1691
+	 */
1692
+	public function is_permanently_deleteable()
1693
+	{
1694
+		return $this->count_registrations() === 0;
1695
+	}
1696
+
1697
+
1698
+	/**
1699
+	 * @return int
1700
+	 * @throws EE_Error
1701
+	 * @throws ReflectionException
1702
+	 * @since   $VID:$
1703
+	 */
1704
+	public function visibility(): int
1705
+	{
1706
+		return $this->get('TKT_visibility');
1707
+	}
1708
+
1709
+
1710
+	/**
1711
+	 * @return int
1712
+	 * @throws EE_Error
1713
+	 * @throws ReflectionException
1714
+	 * @since   $VID:$
1715
+	 */
1716
+	public function isHidden(): int
1717
+	{
1718
+		return $this->visibility() === EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE;
1719
+	}
1720
+
1721
+
1722
+	/**
1723
+	 * @return int
1724
+	 * @throws EE_Error
1725
+	 * @throws ReflectionException
1726
+	 * @since   $VID:$
1727
+	 */
1728
+	public function isNotHidden(): int
1729
+	{
1730
+		return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE;
1731
+	}
1732
+
1733
+
1734
+	/**
1735
+	 * @return int
1736
+	 * @throws EE_Error
1737
+	 * @throws ReflectionException
1738
+	 * @since   $VID:$
1739
+	 */
1740
+	public function isPublicOnly(): int
1741
+	{
1742
+		return $this->isNotHidden() && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE;
1743
+	}
1744
+
1745
+
1746
+	/**
1747
+	 * @return int
1748
+	 * @throws EE_Error
1749
+	 * @throws ReflectionException
1750
+	 * @since   $VID:$
1751
+	 */
1752
+	public function isMembersOnly(): int
1753
+	{
1754
+		return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE
1755
+			   && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE;
1756
+	}
1757
+
1758
+
1759
+	/**
1760
+	 * @return int
1761
+	 * @throws EE_Error
1762
+	 * @throws ReflectionException
1763
+	 * @since   $VID:$
1764
+	 */
1765
+	public function isAdminsOnly(): int
1766
+	{
1767
+		return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE
1768
+			   && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE;
1769
+	}
1770
+
1771
+
1772
+	/**
1773
+	 * @return int
1774
+	 * @throws EE_Error
1775
+	 * @throws ReflectionException
1776
+	 * @since   $VID:$
1777
+	 */
1778
+	public function isAdminUiOnly(): int
1779
+	{
1780
+		return $this->visibility() > EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE
1781
+			   && $this->visibility() <= EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE;
1782
+	}
1783
+
1784
+
1785
+	/**
1786
+	 * @param int $visibility
1787
+	 * @throws EE_Error
1788
+	 * @throws ReflectionException
1789
+	 * @since   $VID:$
1790
+	 */
1791
+	public function set_visibility(int $visibility)
1792
+	{
1793
+
1794
+		$ticket_visibility_options = $this->_model->ticketVisibilityOptions();
1795
+		$ticket_visibility         = -1;
1796
+		foreach ($ticket_visibility_options as $ticket_visibility_option) {
1797
+			if ($visibility === $ticket_visibility_option) {
1798
+				$ticket_visibility = $visibility;
1799
+			}
1800
+		}
1801
+		if ($ticket_visibility === -1) {
1802
+			throw new DomainException(
1803
+				sprintf(
1804
+					esc_html__(
1805
+						'The supplied ticket visibility setting of "%1$s" is not valid. It needs to match one of the keys in the following array:%2$s %3$s ',
1806
+						'event_espresso'
1807
+					),
1808
+					$visibility,
1809
+					'<br />',
1810
+					var_export($ticket_visibility_options, true)
1811
+				)
1812
+			);
1813
+		}
1814
+		$this->set('TKT_visibility', $ticket_visibility);
1815
+	}
1816
+
1817
+
1818
+	/**
1819
+	 * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1820
+	 * @param string                   $relationName
1821
+	 * @param array                    $extra_join_model_fields_n_values
1822
+	 * @param string|null              $cache_id
1823
+	 * @return EE_Base_Class
1824
+	 * @throws EE_Error
1825
+	 * @throws ReflectionException
1826
+	 * @since   $VID:$
1827
+	 */
1828
+	public function _add_relation_to(
1829
+		$otherObjectModelObjectOrID,
1830
+		$relationName,
1831
+		$extra_join_model_fields_n_values = [],
1832
+		$cache_id = null
1833
+	) {
1834
+		if ($relationName === 'Datetime' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1835
+			/** @var EE_Datetime $datetime */
1836
+			$datetime = EEM_Datetime::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1837
+			$datetime->increaseSold($this->sold(), false);
1838
+			$datetime->increaseReserved($this->reserved());
1839
+			$datetime->save();
1840
+			$otherObjectModelObjectOrID = $datetime;
1841
+		}
1842
+		return parent::_add_relation_to(
1843
+			$otherObjectModelObjectOrID,
1844
+			$relationName,
1845
+			$extra_join_model_fields_n_values,
1846
+			$cache_id
1847
+		);
1848
+	}
1849
+
1850
+
1851
+	/**
1852
+	 * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1853
+	 * @param string                   $relationName
1854
+	 * @param array                    $where_query
1855
+	 * @return bool|EE_Base_Class|null
1856
+	 * @throws EE_Error
1857
+	 * @throws ReflectionException
1858
+	 * @since   $VID:$
1859
+	 */
1860
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = [])
1861
+	{
1862
+		// if we're adding a new relation to a datetime
1863
+		if ($relationName === 'Datetime' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1864
+			/** @var EE_Datetime $datetime */
1865
+			$datetime = EEM_Datetime::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1866
+			$datetime->decreaseSold($this->sold());
1867
+			$datetime->decreaseReserved($this->reserved());
1868
+			$datetime->save();
1869
+			$otherObjectModelObjectOrID = $datetime;
1870
+		}
1871
+		return parent::_remove_relation_to(
1872
+			$otherObjectModelObjectOrID,
1873
+			$relationName,
1874
+			$where_query
1875
+		);
1876
+	}
1877
+
1878
+
1879
+	/**
1880
+	 * Removes ALL the related things for the $relationName.
1881
+	 *
1882
+	 * @param string $relationName
1883
+	 * @param array  $where_query_params
1884
+	 * @return EE_Base_Class
1885
+	 * @throws ReflectionException
1886
+	 * @throws InvalidArgumentException
1887
+	 * @throws InvalidInterfaceException
1888
+	 * @throws InvalidDataTypeException
1889
+	 * @throws EE_Error
1890
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
1891
+	 */
1892
+	public function _remove_relations($relationName, $where_query_params = [])
1893
+	{
1894
+		if ($relationName === 'Datetime') {
1895
+			$datetimes = $this->datetimes();
1896
+			foreach ($datetimes as $datetime) {
1897
+				$datetime->decreaseSold($this->sold());
1898
+				$datetime->decreaseReserved($this->reserved());
1899
+				$datetime->save();
1900
+			}
1901
+		}
1902
+		return parent::_remove_relations($relationName, $where_query_params);
1903
+	}
1904
+
1905
+
1906
+	/*******************************************************************
1907 1907
      ***********************  DEPRECATED METHODS  **********************
1908 1908
      *******************************************************************/
1909 1909
 
1910 1910
 
1911
-    /**
1912
-     * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
1913
-     * associated datetimes.
1914
-     *
1915
-     * @param int $qty
1916
-     * @return void
1917
-     * @throws EE_Error
1918
-     * @throws InvalidArgumentException
1919
-     * @throws InvalidDataTypeException
1920
-     * @throws InvalidInterfaceException
1921
-     * @throws ReflectionException
1922
-     * @deprecated 4.9.80.p
1923
-     */
1924
-    public function increase_sold($qty = 1)
1925
-    {
1926
-        EE_Error::doing_it_wrong(
1927
-            __FUNCTION__,
1928
-            esc_html__('Please use EE_Ticket::increaseSold() instead', 'event_espresso'),
1929
-            '4.9.80.p',
1930
-            '5.0.0.p'
1931
-        );
1932
-        $this->increaseSold($qty);
1933
-    }
1934
-
1935
-
1936
-    /**
1937
-     * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
1938
-     *
1939
-     * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts),
1940
-     *                 Negative means to decreases old counts (and increase reserved counts).
1941
-     * @throws EE_Error
1942
-     * @throws InvalidArgumentException
1943
-     * @throws InvalidDataTypeException
1944
-     * @throws InvalidInterfaceException
1945
-     * @throws ReflectionException
1946
-     * @deprecated 4.9.80.p
1947
-     */
1948
-    protected function _increase_sold_for_datetimes($qty)
1949
-    {
1950
-        EE_Error::doing_it_wrong(
1951
-            __FUNCTION__,
1952
-            esc_html__('Please use EE_Ticket::increaseSoldForDatetimes() instead', 'event_espresso'),
1953
-            '4.9.80.p',
1954
-            '5.0.0.p'
1955
-        );
1956
-        $this->increaseSoldForDatetimes($qty);
1957
-    }
1958
-
1959
-
1960
-    /**
1961
-     * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
1962
-     * DB and then updates the model objects.
1963
-     * Does not affect the reserved counts.
1964
-     *
1965
-     * @param int $qty
1966
-     * @return void
1967
-     * @throws EE_Error
1968
-     * @throws InvalidArgumentException
1969
-     * @throws InvalidDataTypeException
1970
-     * @throws InvalidInterfaceException
1971
-     * @throws ReflectionException
1972
-     * @deprecated 4.9.80.p
1973
-     */
1974
-    public function decrease_sold($qty = 1)
1975
-    {
1976
-        EE_Error::doing_it_wrong(
1977
-            __FUNCTION__,
1978
-            esc_html__('Please use EE_Ticket::decreaseSold() instead', 'event_espresso'),
1979
-            '4.9.80.p',
1980
-            '5.0.0.p'
1981
-        );
1982
-        $this->decreaseSold($qty);
1983
-    }
1984
-
1985
-
1986
-    /**
1987
-     * Decreases sold on related datetimes
1988
-     *
1989
-     * @param int $qty
1990
-     * @return void
1991
-     * @throws EE_Error
1992
-     * @throws InvalidArgumentException
1993
-     * @throws InvalidDataTypeException
1994
-     * @throws InvalidInterfaceException
1995
-     * @throws ReflectionException
1996
-     * @deprecated 4.9.80.p
1997
-     */
1998
-    protected function _decrease_sold_for_datetimes($qty = 1)
1999
-    {
2000
-        EE_Error::doing_it_wrong(
2001
-            __FUNCTION__,
2002
-            esc_html__('Please use EE_Ticket::decreaseSoldForDatetimes() instead', 'event_espresso'),
2003
-            '4.9.80.p',
2004
-            '5.0.0.p'
2005
-        );
2006
-        $this->decreaseSoldForDatetimes($qty);
2007
-    }
2008
-
2009
-
2010
-    /**
2011
-     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
2012
-     *
2013
-     * @param int    $qty
2014
-     * @param string $source
2015
-     * @return bool whether we successfully reserved the ticket or not.
2016
-     * @throws EE_Error
2017
-     * @throws InvalidArgumentException
2018
-     * @throws ReflectionException
2019
-     * @throws InvalidDataTypeException
2020
-     * @throws InvalidInterfaceException
2021
-     * @deprecated 4.9.80.p
2022
-     */
2023
-    public function increase_reserved($qty = 1, $source = 'unknown')
2024
-    {
2025
-        EE_Error::doing_it_wrong(
2026
-            __FUNCTION__,
2027
-            esc_html__('Please use EE_Ticket::increaseReserved() instead', 'event_espresso'),
2028
-            '4.9.80.p',
2029
-            '5.0.0.p'
2030
-        );
2031
-        return $this->increaseReserved($qty);
2032
-    }
2033
-
2034
-
2035
-    /**
2036
-     * Increases sold on related datetimes
2037
-     *
2038
-     * @param int $qty
2039
-     * @return boolean indicating success
2040
-     * @throws EE_Error
2041
-     * @throws InvalidArgumentException
2042
-     * @throws InvalidDataTypeException
2043
-     * @throws InvalidInterfaceException
2044
-     * @throws ReflectionException
2045
-     * @deprecated 4.9.80.p
2046
-     */
2047
-    protected function _increase_reserved_for_datetimes($qty = 1)
2048
-    {
2049
-        EE_Error::doing_it_wrong(
2050
-            __FUNCTION__,
2051
-            esc_html__('Please use EE_Ticket::increaseReservedForDatetimes() instead', 'event_espresso'),
2052
-            '4.9.80.p',
2053
-            '5.0.0.p'
2054
-        );
2055
-        return $this->increaseReservedForDatetimes($qty);
2056
-    }
2057
-
2058
-
2059
-    /**
2060
-     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
2061
-     *
2062
-     * @param int    $qty
2063
-     * @param bool   $adjust_datetimes
2064
-     * @param string $source
2065
-     * @return void
2066
-     * @throws EE_Error
2067
-     * @throws InvalidArgumentException
2068
-     * @throws ReflectionException
2069
-     * @throws InvalidDataTypeException
2070
-     * @throws InvalidInterfaceException
2071
-     * @deprecated 4.9.80.p
2072
-     */
2073
-    public function decrease_reserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
2074
-    {
2075
-        EE_Error::doing_it_wrong(
2076
-            __FUNCTION__,
2077
-            esc_html__('Please use EE_Ticket::decreaseReserved() instead', 'event_espresso'),
2078
-            '4.9.80.p',
2079
-            '5.0.0.p'
2080
-        );
2081
-        $this->decreaseReserved($qty);
2082
-    }
2083
-
2084
-
2085
-    /**
2086
-     * Decreases reserved on related datetimes
2087
-     *
2088
-     * @param int $qty
2089
-     * @return void
2090
-     * @throws EE_Error
2091
-     * @throws InvalidArgumentException
2092
-     * @throws ReflectionException
2093
-     * @throws InvalidDataTypeException
2094
-     * @throws InvalidInterfaceException
2095
-     * @deprecated 4.9.80.p
2096
-     */
2097
-    protected function _decrease_reserved_for_datetimes($qty = 1)
2098
-    {
2099
-        EE_Error::doing_it_wrong(
2100
-            __FUNCTION__,
2101
-            esc_html__('Please use EE_Ticket::decreaseReservedForDatetimes() instead', 'event_espresso'),
2102
-            '4.9.80.p',
2103
-            '5.0.0.p'
2104
-        );
2105
-        $this->decreaseReservedForDatetimes($qty);
2106
-    }
1911
+	/**
1912
+	 * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
1913
+	 * associated datetimes.
1914
+	 *
1915
+	 * @param int $qty
1916
+	 * @return void
1917
+	 * @throws EE_Error
1918
+	 * @throws InvalidArgumentException
1919
+	 * @throws InvalidDataTypeException
1920
+	 * @throws InvalidInterfaceException
1921
+	 * @throws ReflectionException
1922
+	 * @deprecated 4.9.80.p
1923
+	 */
1924
+	public function increase_sold($qty = 1)
1925
+	{
1926
+		EE_Error::doing_it_wrong(
1927
+			__FUNCTION__,
1928
+			esc_html__('Please use EE_Ticket::increaseSold() instead', 'event_espresso'),
1929
+			'4.9.80.p',
1930
+			'5.0.0.p'
1931
+		);
1932
+		$this->increaseSold($qty);
1933
+	}
1934
+
1935
+
1936
+	/**
1937
+	 * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
1938
+	 *
1939
+	 * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts),
1940
+	 *                 Negative means to decreases old counts (and increase reserved counts).
1941
+	 * @throws EE_Error
1942
+	 * @throws InvalidArgumentException
1943
+	 * @throws InvalidDataTypeException
1944
+	 * @throws InvalidInterfaceException
1945
+	 * @throws ReflectionException
1946
+	 * @deprecated 4.9.80.p
1947
+	 */
1948
+	protected function _increase_sold_for_datetimes($qty)
1949
+	{
1950
+		EE_Error::doing_it_wrong(
1951
+			__FUNCTION__,
1952
+			esc_html__('Please use EE_Ticket::increaseSoldForDatetimes() instead', 'event_espresso'),
1953
+			'4.9.80.p',
1954
+			'5.0.0.p'
1955
+		);
1956
+		$this->increaseSoldForDatetimes($qty);
1957
+	}
1958
+
1959
+
1960
+	/**
1961
+	 * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
1962
+	 * DB and then updates the model objects.
1963
+	 * Does not affect the reserved counts.
1964
+	 *
1965
+	 * @param int $qty
1966
+	 * @return void
1967
+	 * @throws EE_Error
1968
+	 * @throws InvalidArgumentException
1969
+	 * @throws InvalidDataTypeException
1970
+	 * @throws InvalidInterfaceException
1971
+	 * @throws ReflectionException
1972
+	 * @deprecated 4.9.80.p
1973
+	 */
1974
+	public function decrease_sold($qty = 1)
1975
+	{
1976
+		EE_Error::doing_it_wrong(
1977
+			__FUNCTION__,
1978
+			esc_html__('Please use EE_Ticket::decreaseSold() instead', 'event_espresso'),
1979
+			'4.9.80.p',
1980
+			'5.0.0.p'
1981
+		);
1982
+		$this->decreaseSold($qty);
1983
+	}
1984
+
1985
+
1986
+	/**
1987
+	 * Decreases sold on related datetimes
1988
+	 *
1989
+	 * @param int $qty
1990
+	 * @return void
1991
+	 * @throws EE_Error
1992
+	 * @throws InvalidArgumentException
1993
+	 * @throws InvalidDataTypeException
1994
+	 * @throws InvalidInterfaceException
1995
+	 * @throws ReflectionException
1996
+	 * @deprecated 4.9.80.p
1997
+	 */
1998
+	protected function _decrease_sold_for_datetimes($qty = 1)
1999
+	{
2000
+		EE_Error::doing_it_wrong(
2001
+			__FUNCTION__,
2002
+			esc_html__('Please use EE_Ticket::decreaseSoldForDatetimes() instead', 'event_espresso'),
2003
+			'4.9.80.p',
2004
+			'5.0.0.p'
2005
+		);
2006
+		$this->decreaseSoldForDatetimes($qty);
2007
+	}
2008
+
2009
+
2010
+	/**
2011
+	 * Increments reserved by amount passed by $qty, and persists it immediately to the database.
2012
+	 *
2013
+	 * @param int    $qty
2014
+	 * @param string $source
2015
+	 * @return bool whether we successfully reserved the ticket or not.
2016
+	 * @throws EE_Error
2017
+	 * @throws InvalidArgumentException
2018
+	 * @throws ReflectionException
2019
+	 * @throws InvalidDataTypeException
2020
+	 * @throws InvalidInterfaceException
2021
+	 * @deprecated 4.9.80.p
2022
+	 */
2023
+	public function increase_reserved($qty = 1, $source = 'unknown')
2024
+	{
2025
+		EE_Error::doing_it_wrong(
2026
+			__FUNCTION__,
2027
+			esc_html__('Please use EE_Ticket::increaseReserved() instead', 'event_espresso'),
2028
+			'4.9.80.p',
2029
+			'5.0.0.p'
2030
+		);
2031
+		return $this->increaseReserved($qty);
2032
+	}
2033
+
2034
+
2035
+	/**
2036
+	 * Increases sold on related datetimes
2037
+	 *
2038
+	 * @param int $qty
2039
+	 * @return boolean indicating success
2040
+	 * @throws EE_Error
2041
+	 * @throws InvalidArgumentException
2042
+	 * @throws InvalidDataTypeException
2043
+	 * @throws InvalidInterfaceException
2044
+	 * @throws ReflectionException
2045
+	 * @deprecated 4.9.80.p
2046
+	 */
2047
+	protected function _increase_reserved_for_datetimes($qty = 1)
2048
+	{
2049
+		EE_Error::doing_it_wrong(
2050
+			__FUNCTION__,
2051
+			esc_html__('Please use EE_Ticket::increaseReservedForDatetimes() instead', 'event_espresso'),
2052
+			'4.9.80.p',
2053
+			'5.0.0.p'
2054
+		);
2055
+		return $this->increaseReservedForDatetimes($qty);
2056
+	}
2057
+
2058
+
2059
+	/**
2060
+	 * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
2061
+	 *
2062
+	 * @param int    $qty
2063
+	 * @param bool   $adjust_datetimes
2064
+	 * @param string $source
2065
+	 * @return void
2066
+	 * @throws EE_Error
2067
+	 * @throws InvalidArgumentException
2068
+	 * @throws ReflectionException
2069
+	 * @throws InvalidDataTypeException
2070
+	 * @throws InvalidInterfaceException
2071
+	 * @deprecated 4.9.80.p
2072
+	 */
2073
+	public function decrease_reserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
2074
+	{
2075
+		EE_Error::doing_it_wrong(
2076
+			__FUNCTION__,
2077
+			esc_html__('Please use EE_Ticket::decreaseReserved() instead', 'event_espresso'),
2078
+			'4.9.80.p',
2079
+			'5.0.0.p'
2080
+		);
2081
+		$this->decreaseReserved($qty);
2082
+	}
2083
+
2084
+
2085
+	/**
2086
+	 * Decreases reserved on related datetimes
2087
+	 *
2088
+	 * @param int $qty
2089
+	 * @return void
2090
+	 * @throws EE_Error
2091
+	 * @throws InvalidArgumentException
2092
+	 * @throws ReflectionException
2093
+	 * @throws InvalidDataTypeException
2094
+	 * @throws InvalidInterfaceException
2095
+	 * @deprecated 4.9.80.p
2096
+	 */
2097
+	protected function _decrease_reserved_for_datetimes($qty = 1)
2098
+	{
2099
+		EE_Error::doing_it_wrong(
2100
+			__FUNCTION__,
2101
+			esc_html__('Please use EE_Ticket::decreaseReservedForDatetimes() instead', 'event_espresso'),
2102
+			'4.9.80.p',
2103
+			'5.0.0.p'
2104
+		);
2105
+		$this->decreaseReservedForDatetimes($qty);
2106
+	}
2107 2107
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Datetime.class.php 1 patch
Indentation   +1552 added lines, -1552 removed lines patch added patch discarded remove patch
@@ -13,1560 +13,1560 @@
 block discarded – undo
13 13
 class EE_Datetime extends EE_Soft_Delete_Base_Class
14 14
 {
15 15
 
16
-    /**
17
-     * constant used by get_active_status, indicates datetime has no more available spaces
18
-     */
19
-    const sold_out = 'DTS';
20
-
21
-    /**
22
-     * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for)
23
-     */
24
-    const active = 'DTA';
25
-
26
-    /**
27
-     * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not
28
-     * expired
29
-     */
30
-    const upcoming = 'DTU';
31
-
32
-    /**
33
-     * Datetime is postponed
34
-     */
35
-    const postponed = 'DTP';
36
-
37
-    /**
38
-     * Datetime is cancelled
39
-     */
40
-    const cancelled = 'DTC';
41
-
42
-    /**
43
-     * constant used by get_active_status, indicates datetime has expired (event is over)
44
-     */
45
-    const expired = 'DTE';
46
-
47
-    /**
48
-     * constant used in various places indicating that an event is INACTIVE (not yet ready to be published)
49
-     */
50
-    const inactive = 'DTI';
51
-
52
-
53
-    /**
54
-     * @param array  $props_n_values    incoming values
55
-     * @param string $timezone          incoming timezone (if not set the timezone set for the website will be used.)
56
-     * @param array  $date_formats      incoming date_formats in an array where the first value is the date_format
57
-     *                                  and the second value is the time format
58
-     * @return EE_Datetime
59
-     * @throws ReflectionException
60
-     * @throws InvalidArgumentException
61
-     * @throws InvalidInterfaceException
62
-     * @throws InvalidDataTypeException
63
-     * @throws EE_Error
64
-     */
65
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
66
-    {
67
-        $has_object = parent::_check_for_object(
68
-            $props_n_values,
69
-            __CLASS__,
70
-            $timezone,
71
-            $date_formats
72
-        );
73
-        return $has_object
74
-            ? $has_object
75
-            : new self($props_n_values, false, $timezone, $date_formats);
76
-    }
77
-
78
-
79
-    /**
80
-     * @param array  $props_n_values  incoming values from the database
81
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
-     *                                the website will be used.
83
-     * @return EE_Datetime
84
-     * @throws ReflectionException
85
-     * @throws InvalidArgumentException
86
-     * @throws InvalidInterfaceException
87
-     * @throws InvalidDataTypeException
88
-     * @throws EE_Error
89
-     */
90
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
91
-    {
92
-        return new self($props_n_values, true, $timezone);
93
-    }
94
-
95
-
96
-    /**
97
-     * @param $name
98
-     * @throws ReflectionException
99
-     * @throws InvalidArgumentException
100
-     * @throws InvalidInterfaceException
101
-     * @throws InvalidDataTypeException
102
-     * @throws EE_Error
103
-     */
104
-    public function set_name($name)
105
-    {
106
-        $this->set('DTT_name', $name);
107
-    }
108
-
109
-
110
-    /**
111
-     * @param $description
112
-     * @throws ReflectionException
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidInterfaceException
115
-     * @throws InvalidDataTypeException
116
-     * @throws EE_Error
117
-     */
118
-    public function set_description($description)
119
-    {
120
-        $this->set('DTT_description', $description);
121
-    }
122
-
123
-
124
-    /**
125
-     * Set event start date
126
-     * set the start date for an event
127
-     *
128
-     * @param string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
129
-     * @throws ReflectionException
130
-     * @throws InvalidArgumentException
131
-     * @throws InvalidInterfaceException
132
-     * @throws InvalidDataTypeException
133
-     * @throws EE_Error
134
-     */
135
-    public function set_start_date($date)
136
-    {
137
-        $this->_set_date_for($date, 'DTT_EVT_start');
138
-    }
139
-
140
-
141
-    /**
142
-     * Set event start time
143
-     * set the start time for an event
144
-     *
145
-     * @param string $time a string representation of the event time ex:  9am  or  7:30 PM
146
-     * @throws ReflectionException
147
-     * @throws InvalidArgumentException
148
-     * @throws InvalidInterfaceException
149
-     * @throws InvalidDataTypeException
150
-     * @throws EE_Error
151
-     */
152
-    public function set_start_time($time)
153
-    {
154
-        $this->_set_time_for($time, 'DTT_EVT_start');
155
-    }
156
-
157
-
158
-    /**
159
-     * Set event end date
160
-     * set the end date for an event
161
-     *
162
-     * @param string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
163
-     * @throws ReflectionException
164
-     * @throws InvalidArgumentException
165
-     * @throws InvalidInterfaceException
166
-     * @throws InvalidDataTypeException
167
-     * @throws EE_Error
168
-     */
169
-    public function set_end_date($date)
170
-    {
171
-        $this->_set_date_for($date, 'DTT_EVT_end');
172
-    }
173
-
174
-
175
-    /**
176
-     * Set event end time
177
-     * set the end time for an event
178
-     *
179
-     * @param string $time a string representation of the event time ex:  9am  or  7:30 PM
180
-     * @throws ReflectionException
181
-     * @throws InvalidArgumentException
182
-     * @throws InvalidInterfaceException
183
-     * @throws InvalidDataTypeException
184
-     * @throws EE_Error
185
-     */
186
-    public function set_end_time($time)
187
-    {
188
-        $this->_set_time_for($time, 'DTT_EVT_end');
189
-    }
190
-
191
-
192
-    /**
193
-     * Set registration limit
194
-     * set the maximum number of attendees that can be registered for this datetime slot
195
-     *
196
-     * @param int $reg_limit
197
-     * @throws ReflectionException
198
-     * @throws InvalidArgumentException
199
-     * @throws InvalidInterfaceException
200
-     * @throws InvalidDataTypeException
201
-     * @throws EE_Error
202
-     */
203
-    public function set_reg_limit($reg_limit)
204
-    {
205
-        $this->set('DTT_reg_limit', $reg_limit);
206
-    }
207
-
208
-
209
-    /**
210
-     * get the number of tickets sold for this datetime slot
211
-     *
212
-     * @return mixed int on success, FALSE on fail
213
-     * @throws ReflectionException
214
-     * @throws InvalidArgumentException
215
-     * @throws InvalidInterfaceException
216
-     * @throws InvalidDataTypeException
217
-     * @throws EE_Error
218
-     */
219
-    public function sold()
220
-    {
221
-        return $this->get_raw('DTT_sold');
222
-    }
223
-
224
-
225
-    /**
226
-     * @param int $sold
227
-     * @throws ReflectionException
228
-     * @throws InvalidArgumentException
229
-     * @throws InvalidInterfaceException
230
-     * @throws InvalidDataTypeException
231
-     * @throws EE_Error
232
-     */
233
-    public function set_sold($sold)
234
-    {
235
-        // sold can not go below zero
236
-        $sold = max(0, $sold);
237
-        $this->set('DTT_sold', $sold);
238
-    }
239
-
240
-
241
-    /**
242
-     * Increments sold by amount passed by $qty, and persists it immediately to the database.
243
-     * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false.
244
-     *
245
-     * @param int $qty
246
-     * @param boolean $also_decrease_reserved
247
-     * @return boolean indicating success
248
-     * @throws ReflectionException
249
-     * @throws InvalidArgumentException
250
-     * @throws InvalidInterfaceException
251
-     * @throws InvalidDataTypeException
252
-     * @throws EE_Error
253
-     */
254
-    public function increaseSold($qty = 1, $also_decrease_reserved = true)
255
-    {
256
-        $qty = absint($qty);
257
-        if ($also_decrease_reserved) {
258
-            $success = $this->adjustNumericFieldsInDb(
259
-                [
260
-                    'DTT_reserved' => $qty * -1,
261
-                    'DTT_sold' => $qty
262
-                ]
263
-            );
264
-        } else {
265
-            $success = $this->adjustNumericFieldsInDb(
266
-                [
267
-                    'DTT_sold' => $qty
268
-                ]
269
-            );
270
-        }
271
-
272
-        do_action(
273
-            'AHEE__EE_Datetime__increase_sold',
274
-            $this,
275
-            $qty,
276
-            $this->sold(),
277
-            $success
278
-        );
279
-        return $success;
280
-    }
281
-
282
-
283
-    /**
284
-     * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need
285
-     * to save afterwards.)
286
-     *
287
-     * @param int $qty
288
-     * @return boolean indicating success
289
-     * @throws ReflectionException
290
-     * @throws InvalidArgumentException
291
-     * @throws InvalidInterfaceException
292
-     * @throws InvalidDataTypeException
293
-     * @throws EE_Error
294
-     */
295
-    public function decreaseSold($qty = 1)
296
-    {
297
-        $qty = absint($qty);
298
-        $success = $this->adjustNumericFieldsInDb(
299
-            [
300
-                'DTT_sold' => $qty * -1
301
-            ]
302
-        );
303
-        do_action(
304
-            'AHEE__EE_Datetime__decrease_sold',
305
-            $this,
306
-            $qty,
307
-            $this->sold(),
308
-            $success
309
-        );
310
-        return $success;
311
-    }
312
-
313
-
314
-    /**
315
-     * Gets qty of reserved tickets for this datetime
316
-     *
317
-     * @return int
318
-     * @throws ReflectionException
319
-     * @throws InvalidArgumentException
320
-     * @throws InvalidInterfaceException
321
-     * @throws InvalidDataTypeException
322
-     * @throws EE_Error
323
-     */
324
-    public function reserved()
325
-    {
326
-        return $this->get_raw('DTT_reserved');
327
-    }
328
-
329
-
330
-    /**
331
-     * Sets qty of reserved tickets for this datetime
332
-     *
333
-     * @param int $reserved
334
-     * @throws ReflectionException
335
-     * @throws InvalidArgumentException
336
-     * @throws InvalidInterfaceException
337
-     * @throws InvalidDataTypeException
338
-     * @throws EE_Error
339
-     */
340
-    public function set_reserved($reserved)
341
-    {
342
-        // reserved can not go below zero
343
-        $reserved = max(0, (int) $reserved);
344
-        $this->set('DTT_reserved', $reserved);
345
-    }
346
-
347
-
348
-    /**
349
-     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
350
-     *
351
-     * @param int $qty
352
-     * @return boolean indicating success
353
-     * @throws ReflectionException
354
-     * @throws InvalidArgumentException
355
-     * @throws InvalidInterfaceException
356
-     * @throws InvalidDataTypeException
357
-     * @throws EE_Error
358
-     */
359
-    public function increaseReserved($qty = 1)
360
-    {
361
-        $qty = absint($qty);
362
-        $success = $this->incrementFieldConditionallyInDb(
363
-            'DTT_reserved',
364
-            'DTT_sold',
365
-            'DTT_reg_limit',
366
-            $qty
367
-        );
368
-        do_action(
369
-            'AHEE__EE_Datetime__increase_reserved',
370
-            $this,
371
-            $qty,
372
-            $this->reserved(),
373
-            $success
374
-        );
375
-        return $success;
376
-    }
377
-
378
-
379
-    /**
380
-     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
381
-     *
382
-     * @param int $qty
383
-     * @return boolean indicating success
384
-     * @throws ReflectionException
385
-     * @throws InvalidArgumentException
386
-     * @throws InvalidInterfaceException
387
-     * @throws InvalidDataTypeException
388
-     * @throws EE_Error
389
-     */
390
-    public function decreaseReserved($qty = 1)
391
-    {
392
-        $qty = absint($qty);
393
-        $success = $this->adjustNumericFieldsInDb(
394
-            [
395
-                'DTT_reserved' => $qty * -1
396
-            ]
397
-        );
398
-        do_action(
399
-            'AHEE__EE_Datetime__decrease_reserved',
400
-            $this,
401
-            $qty,
402
-            $this->reserved(),
403
-            $success
404
-        );
405
-        return $success;
406
-    }
407
-
408
-
409
-    /**
410
-     * total sold and reserved tickets
411
-     *
412
-     * @return int
413
-     * @throws ReflectionException
414
-     * @throws InvalidArgumentException
415
-     * @throws InvalidInterfaceException
416
-     * @throws InvalidDataTypeException
417
-     * @throws EE_Error
418
-     */
419
-    public function sold_and_reserved()
420
-    {
421
-        return $this->sold() + $this->reserved();
422
-    }
423
-
424
-
425
-    /**
426
-     * returns the datetime name
427
-     *
428
-     * @return string
429
-     * @throws ReflectionException
430
-     * @throws InvalidArgumentException
431
-     * @throws InvalidInterfaceException
432
-     * @throws InvalidDataTypeException
433
-     * @throws EE_Error
434
-     */
435
-    public function name()
436
-    {
437
-        return $this->get('DTT_name');
438
-    }
439
-
440
-
441
-    /**
442
-     * returns the datetime description
443
-     *
444
-     * @return string
445
-     * @throws ReflectionException
446
-     * @throws InvalidArgumentException
447
-     * @throws InvalidInterfaceException
448
-     * @throws InvalidDataTypeException
449
-     * @throws EE_Error
450
-     */
451
-    public function description()
452
-    {
453
-        return $this->get('DTT_description');
454
-    }
455
-
456
-
457
-    /**
458
-     * This helper simply returns whether the event_datetime for the current datetime is a primary datetime
459
-     *
460
-     * @return boolean  TRUE if is primary, FALSE if not.
461
-     * @throws ReflectionException
462
-     * @throws InvalidArgumentException
463
-     * @throws InvalidInterfaceException
464
-     * @throws InvalidDataTypeException
465
-     * @throws EE_Error
466
-     */
467
-    public function is_primary()
468
-    {
469
-        return $this->get('DTT_is_primary');
470
-    }
471
-
472
-
473
-    /**
474
-     * This helper simply returns the order for the datetime
475
-     *
476
-     * @return int  The order of the datetime for this event.
477
-     * @throws ReflectionException
478
-     * @throws InvalidArgumentException
479
-     * @throws InvalidInterfaceException
480
-     * @throws InvalidDataTypeException
481
-     * @throws EE_Error
482
-     */
483
-    public function order()
484
-    {
485
-        return $this->get('DTT_order');
486
-    }
487
-
488
-
489
-    /**
490
-     * This helper simply returns the parent id for the datetime
491
-     *
492
-     * @return int
493
-     * @throws ReflectionException
494
-     * @throws InvalidArgumentException
495
-     * @throws InvalidInterfaceException
496
-     * @throws InvalidDataTypeException
497
-     * @throws EE_Error
498
-     */
499
-    public function parent()
500
-    {
501
-        return $this->get('DTT_parent');
502
-    }
503
-
504
-
505
-    /**
506
-     * show date and/or time
507
-     *
508
-     * @param string $date_or_time    whether to display a date or time or both
509
-     * @param string $start_or_end    whether to display start or end datetimes
510
-     * @param string $dt_frmt
511
-     * @param string $tm_frmt
512
-     * @param bool   $echo            whether we echo or return (note echoing uses "pretty" formats,
513
-     *                                otherwise we use the standard formats)
514
-     * @return string|bool  string on success, FALSE on fail
515
-     * @throws ReflectionException
516
-     * @throws InvalidArgumentException
517
-     * @throws InvalidInterfaceException
518
-     * @throws InvalidDataTypeException
519
-     * @throws EE_Error
520
-     */
521
-    private function _show_datetime(
522
-        $date_or_time = null,
523
-        $start_or_end = 'start',
524
-        $dt_frmt = '',
525
-        $tm_frmt = '',
526
-        $echo = false
527
-    ) {
528
-        $field_name = "DTT_EVT_{$start_or_end}";
529
-        $dtt = $this->_get_datetime(
530
-            $field_name,
531
-            $dt_frmt,
532
-            $tm_frmt,
533
-            $date_or_time,
534
-            $echo
535
-        );
536
-        if (! $echo) {
537
-            return $dtt;
538
-        }
539
-        return '';
540
-    }
541
-
542
-
543
-    /**
544
-     * get event start date.  Provide either the date format, or NULL to re-use the
545
-     * last-used format, or '' to use the default date format
546
-     *
547
-     * @param string $dt_frmt string representation of date format defaults to 'F j, Y'
548
-     * @return mixed            string on success, FALSE on fail
549
-     * @throws ReflectionException
550
-     * @throws InvalidArgumentException
551
-     * @throws InvalidInterfaceException
552
-     * @throws InvalidDataTypeException
553
-     * @throws EE_Error
554
-     */
555
-    public function start_date($dt_frmt = '')
556
-    {
557
-        return $this->_show_datetime('D', 'start', $dt_frmt);
558
-    }
559
-
560
-
561
-    /**
562
-     * Echoes start_date()
563
-     *
564
-     * @param string $dt_frmt
565
-     * @throws ReflectionException
566
-     * @throws InvalidArgumentException
567
-     * @throws InvalidInterfaceException
568
-     * @throws InvalidDataTypeException
569
-     * @throws EE_Error
570
-     */
571
-    public function e_start_date($dt_frmt = '')
572
-    {
573
-        $this->_show_datetime('D', 'start', $dt_frmt, null, true);
574
-    }
575
-
576
-
577
-    /**
578
-     * get end date. Provide either the date format, or NULL to re-use the
579
-     * last-used format, or '' to use the default date format
580
-     *
581
-     * @param string $dt_frmt string representation of date format defaults to 'F j, Y'
582
-     * @return mixed            string on success, FALSE on fail
583
-     * @throws ReflectionException
584
-     * @throws InvalidArgumentException
585
-     * @throws InvalidInterfaceException
586
-     * @throws InvalidDataTypeException
587
-     * @throws EE_Error
588
-     */
589
-    public function end_date($dt_frmt = '')
590
-    {
591
-        return $this->_show_datetime('D', 'end', $dt_frmt);
592
-    }
593
-
594
-
595
-    /**
596
-     * Echoes the end date. See end_date()
597
-     *
598
-     * @param string $dt_frmt
599
-     * @throws ReflectionException
600
-     * @throws InvalidArgumentException
601
-     * @throws InvalidInterfaceException
602
-     * @throws InvalidDataTypeException
603
-     * @throws EE_Error
604
-     */
605
-    public function e_end_date($dt_frmt = '')
606
-    {
607
-        $this->_show_datetime('D', 'end', $dt_frmt, null, true);
608
-    }
609
-
610
-
611
-    /**
612
-     * get date_range - meaning the start AND end date
613
-     *
614
-     * @access public
615
-     * @param string $dt_frmt     string representation of date format defaults to WP settings
616
-     * @param string $conjunction conjunction junction what's your function ?
617
-     *                            this string joins the start date with the end date ie: Jan 01 "to" Dec 31
618
-     * @return mixed              string on success, FALSE on fail
619
-     * @throws ReflectionException
620
-     * @throws InvalidArgumentException
621
-     * @throws InvalidInterfaceException
622
-     * @throws InvalidDataTypeException
623
-     * @throws EE_Error
624
-     */
625
-    public function date_range($dt_frmt = '', $conjunction = ' - ')
626
-    {
627
-        $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt;
628
-        $start = str_replace(
629
-            ' ',
630
-            '&nbsp;',
631
-            $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt)
632
-        );
633
-        $end = str_replace(
634
-            ' ',
635
-            '&nbsp;',
636
-            $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt)
637
-        );
638
-        return $start !== $end ? $start . $conjunction . $end : $start;
639
-    }
640
-
641
-
642
-    /**
643
-     * @param string $dt_frmt
644
-     * @param string $conjunction
645
-     * @throws ReflectionException
646
-     * @throws InvalidArgumentException
647
-     * @throws InvalidInterfaceException
648
-     * @throws InvalidDataTypeException
649
-     * @throws EE_Error
650
-     */
651
-    public function e_date_range($dt_frmt = '', $conjunction = ' - ')
652
-    {
653
-        echo $this->date_range($dt_frmt, $conjunction);
654
-    }
655
-
656
-
657
-    /**
658
-     * get start time
659
-     *
660
-     * @param string $tm_format - string representation of time format defaults to 'g:i a'
661
-     * @return mixed        string on success, FALSE on fail
662
-     * @throws ReflectionException
663
-     * @throws InvalidArgumentException
664
-     * @throws InvalidInterfaceException
665
-     * @throws InvalidDataTypeException
666
-     * @throws EE_Error
667
-     */
668
-    public function start_time($tm_format = '')
669
-    {
670
-        return $this->_show_datetime('T', 'start', null, $tm_format);
671
-    }
672
-
673
-
674
-    /**
675
-     * @param string $tm_format
676
-     * @throws ReflectionException
677
-     * @throws InvalidArgumentException
678
-     * @throws InvalidInterfaceException
679
-     * @throws InvalidDataTypeException
680
-     * @throws EE_Error
681
-     */
682
-    public function e_start_time($tm_format = '')
683
-    {
684
-        $this->_show_datetime('T', 'start', null, $tm_format, true);
685
-    }
686
-
687
-
688
-    /**
689
-     * get end time
690
-     *
691
-     * @param string $tm_format string representation of time format defaults to 'g:i a'
692
-     * @return mixed                string on success, FALSE on fail
693
-     * @throws ReflectionException
694
-     * @throws InvalidArgumentException
695
-     * @throws InvalidInterfaceException
696
-     * @throws InvalidDataTypeException
697
-     * @throws EE_Error
698
-     */
699
-    public function end_time($tm_format = '')
700
-    {
701
-        return $this->_show_datetime('T', 'end', null, $tm_format);
702
-    }
703
-
704
-
705
-    /**
706
-     * @param string $tm_format
707
-     * @throws ReflectionException
708
-     * @throws InvalidArgumentException
709
-     * @throws InvalidInterfaceException
710
-     * @throws InvalidDataTypeException
711
-     * @throws EE_Error
712
-     */
713
-    public function e_end_time($tm_format = '')
714
-    {
715
-        $this->_show_datetime('T', 'end', null, $tm_format, true);
716
-    }
717
-
718
-
719
-    /**
720
-     * get time_range
721
-     *
722
-     * @access public
723
-     * @param string $tm_format   string representation of time format defaults to 'g:i a'
724
-     * @param string $conjunction conjunction junction what's your function ?
725
-     *                            this string joins the start date with the end date ie: Jan 01 "to" Dec 31
726
-     * @return mixed              string on success, FALSE on fail
727
-     * @throws ReflectionException
728
-     * @throws InvalidArgumentException
729
-     * @throws InvalidInterfaceException
730
-     * @throws InvalidDataTypeException
731
-     * @throws EE_Error
732
-     */
733
-    public function time_range($tm_format = '', $conjunction = ' - ')
734
-    {
735
-        $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
736
-        $start = str_replace(
737
-            ' ',
738
-            '&nbsp;',
739
-            $this->get_i18n_datetime('DTT_EVT_start', $tm_format)
740
-        );
741
-        $end = str_replace(
742
-            ' ',
743
-            '&nbsp;',
744
-            $this->get_i18n_datetime('DTT_EVT_end', $tm_format)
745
-        );
746
-        return $start !== $end ? $start . $conjunction . $end : $start;
747
-    }
748
-
749
-
750
-    /**
751
-     * @param string $tm_format
752
-     * @param string $conjunction
753
-     * @throws ReflectionException
754
-     * @throws InvalidArgumentException
755
-     * @throws InvalidInterfaceException
756
-     * @throws InvalidDataTypeException
757
-     * @throws EE_Error
758
-     */
759
-    public function e_time_range($tm_format = '', $conjunction = ' - ')
760
-    {
761
-        echo $this->time_range($tm_format, $conjunction);
762
-    }
763
-
764
-
765
-    /**
766
-     * This returns a range representation of the date and times.
767
-     * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end.
768
-     * Also, the return value is localized.
769
-     *
770
-     * @param string $dt_format
771
-     * @param string $tm_format
772
-     * @param string $conjunction used between two different dates or times.
773
-     *                            ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm
774
-     * @param string $separator   used between the date and time formats.
775
-     *                            ex: Dec 1, 2016{$separator}2pm
776
-     * @return string
777
-     * @throws ReflectionException
778
-     * @throws InvalidArgumentException
779
-     * @throws InvalidInterfaceException
780
-     * @throws InvalidDataTypeException
781
-     * @throws EE_Error
782
-     */
783
-    public function date_and_time_range(
784
-        $dt_format = '',
785
-        $tm_format = '',
786
-        $conjunction = ' - ',
787
-        $separator = ' '
788
-    ) {
789
-        $dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt;
790
-        $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
791
-        $full_format = $dt_format . $separator . $tm_format;
792
-        // the range output depends on various conditions
793
-        switch (true) {
794
-            // start date timestamp and end date timestamp are the same.
795
-            case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')):
796
-                $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format);
797
-                break;
798
-            // start and end date are the same but times are different
799
-            case ($this->start_date() === $this->end_date()):
800
-                $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
801
-                          . $conjunction
802
-                          . $this->get_i18n_datetime('DTT_EVT_end', $tm_format);
803
-                break;
804
-            // all other conditions
805
-            default:
806
-                $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
807
-                          . $conjunction
808
-                          . $this->get_i18n_datetime('DTT_EVT_end', $full_format);
809
-                break;
810
-        }
811
-        return $output;
812
-    }
813
-
814
-
815
-    /**
816
-     * This echos the results of date and time range.
817
-     *
818
-     * @see date_and_time_range() for more details on purpose.
819
-     * @param string $dt_format
820
-     * @param string $tm_format
821
-     * @param string $conjunction
822
-     * @return void
823
-     * @throws ReflectionException
824
-     * @throws InvalidArgumentException
825
-     * @throws InvalidInterfaceException
826
-     * @throws InvalidDataTypeException
827
-     * @throws EE_Error
828
-     */
829
-    public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ')
830
-    {
831
-        echo $this->date_and_time_range($dt_format, $tm_format, $conjunction);
832
-    }
833
-
834
-
835
-    /**
836
-     * get start date and start time
837
-     *
838
-     * @param    string $dt_format - string representation of date format defaults to 'F j, Y'
839
-     * @param    string $tm_format - string representation of time format defaults to 'g:i a'
840
-     * @return    mixed    string on success, FALSE on fail
841
-     * @throws ReflectionException
842
-     * @throws InvalidArgumentException
843
-     * @throws InvalidInterfaceException
844
-     * @throws InvalidDataTypeException
845
-     * @throws EE_Error
846
-     */
847
-    public function start_date_and_time($dt_format = '', $tm_format = '')
848
-    {
849
-        return $this->_show_datetime('', 'start', $dt_format, $tm_format);
850
-    }
851
-
852
-
853
-    /**
854
-     * @param string $dt_frmt
855
-     * @param string $tm_format
856
-     * @throws ReflectionException
857
-     * @throws InvalidArgumentException
858
-     * @throws InvalidInterfaceException
859
-     * @throws InvalidDataTypeException
860
-     * @throws EE_Error
861
-     */
862
-    public function e_start_date_and_time($dt_frmt = '', $tm_format = '')
863
-    {
864
-        $this->_show_datetime('', 'start', $dt_frmt, $tm_format, true);
865
-    }
866
-
867
-
868
-    /**
869
-     * Shows the length of the event (start to end time).
870
-     * Can be shown in 'seconds','minutes','hours', or 'days'.
871
-     * By default, rounds up. (So if you use 'days', and then event
872
-     * only occurs for 1 hour, it will return 1 day).
873
-     *
874
-     * @param string $units 'seconds','minutes','hours','days'
875
-     * @param bool   $round_up
876
-     * @return float|int|mixed
877
-     * @throws ReflectionException
878
-     * @throws InvalidArgumentException
879
-     * @throws InvalidInterfaceException
880
-     * @throws InvalidDataTypeException
881
-     * @throws EE_Error
882
-     */
883
-    public function length($units = 'seconds', $round_up = false)
884
-    {
885
-        $start = $this->get_raw('DTT_EVT_start');
886
-        $end = $this->get_raw('DTT_EVT_end');
887
-        $length_in_units = $end - $start;
888
-        switch ($units) {
889
-            // NOTE: We purposefully don't use "break;" in order to chain the divisions
890
-            /** @noinspection PhpMissingBreakStatementInspection */
891
-            // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
892
-            case 'days':
893
-                $length_in_units /= 24;
894
-            /** @noinspection PhpMissingBreakStatementInspection */
895
-            case 'hours':
896
-                // fall through is intentional
897
-                $length_in_units /= 60;
898
-            /** @noinspection PhpMissingBreakStatementInspection */
899
-            case 'minutes':
900
-                // fall through is intentional
901
-                $length_in_units /= 60;
902
-            case 'seconds':
903
-            default:
904
-                $length_in_units = ceil($length_in_units);
905
-        }
906
-        // phpcs:enable
907
-        if ($round_up) {
908
-            $length_in_units = max($length_in_units, 1);
909
-        }
910
-        return $length_in_units;
911
-    }
912
-
913
-
914
-    /**
915
-     *        get end date and time
916
-     *
917
-     * @param string $dt_frmt   - string representation of date format defaults to 'F j, Y'
918
-     * @param string $tm_format - string representation of time format defaults to 'g:i a'
919
-     * @return    mixed                string on success, FALSE on fail
920
-     * @throws ReflectionException
921
-     * @throws InvalidArgumentException
922
-     * @throws InvalidInterfaceException
923
-     * @throws InvalidDataTypeException
924
-     * @throws EE_Error
925
-     */
926
-    public function end_date_and_time($dt_frmt = '', $tm_format = '')
927
-    {
928
-        return $this->_show_datetime('', 'end', $dt_frmt, $tm_format);
929
-    }
930
-
931
-
932
-    /**
933
-     * @param string $dt_frmt
934
-     * @param string $tm_format
935
-     * @throws ReflectionException
936
-     * @throws InvalidArgumentException
937
-     * @throws InvalidInterfaceException
938
-     * @throws InvalidDataTypeException
939
-     * @throws EE_Error
940
-     */
941
-    public function e_end_date_and_time($dt_frmt = '', $tm_format = '')
942
-    {
943
-        $this->_show_datetime('', 'end', $dt_frmt, $tm_format, true);
944
-    }
945
-
946
-
947
-    /**
948
-     *        get start timestamp
949
-     *
950
-     * @return        int
951
-     * @throws ReflectionException
952
-     * @throws InvalidArgumentException
953
-     * @throws InvalidInterfaceException
954
-     * @throws InvalidDataTypeException
955
-     * @throws EE_Error
956
-     */
957
-    public function start()
958
-    {
959
-        return $this->get_raw('DTT_EVT_start');
960
-    }
961
-
962
-
963
-    /**
964
-     *        get end timestamp
965
-     *
966
-     * @return        int
967
-     * @throws ReflectionException
968
-     * @throws InvalidArgumentException
969
-     * @throws InvalidInterfaceException
970
-     * @throws InvalidDataTypeException
971
-     * @throws EE_Error
972
-     */
973
-    public function end()
974
-    {
975
-        return $this->get_raw('DTT_EVT_end');
976
-    }
977
-
978
-
979
-    /**
980
-     *    get the registration limit for this datetime slot
981
-     *
982
-     * @return        mixed        int on success, FALSE on fail
983
-     * @throws ReflectionException
984
-     * @throws InvalidArgumentException
985
-     * @throws InvalidInterfaceException
986
-     * @throws InvalidDataTypeException
987
-     * @throws EE_Error
988
-     */
989
-    public function reg_limit()
990
-    {
991
-        return $this->get_raw('DTT_reg_limit');
992
-    }
993
-
994
-
995
-    /**
996
-     *    have the tickets sold for this datetime, met or exceed the registration limit ?
997
-     *
998
-     * @return        boolean
999
-     * @throws ReflectionException
1000
-     * @throws InvalidArgumentException
1001
-     * @throws InvalidInterfaceException
1002
-     * @throws InvalidDataTypeException
1003
-     * @throws EE_Error
1004
-     */
1005
-    public function sold_out()
1006
-    {
1007
-        return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit();
1008
-    }
1009
-
1010
-
1011
-    /**
1012
-     * return the total number of spaces remaining at this venue.
1013
-     * This only takes the venue's capacity into account, NOT the tickets available for sale
1014
-     *
1015
-     * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left
1016
-     *                               Because if all tickets attached to this datetime have no spaces left,
1017
-     *                               then this datetime IS effectively sold out.
1018
-     *                               However, there are cases where we just want to know the spaces
1019
-     *                               remaining for this particular datetime, hence the flag.
1020
-     * @return int
1021
-     * @throws ReflectionException
1022
-     * @throws InvalidArgumentException
1023
-     * @throws InvalidInterfaceException
1024
-     * @throws InvalidDataTypeException
1025
-     * @throws EE_Error
1026
-     */
1027
-    public function spaces_remaining($consider_tickets = false)
1028
-    {
1029
-        // tickets remaining available for purchase
1030
-        // no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF
1031
-        $dtt_remaining = $this->reg_limit() - $this->sold_and_reserved();
1032
-        if (! $consider_tickets) {
1033
-            return $dtt_remaining;
1034
-        }
1035
-        $tickets_remaining = $this->tickets_remaining();
1036
-        return min($dtt_remaining, $tickets_remaining);
1037
-    }
1038
-
1039
-
1040
-    /**
1041
-     * Counts the total tickets available
1042
-     * (from all the different types of tickets which are available for this datetime).
1043
-     *
1044
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1045
-     * @return int
1046
-     * @throws ReflectionException
1047
-     * @throws InvalidArgumentException
1048
-     * @throws InvalidInterfaceException
1049
-     * @throws InvalidDataTypeException
1050
-     * @throws EE_Error
1051
-     */
1052
-    public function tickets_remaining($query_params = array())
1053
-    {
1054
-        $sum = 0;
1055
-        $tickets = $this->tickets($query_params);
1056
-        if (! empty($tickets)) {
1057
-            foreach ($tickets as $ticket) {
1058
-                if ($ticket instanceof EE_Ticket) {
1059
-                    // get the actual amount of tickets that can be sold
1060
-                    $qty = $ticket->qty('saleable');
1061
-                    if ($qty === EE_INF) {
1062
-                        return EE_INF;
1063
-                    }
1064
-                    // no negative ticket quantities plz
1065
-                    if ($qty > 0) {
1066
-                        $sum += $qty;
1067
-                    }
1068
-                }
1069
-            }
1070
-        }
1071
-        return $sum;
1072
-    }
1073
-
1074
-
1075
-    /**
1076
-     * Gets the count of all the tickets available at this datetime (not ticket types)
1077
-     * before any were sold
1078
-     *
1079
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1080
-     * @return int
1081
-     * @throws ReflectionException
1082
-     * @throws InvalidArgumentException
1083
-     * @throws InvalidInterfaceException
1084
-     * @throws InvalidDataTypeException
1085
-     * @throws EE_Error
1086
-     */
1087
-    public function sum_tickets_initially_available($query_params = array())
1088
-    {
1089
-        return $this->sum_related('Ticket', $query_params, 'TKT_qty');
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     * Returns the lesser-of-the two: spaces remaining at this datetime, or
1095
-     * the total tickets remaining (a sum of the tickets remaining for each ticket type
1096
-     * that is available for this datetime).
1097
-     *
1098
-     * @return int
1099
-     * @throws ReflectionException
1100
-     * @throws InvalidArgumentException
1101
-     * @throws InvalidInterfaceException
1102
-     * @throws InvalidDataTypeException
1103
-     * @throws EE_Error
1104
-     */
1105
-    public function total_tickets_available_at_this_datetime()
1106
-    {
1107
-        return $this->spaces_remaining(true);
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     * This simply compares the internal dtt for the given string with NOW
1113
-     * and determines if the date is upcoming or not.
1114
-     *
1115
-     * @access public
1116
-     * @return boolean
1117
-     * @throws ReflectionException
1118
-     * @throws InvalidArgumentException
1119
-     * @throws InvalidInterfaceException
1120
-     * @throws InvalidDataTypeException
1121
-     * @throws EE_Error
1122
-     */
1123
-    public function is_upcoming()
1124
-    {
1125
-        return ($this->get_raw('DTT_EVT_start') > time());
1126
-    }
1127
-
1128
-
1129
-    /**
1130
-     * This simply compares the internal datetime for the given string with NOW
1131
-     * and returns if the date is active (i.e. start and end time)
1132
-     *
1133
-     * @return boolean
1134
-     * @throws ReflectionException
1135
-     * @throws InvalidArgumentException
1136
-     * @throws InvalidInterfaceException
1137
-     * @throws InvalidDataTypeException
1138
-     * @throws EE_Error
1139
-     */
1140
-    public function is_active()
1141
-    {
1142
-        return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time());
1143
-    }
1144
-
1145
-
1146
-    /**
1147
-     * This simply compares the internal dtt for the given string with NOW
1148
-     * and determines if the date is expired or not.
1149
-     *
1150
-     * @return boolean
1151
-     * @throws ReflectionException
1152
-     * @throws InvalidArgumentException
1153
-     * @throws InvalidInterfaceException
1154
-     * @throws InvalidDataTypeException
1155
-     * @throws EE_Error
1156
-     */
1157
-    public function is_expired()
1158
-    {
1159
-        return ($this->get_raw('DTT_EVT_end') < time());
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * This returns the active status for whether an event is active, upcoming, or expired
1165
-     *
1166
-     * @return int return value will be one of the EE_Datetime status constants.
1167
-     * @throws ReflectionException
1168
-     * @throws InvalidArgumentException
1169
-     * @throws InvalidInterfaceException
1170
-     * @throws InvalidDataTypeException
1171
-     * @throws EE_Error
1172
-     */
1173
-    public function get_active_status()
1174
-    {
1175
-        $total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime();
1176
-        if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) {
1177
-            return EE_Datetime::sold_out;
1178
-        }
1179
-        if ($this->is_expired()) {
1180
-            return EE_Datetime::expired;
1181
-        }
1182
-        if ($this->is_upcoming()) {
1183
-            return EE_Datetime::upcoming;
1184
-        }
1185
-        if ($this->is_active()) {
1186
-            return EE_Datetime::active;
1187
-        }
1188
-        return null;
1189
-    }
1190
-
1191
-
1192
-    /**
1193
-     * This returns a nice display name for the datetime that is contingent on the span between the dates and times.
1194
-     *
1195
-     * @param  boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty.
1196
-     * @return string
1197
-     * @throws ReflectionException
1198
-     * @throws InvalidArgumentException
1199
-     * @throws InvalidInterfaceException
1200
-     * @throws InvalidDataTypeException
1201
-     * @throws EE_Error
1202
-     */
1203
-    public function get_dtt_display_name($use_dtt_name = false)
1204
-    {
1205
-        if ($use_dtt_name) {
1206
-            $dtt_name = $this->name();
1207
-            if (! empty($dtt_name)) {
1208
-                return $dtt_name;
1209
-            }
1210
-        }
1211
-        // first condition is to see if the months are different
1212
-        if (
1213
-            date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end'))
1214
-        ) {
1215
-            $display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a');
1216
-            // next condition is if its the same month but different day
1217
-        } else {
1218
-            if (
1219
-                date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end'))
1220
-                && date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end'))
1221
-            ) {
1222
-                $display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y');
1223
-            } else {
1224
-                $display_date = $this->start_date('F j\, Y')
1225
-                                . ' @ '
1226
-                                . $this->start_date('g:i a')
1227
-                                . ' - '
1228
-                                . $this->end_date('g:i a');
1229
-            }
1230
-        }
1231
-        return $display_date;
1232
-    }
1233
-
1234
-
1235
-    /**
1236
-     * Gets all the tickets for this datetime
1237
-     *
1238
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1239
-     * @return EE_Base_Class[]|EE_Ticket[]
1240
-     * @throws ReflectionException
1241
-     * @throws InvalidArgumentException
1242
-     * @throws InvalidInterfaceException
1243
-     * @throws InvalidDataTypeException
1244
-     * @throws EE_Error
1245
-     */
1246
-    public function tickets($query_params = array())
1247
-    {
1248
-        return $this->get_many_related('Ticket', $query_params);
1249
-    }
1250
-
1251
-
1252
-    /**
1253
-     * Gets all the ticket types currently available for purchase
1254
-     *
1255
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
-     * @return EE_Ticket[]
1257
-     * @throws ReflectionException
1258
-     * @throws InvalidArgumentException
1259
-     * @throws InvalidInterfaceException
1260
-     * @throws InvalidDataTypeException
1261
-     * @throws EE_Error
1262
-     */
1263
-    public function ticket_types_available_for_purchase($query_params = array())
1264
-    {
1265
-        // first check if datetime is valid
1266
-        if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) {
1267
-            return array();
1268
-        }
1269
-        if (empty($query_params)) {
1270
-            $query_params = array(
1271
-                array(
1272
-                    'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')),
1273
-                    'TKT_end_date'   => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
1274
-                    'TKT_deleted'    => false,
1275
-                ),
1276
-            );
1277
-        }
1278
-        return $this->tickets($query_params);
1279
-    }
1280
-
1281
-
1282
-    /**
1283
-     * @return EE_Base_Class|EE_Event
1284
-     * @throws ReflectionException
1285
-     * @throws InvalidArgumentException
1286
-     * @throws InvalidInterfaceException
1287
-     * @throws InvalidDataTypeException
1288
-     * @throws EE_Error
1289
-     */
1290
-    public function event()
1291
-    {
1292
-        return $this->get_first_related('Event');
1293
-    }
1294
-
1295
-
1296
-    /**
1297
-     * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime
1298
-     * (via the tickets).
1299
-     *
1300
-     * @return int
1301
-     * @throws ReflectionException
1302
-     * @throws InvalidArgumentException
1303
-     * @throws InvalidInterfaceException
1304
-     * @throws InvalidDataTypeException
1305
-     * @throws EE_Error
1306
-     */
1307
-    public function update_sold()
1308
-    {
1309
-        $count_regs_for_this_datetime = EEM_Registration::instance()->count(
1310
-            array(
1311
-                array(
1312
-                    'STS_ID'                 => EEM_Registration::status_id_approved,
1313
-                    'REG_deleted'            => 0,
1314
-                    'Ticket.Datetime.DTT_ID' => $this->ID(),
1315
-                ),
1316
-            )
1317
-        );
1318
-        $this->set_sold($count_regs_for_this_datetime);
1319
-        $this->save();
1320
-        return $count_regs_for_this_datetime;
1321
-    }
1322
-
1323
-
1324
-    /**
1325
-     * Adds a venue to this event
1326
-     *
1327
-     * @param int|EE_Venue /int $venue_id_or_obj
1328
-     * @return EE_Base_Class|EE_Venue
1329
-     * @throws EE_Error
1330
-     * @throws ReflectionException
1331
-     */
1332
-    public function add_venue($venue_id_or_obj): EE_Venue
1333
-    {
1334
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     * Removes a venue from the event
1340
-     *
1341
-     * @param EE_Venue /int $venue_id_or_obj
1342
-     * @return EE_Base_Class|EE_Venue
1343
-     * @throws EE_Error
1344
-     * @throws ReflectionException
1345
-     */
1346
-    public function remove_venue($venue_id_or_obj): EE_Venue
1347
-    {
1348
-        $venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
1349
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
1350
-    }
1351
-
1352
-
1353
-    /**
1354
-     * Gets the venue related to the event. May provide additional $query_params if desired
1355
-     *
1356
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1357
-     * @return int
1358
-     * @throws EE_Error
1359
-     * @throws ReflectionException
1360
-     */
1361
-    public function venue_ID(array $query_params = []): int
1362
-    {
1363
-        $venue = $this->get_first_related('Venue', $query_params);
1364
-        return $venue instanceof EE_Venue
1365
-            ? $venue->ID()
1366
-            : 0;
1367
-    }
1368
-
1369
-
1370
-    /**
1371
-     * Gets the venue related to the event. May provide additional $query_params if desired
1372
-     *
1373
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1374
-     * @return EE_Base_Class|EE_Venue
1375
-     * @throws EE_Error
1376
-     * @throws ReflectionException
1377
-     */
1378
-    public function venue(array $query_params = [])
1379
-    {
1380
-        return $this->get_first_related('Venue', $query_params);
1381
-    }
1382
-
1383
-
1384
-    /**
1385
-     * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1386
-     * @param string                   $relationName
1387
-     * @param array                    $extra_join_model_fields_n_values
1388
-     * @param string|null              $cache_id
1389
-     * @return EE_Base_Class
1390
-     * @throws EE_Error
1391
-     * @throws ReflectionException
1392
-     * @since   $VID:$
1393
-     */
1394
-    public function _add_relation_to(
1395
-        $otherObjectModelObjectOrID,
1396
-        $relationName,
1397
-        $extra_join_model_fields_n_values = [],
1398
-        $cache_id = null
1399
-    ) {
1400
-        // if we're adding a new relation to a ticket
1401
-        if ($relationName === 'Ticket' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1402
-            /** @var EE_Ticket $ticket */
1403
-            $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1404
-            $this->increaseSold($ticket->sold(), false);
1405
-            $this->increaseReserved($ticket->reserved());
1406
-            $this->save();
1407
-            $otherObjectModelObjectOrID = $ticket;
1408
-        }
1409
-        return parent::_add_relation_to(
1410
-            $otherObjectModelObjectOrID,
1411
-            $relationName,
1412
-            $extra_join_model_fields_n_values,
1413
-            $cache_id
1414
-        );
1415
-    }
1416
-
1417
-
1418
-    /**
1419
-     * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1420
-     * @param string                   $relationName
1421
-     * @param array                    $where_query
1422
-     * @return bool|EE_Base_Class|null
1423
-     * @throws EE_Error
1424
-     * @throws ReflectionException
1425
-     * @since   $VID:$
1426
-     */
1427
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = [])
1428
-    {
1429
-        if ($relationName === 'Ticket' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1430
-            /** @var EE_Ticket $ticket */
1431
-            $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1432
-            $this->decreaseSold($ticket->sold());
1433
-            $this->decreaseReserved($ticket->reserved());
1434
-            $this->save();
1435
-            $otherObjectModelObjectOrID = $ticket;
1436
-        }
1437
-        return parent::_remove_relation_to(
1438
-            $otherObjectModelObjectOrID,
1439
-            $relationName,
1440
-            $where_query
1441
-        );
1442
-    }
1443
-
1444
-
1445
-    /**
1446
-     * Removes ALL the related things for the $relationName.
1447
-     *
1448
-     * @param string $relationName
1449
-     * @param array  $where_query_params
1450
-     * @return EE_Base_Class
1451
-     * @throws ReflectionException
1452
-     * @throws InvalidArgumentException
1453
-     * @throws InvalidInterfaceException
1454
-     * @throws InvalidDataTypeException
1455
-     * @throws EE_Error
1456
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
1457
-     */
1458
-    public function _remove_relations($relationName, $where_query_params = [])
1459
-    {
1460
-        if ($relationName === 'Ticket') {
1461
-            $tickets = $this->tickets();
1462
-            foreach ($tickets as $ticket) {
1463
-                $this->decreaseSold($ticket->sold());
1464
-                $this->decreaseReserved($ticket->reserved());
1465
-                $this->save();
1466
-            }
1467
-        }
1468
-        return parent::_remove_relations($relationName, $where_query_params);
1469
-    }
1470
-
1471
-
1472
-    /*******************************************************************
16
+	/**
17
+	 * constant used by get_active_status, indicates datetime has no more available spaces
18
+	 */
19
+	const sold_out = 'DTS';
20
+
21
+	/**
22
+	 * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for)
23
+	 */
24
+	const active = 'DTA';
25
+
26
+	/**
27
+	 * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not
28
+	 * expired
29
+	 */
30
+	const upcoming = 'DTU';
31
+
32
+	/**
33
+	 * Datetime is postponed
34
+	 */
35
+	const postponed = 'DTP';
36
+
37
+	/**
38
+	 * Datetime is cancelled
39
+	 */
40
+	const cancelled = 'DTC';
41
+
42
+	/**
43
+	 * constant used by get_active_status, indicates datetime has expired (event is over)
44
+	 */
45
+	const expired = 'DTE';
46
+
47
+	/**
48
+	 * constant used in various places indicating that an event is INACTIVE (not yet ready to be published)
49
+	 */
50
+	const inactive = 'DTI';
51
+
52
+
53
+	/**
54
+	 * @param array  $props_n_values    incoming values
55
+	 * @param string $timezone          incoming timezone (if not set the timezone set for the website will be used.)
56
+	 * @param array  $date_formats      incoming date_formats in an array where the first value is the date_format
57
+	 *                                  and the second value is the time format
58
+	 * @return EE_Datetime
59
+	 * @throws ReflectionException
60
+	 * @throws InvalidArgumentException
61
+	 * @throws InvalidInterfaceException
62
+	 * @throws InvalidDataTypeException
63
+	 * @throws EE_Error
64
+	 */
65
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
66
+	{
67
+		$has_object = parent::_check_for_object(
68
+			$props_n_values,
69
+			__CLASS__,
70
+			$timezone,
71
+			$date_formats
72
+		);
73
+		return $has_object
74
+			? $has_object
75
+			: new self($props_n_values, false, $timezone, $date_formats);
76
+	}
77
+
78
+
79
+	/**
80
+	 * @param array  $props_n_values  incoming values from the database
81
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
+	 *                                the website will be used.
83
+	 * @return EE_Datetime
84
+	 * @throws ReflectionException
85
+	 * @throws InvalidArgumentException
86
+	 * @throws InvalidInterfaceException
87
+	 * @throws InvalidDataTypeException
88
+	 * @throws EE_Error
89
+	 */
90
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
91
+	{
92
+		return new self($props_n_values, true, $timezone);
93
+	}
94
+
95
+
96
+	/**
97
+	 * @param $name
98
+	 * @throws ReflectionException
99
+	 * @throws InvalidArgumentException
100
+	 * @throws InvalidInterfaceException
101
+	 * @throws InvalidDataTypeException
102
+	 * @throws EE_Error
103
+	 */
104
+	public function set_name($name)
105
+	{
106
+		$this->set('DTT_name', $name);
107
+	}
108
+
109
+
110
+	/**
111
+	 * @param $description
112
+	 * @throws ReflectionException
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidInterfaceException
115
+	 * @throws InvalidDataTypeException
116
+	 * @throws EE_Error
117
+	 */
118
+	public function set_description($description)
119
+	{
120
+		$this->set('DTT_description', $description);
121
+	}
122
+
123
+
124
+	/**
125
+	 * Set event start date
126
+	 * set the start date for an event
127
+	 *
128
+	 * @param string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
129
+	 * @throws ReflectionException
130
+	 * @throws InvalidArgumentException
131
+	 * @throws InvalidInterfaceException
132
+	 * @throws InvalidDataTypeException
133
+	 * @throws EE_Error
134
+	 */
135
+	public function set_start_date($date)
136
+	{
137
+		$this->_set_date_for($date, 'DTT_EVT_start');
138
+	}
139
+
140
+
141
+	/**
142
+	 * Set event start time
143
+	 * set the start time for an event
144
+	 *
145
+	 * @param string $time a string representation of the event time ex:  9am  or  7:30 PM
146
+	 * @throws ReflectionException
147
+	 * @throws InvalidArgumentException
148
+	 * @throws InvalidInterfaceException
149
+	 * @throws InvalidDataTypeException
150
+	 * @throws EE_Error
151
+	 */
152
+	public function set_start_time($time)
153
+	{
154
+		$this->_set_time_for($time, 'DTT_EVT_start');
155
+	}
156
+
157
+
158
+	/**
159
+	 * Set event end date
160
+	 * set the end date for an event
161
+	 *
162
+	 * @param string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
163
+	 * @throws ReflectionException
164
+	 * @throws InvalidArgumentException
165
+	 * @throws InvalidInterfaceException
166
+	 * @throws InvalidDataTypeException
167
+	 * @throws EE_Error
168
+	 */
169
+	public function set_end_date($date)
170
+	{
171
+		$this->_set_date_for($date, 'DTT_EVT_end');
172
+	}
173
+
174
+
175
+	/**
176
+	 * Set event end time
177
+	 * set the end time for an event
178
+	 *
179
+	 * @param string $time a string representation of the event time ex:  9am  or  7:30 PM
180
+	 * @throws ReflectionException
181
+	 * @throws InvalidArgumentException
182
+	 * @throws InvalidInterfaceException
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws EE_Error
185
+	 */
186
+	public function set_end_time($time)
187
+	{
188
+		$this->_set_time_for($time, 'DTT_EVT_end');
189
+	}
190
+
191
+
192
+	/**
193
+	 * Set registration limit
194
+	 * set the maximum number of attendees that can be registered for this datetime slot
195
+	 *
196
+	 * @param int $reg_limit
197
+	 * @throws ReflectionException
198
+	 * @throws InvalidArgumentException
199
+	 * @throws InvalidInterfaceException
200
+	 * @throws InvalidDataTypeException
201
+	 * @throws EE_Error
202
+	 */
203
+	public function set_reg_limit($reg_limit)
204
+	{
205
+		$this->set('DTT_reg_limit', $reg_limit);
206
+	}
207
+
208
+
209
+	/**
210
+	 * get the number of tickets sold for this datetime slot
211
+	 *
212
+	 * @return mixed int on success, FALSE on fail
213
+	 * @throws ReflectionException
214
+	 * @throws InvalidArgumentException
215
+	 * @throws InvalidInterfaceException
216
+	 * @throws InvalidDataTypeException
217
+	 * @throws EE_Error
218
+	 */
219
+	public function sold()
220
+	{
221
+		return $this->get_raw('DTT_sold');
222
+	}
223
+
224
+
225
+	/**
226
+	 * @param int $sold
227
+	 * @throws ReflectionException
228
+	 * @throws InvalidArgumentException
229
+	 * @throws InvalidInterfaceException
230
+	 * @throws InvalidDataTypeException
231
+	 * @throws EE_Error
232
+	 */
233
+	public function set_sold($sold)
234
+	{
235
+		// sold can not go below zero
236
+		$sold = max(0, $sold);
237
+		$this->set('DTT_sold', $sold);
238
+	}
239
+
240
+
241
+	/**
242
+	 * Increments sold by amount passed by $qty, and persists it immediately to the database.
243
+	 * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false.
244
+	 *
245
+	 * @param int $qty
246
+	 * @param boolean $also_decrease_reserved
247
+	 * @return boolean indicating success
248
+	 * @throws ReflectionException
249
+	 * @throws InvalidArgumentException
250
+	 * @throws InvalidInterfaceException
251
+	 * @throws InvalidDataTypeException
252
+	 * @throws EE_Error
253
+	 */
254
+	public function increaseSold($qty = 1, $also_decrease_reserved = true)
255
+	{
256
+		$qty = absint($qty);
257
+		if ($also_decrease_reserved) {
258
+			$success = $this->adjustNumericFieldsInDb(
259
+				[
260
+					'DTT_reserved' => $qty * -1,
261
+					'DTT_sold' => $qty
262
+				]
263
+			);
264
+		} else {
265
+			$success = $this->adjustNumericFieldsInDb(
266
+				[
267
+					'DTT_sold' => $qty
268
+				]
269
+			);
270
+		}
271
+
272
+		do_action(
273
+			'AHEE__EE_Datetime__increase_sold',
274
+			$this,
275
+			$qty,
276
+			$this->sold(),
277
+			$success
278
+		);
279
+		return $success;
280
+	}
281
+
282
+
283
+	/**
284
+	 * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need
285
+	 * to save afterwards.)
286
+	 *
287
+	 * @param int $qty
288
+	 * @return boolean indicating success
289
+	 * @throws ReflectionException
290
+	 * @throws InvalidArgumentException
291
+	 * @throws InvalidInterfaceException
292
+	 * @throws InvalidDataTypeException
293
+	 * @throws EE_Error
294
+	 */
295
+	public function decreaseSold($qty = 1)
296
+	{
297
+		$qty = absint($qty);
298
+		$success = $this->adjustNumericFieldsInDb(
299
+			[
300
+				'DTT_sold' => $qty * -1
301
+			]
302
+		);
303
+		do_action(
304
+			'AHEE__EE_Datetime__decrease_sold',
305
+			$this,
306
+			$qty,
307
+			$this->sold(),
308
+			$success
309
+		);
310
+		return $success;
311
+	}
312
+
313
+
314
+	/**
315
+	 * Gets qty of reserved tickets for this datetime
316
+	 *
317
+	 * @return int
318
+	 * @throws ReflectionException
319
+	 * @throws InvalidArgumentException
320
+	 * @throws InvalidInterfaceException
321
+	 * @throws InvalidDataTypeException
322
+	 * @throws EE_Error
323
+	 */
324
+	public function reserved()
325
+	{
326
+		return $this->get_raw('DTT_reserved');
327
+	}
328
+
329
+
330
+	/**
331
+	 * Sets qty of reserved tickets for this datetime
332
+	 *
333
+	 * @param int $reserved
334
+	 * @throws ReflectionException
335
+	 * @throws InvalidArgumentException
336
+	 * @throws InvalidInterfaceException
337
+	 * @throws InvalidDataTypeException
338
+	 * @throws EE_Error
339
+	 */
340
+	public function set_reserved($reserved)
341
+	{
342
+		// reserved can not go below zero
343
+		$reserved = max(0, (int) $reserved);
344
+		$this->set('DTT_reserved', $reserved);
345
+	}
346
+
347
+
348
+	/**
349
+	 * Increments reserved by amount passed by $qty, and persists it immediately to the database.
350
+	 *
351
+	 * @param int $qty
352
+	 * @return boolean indicating success
353
+	 * @throws ReflectionException
354
+	 * @throws InvalidArgumentException
355
+	 * @throws InvalidInterfaceException
356
+	 * @throws InvalidDataTypeException
357
+	 * @throws EE_Error
358
+	 */
359
+	public function increaseReserved($qty = 1)
360
+	{
361
+		$qty = absint($qty);
362
+		$success = $this->incrementFieldConditionallyInDb(
363
+			'DTT_reserved',
364
+			'DTT_sold',
365
+			'DTT_reg_limit',
366
+			$qty
367
+		);
368
+		do_action(
369
+			'AHEE__EE_Datetime__increase_reserved',
370
+			$this,
371
+			$qty,
372
+			$this->reserved(),
373
+			$success
374
+		);
375
+		return $success;
376
+	}
377
+
378
+
379
+	/**
380
+	 * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
381
+	 *
382
+	 * @param int $qty
383
+	 * @return boolean indicating success
384
+	 * @throws ReflectionException
385
+	 * @throws InvalidArgumentException
386
+	 * @throws InvalidInterfaceException
387
+	 * @throws InvalidDataTypeException
388
+	 * @throws EE_Error
389
+	 */
390
+	public function decreaseReserved($qty = 1)
391
+	{
392
+		$qty = absint($qty);
393
+		$success = $this->adjustNumericFieldsInDb(
394
+			[
395
+				'DTT_reserved' => $qty * -1
396
+			]
397
+		);
398
+		do_action(
399
+			'AHEE__EE_Datetime__decrease_reserved',
400
+			$this,
401
+			$qty,
402
+			$this->reserved(),
403
+			$success
404
+		);
405
+		return $success;
406
+	}
407
+
408
+
409
+	/**
410
+	 * total sold and reserved tickets
411
+	 *
412
+	 * @return int
413
+	 * @throws ReflectionException
414
+	 * @throws InvalidArgumentException
415
+	 * @throws InvalidInterfaceException
416
+	 * @throws InvalidDataTypeException
417
+	 * @throws EE_Error
418
+	 */
419
+	public function sold_and_reserved()
420
+	{
421
+		return $this->sold() + $this->reserved();
422
+	}
423
+
424
+
425
+	/**
426
+	 * returns the datetime name
427
+	 *
428
+	 * @return string
429
+	 * @throws ReflectionException
430
+	 * @throws InvalidArgumentException
431
+	 * @throws InvalidInterfaceException
432
+	 * @throws InvalidDataTypeException
433
+	 * @throws EE_Error
434
+	 */
435
+	public function name()
436
+	{
437
+		return $this->get('DTT_name');
438
+	}
439
+
440
+
441
+	/**
442
+	 * returns the datetime description
443
+	 *
444
+	 * @return string
445
+	 * @throws ReflectionException
446
+	 * @throws InvalidArgumentException
447
+	 * @throws InvalidInterfaceException
448
+	 * @throws InvalidDataTypeException
449
+	 * @throws EE_Error
450
+	 */
451
+	public function description()
452
+	{
453
+		return $this->get('DTT_description');
454
+	}
455
+
456
+
457
+	/**
458
+	 * This helper simply returns whether the event_datetime for the current datetime is a primary datetime
459
+	 *
460
+	 * @return boolean  TRUE if is primary, FALSE if not.
461
+	 * @throws ReflectionException
462
+	 * @throws InvalidArgumentException
463
+	 * @throws InvalidInterfaceException
464
+	 * @throws InvalidDataTypeException
465
+	 * @throws EE_Error
466
+	 */
467
+	public function is_primary()
468
+	{
469
+		return $this->get('DTT_is_primary');
470
+	}
471
+
472
+
473
+	/**
474
+	 * This helper simply returns the order for the datetime
475
+	 *
476
+	 * @return int  The order of the datetime for this event.
477
+	 * @throws ReflectionException
478
+	 * @throws InvalidArgumentException
479
+	 * @throws InvalidInterfaceException
480
+	 * @throws InvalidDataTypeException
481
+	 * @throws EE_Error
482
+	 */
483
+	public function order()
484
+	{
485
+		return $this->get('DTT_order');
486
+	}
487
+
488
+
489
+	/**
490
+	 * This helper simply returns the parent id for the datetime
491
+	 *
492
+	 * @return int
493
+	 * @throws ReflectionException
494
+	 * @throws InvalidArgumentException
495
+	 * @throws InvalidInterfaceException
496
+	 * @throws InvalidDataTypeException
497
+	 * @throws EE_Error
498
+	 */
499
+	public function parent()
500
+	{
501
+		return $this->get('DTT_parent');
502
+	}
503
+
504
+
505
+	/**
506
+	 * show date and/or time
507
+	 *
508
+	 * @param string $date_or_time    whether to display a date or time or both
509
+	 * @param string $start_or_end    whether to display start or end datetimes
510
+	 * @param string $dt_frmt
511
+	 * @param string $tm_frmt
512
+	 * @param bool   $echo            whether we echo or return (note echoing uses "pretty" formats,
513
+	 *                                otherwise we use the standard formats)
514
+	 * @return string|bool  string on success, FALSE on fail
515
+	 * @throws ReflectionException
516
+	 * @throws InvalidArgumentException
517
+	 * @throws InvalidInterfaceException
518
+	 * @throws InvalidDataTypeException
519
+	 * @throws EE_Error
520
+	 */
521
+	private function _show_datetime(
522
+		$date_or_time = null,
523
+		$start_or_end = 'start',
524
+		$dt_frmt = '',
525
+		$tm_frmt = '',
526
+		$echo = false
527
+	) {
528
+		$field_name = "DTT_EVT_{$start_or_end}";
529
+		$dtt = $this->_get_datetime(
530
+			$field_name,
531
+			$dt_frmt,
532
+			$tm_frmt,
533
+			$date_or_time,
534
+			$echo
535
+		);
536
+		if (! $echo) {
537
+			return $dtt;
538
+		}
539
+		return '';
540
+	}
541
+
542
+
543
+	/**
544
+	 * get event start date.  Provide either the date format, or NULL to re-use the
545
+	 * last-used format, or '' to use the default date format
546
+	 *
547
+	 * @param string $dt_frmt string representation of date format defaults to 'F j, Y'
548
+	 * @return mixed            string on success, FALSE on fail
549
+	 * @throws ReflectionException
550
+	 * @throws InvalidArgumentException
551
+	 * @throws InvalidInterfaceException
552
+	 * @throws InvalidDataTypeException
553
+	 * @throws EE_Error
554
+	 */
555
+	public function start_date($dt_frmt = '')
556
+	{
557
+		return $this->_show_datetime('D', 'start', $dt_frmt);
558
+	}
559
+
560
+
561
+	/**
562
+	 * Echoes start_date()
563
+	 *
564
+	 * @param string $dt_frmt
565
+	 * @throws ReflectionException
566
+	 * @throws InvalidArgumentException
567
+	 * @throws InvalidInterfaceException
568
+	 * @throws InvalidDataTypeException
569
+	 * @throws EE_Error
570
+	 */
571
+	public function e_start_date($dt_frmt = '')
572
+	{
573
+		$this->_show_datetime('D', 'start', $dt_frmt, null, true);
574
+	}
575
+
576
+
577
+	/**
578
+	 * get end date. Provide either the date format, or NULL to re-use the
579
+	 * last-used format, or '' to use the default date format
580
+	 *
581
+	 * @param string $dt_frmt string representation of date format defaults to 'F j, Y'
582
+	 * @return mixed            string on success, FALSE on fail
583
+	 * @throws ReflectionException
584
+	 * @throws InvalidArgumentException
585
+	 * @throws InvalidInterfaceException
586
+	 * @throws InvalidDataTypeException
587
+	 * @throws EE_Error
588
+	 */
589
+	public function end_date($dt_frmt = '')
590
+	{
591
+		return $this->_show_datetime('D', 'end', $dt_frmt);
592
+	}
593
+
594
+
595
+	/**
596
+	 * Echoes the end date. See end_date()
597
+	 *
598
+	 * @param string $dt_frmt
599
+	 * @throws ReflectionException
600
+	 * @throws InvalidArgumentException
601
+	 * @throws InvalidInterfaceException
602
+	 * @throws InvalidDataTypeException
603
+	 * @throws EE_Error
604
+	 */
605
+	public function e_end_date($dt_frmt = '')
606
+	{
607
+		$this->_show_datetime('D', 'end', $dt_frmt, null, true);
608
+	}
609
+
610
+
611
+	/**
612
+	 * get date_range - meaning the start AND end date
613
+	 *
614
+	 * @access public
615
+	 * @param string $dt_frmt     string representation of date format defaults to WP settings
616
+	 * @param string $conjunction conjunction junction what's your function ?
617
+	 *                            this string joins the start date with the end date ie: Jan 01 "to" Dec 31
618
+	 * @return mixed              string on success, FALSE on fail
619
+	 * @throws ReflectionException
620
+	 * @throws InvalidArgumentException
621
+	 * @throws InvalidInterfaceException
622
+	 * @throws InvalidDataTypeException
623
+	 * @throws EE_Error
624
+	 */
625
+	public function date_range($dt_frmt = '', $conjunction = ' - ')
626
+	{
627
+		$dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt;
628
+		$start = str_replace(
629
+			' ',
630
+			'&nbsp;',
631
+			$this->get_i18n_datetime('DTT_EVT_start', $dt_frmt)
632
+		);
633
+		$end = str_replace(
634
+			' ',
635
+			'&nbsp;',
636
+			$this->get_i18n_datetime('DTT_EVT_end', $dt_frmt)
637
+		);
638
+		return $start !== $end ? $start . $conjunction . $end : $start;
639
+	}
640
+
641
+
642
+	/**
643
+	 * @param string $dt_frmt
644
+	 * @param string $conjunction
645
+	 * @throws ReflectionException
646
+	 * @throws InvalidArgumentException
647
+	 * @throws InvalidInterfaceException
648
+	 * @throws InvalidDataTypeException
649
+	 * @throws EE_Error
650
+	 */
651
+	public function e_date_range($dt_frmt = '', $conjunction = ' - ')
652
+	{
653
+		echo $this->date_range($dt_frmt, $conjunction);
654
+	}
655
+
656
+
657
+	/**
658
+	 * get start time
659
+	 *
660
+	 * @param string $tm_format - string representation of time format defaults to 'g:i a'
661
+	 * @return mixed        string on success, FALSE on fail
662
+	 * @throws ReflectionException
663
+	 * @throws InvalidArgumentException
664
+	 * @throws InvalidInterfaceException
665
+	 * @throws InvalidDataTypeException
666
+	 * @throws EE_Error
667
+	 */
668
+	public function start_time($tm_format = '')
669
+	{
670
+		return $this->_show_datetime('T', 'start', null, $tm_format);
671
+	}
672
+
673
+
674
+	/**
675
+	 * @param string $tm_format
676
+	 * @throws ReflectionException
677
+	 * @throws InvalidArgumentException
678
+	 * @throws InvalidInterfaceException
679
+	 * @throws InvalidDataTypeException
680
+	 * @throws EE_Error
681
+	 */
682
+	public function e_start_time($tm_format = '')
683
+	{
684
+		$this->_show_datetime('T', 'start', null, $tm_format, true);
685
+	}
686
+
687
+
688
+	/**
689
+	 * get end time
690
+	 *
691
+	 * @param string $tm_format string representation of time format defaults to 'g:i a'
692
+	 * @return mixed                string on success, FALSE on fail
693
+	 * @throws ReflectionException
694
+	 * @throws InvalidArgumentException
695
+	 * @throws InvalidInterfaceException
696
+	 * @throws InvalidDataTypeException
697
+	 * @throws EE_Error
698
+	 */
699
+	public function end_time($tm_format = '')
700
+	{
701
+		return $this->_show_datetime('T', 'end', null, $tm_format);
702
+	}
703
+
704
+
705
+	/**
706
+	 * @param string $tm_format
707
+	 * @throws ReflectionException
708
+	 * @throws InvalidArgumentException
709
+	 * @throws InvalidInterfaceException
710
+	 * @throws InvalidDataTypeException
711
+	 * @throws EE_Error
712
+	 */
713
+	public function e_end_time($tm_format = '')
714
+	{
715
+		$this->_show_datetime('T', 'end', null, $tm_format, true);
716
+	}
717
+
718
+
719
+	/**
720
+	 * get time_range
721
+	 *
722
+	 * @access public
723
+	 * @param string $tm_format   string representation of time format defaults to 'g:i a'
724
+	 * @param string $conjunction conjunction junction what's your function ?
725
+	 *                            this string joins the start date with the end date ie: Jan 01 "to" Dec 31
726
+	 * @return mixed              string on success, FALSE on fail
727
+	 * @throws ReflectionException
728
+	 * @throws InvalidArgumentException
729
+	 * @throws InvalidInterfaceException
730
+	 * @throws InvalidDataTypeException
731
+	 * @throws EE_Error
732
+	 */
733
+	public function time_range($tm_format = '', $conjunction = ' - ')
734
+	{
735
+		$tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
736
+		$start = str_replace(
737
+			' ',
738
+			'&nbsp;',
739
+			$this->get_i18n_datetime('DTT_EVT_start', $tm_format)
740
+		);
741
+		$end = str_replace(
742
+			' ',
743
+			'&nbsp;',
744
+			$this->get_i18n_datetime('DTT_EVT_end', $tm_format)
745
+		);
746
+		return $start !== $end ? $start . $conjunction . $end : $start;
747
+	}
748
+
749
+
750
+	/**
751
+	 * @param string $tm_format
752
+	 * @param string $conjunction
753
+	 * @throws ReflectionException
754
+	 * @throws InvalidArgumentException
755
+	 * @throws InvalidInterfaceException
756
+	 * @throws InvalidDataTypeException
757
+	 * @throws EE_Error
758
+	 */
759
+	public function e_time_range($tm_format = '', $conjunction = ' - ')
760
+	{
761
+		echo $this->time_range($tm_format, $conjunction);
762
+	}
763
+
764
+
765
+	/**
766
+	 * This returns a range representation of the date and times.
767
+	 * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end.
768
+	 * Also, the return value is localized.
769
+	 *
770
+	 * @param string $dt_format
771
+	 * @param string $tm_format
772
+	 * @param string $conjunction used between two different dates or times.
773
+	 *                            ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm
774
+	 * @param string $separator   used between the date and time formats.
775
+	 *                            ex: Dec 1, 2016{$separator}2pm
776
+	 * @return string
777
+	 * @throws ReflectionException
778
+	 * @throws InvalidArgumentException
779
+	 * @throws InvalidInterfaceException
780
+	 * @throws InvalidDataTypeException
781
+	 * @throws EE_Error
782
+	 */
783
+	public function date_and_time_range(
784
+		$dt_format = '',
785
+		$tm_format = '',
786
+		$conjunction = ' - ',
787
+		$separator = ' '
788
+	) {
789
+		$dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt;
790
+		$tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
791
+		$full_format = $dt_format . $separator . $tm_format;
792
+		// the range output depends on various conditions
793
+		switch (true) {
794
+			// start date timestamp and end date timestamp are the same.
795
+			case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')):
796
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format);
797
+				break;
798
+			// start and end date are the same but times are different
799
+			case ($this->start_date() === $this->end_date()):
800
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
801
+						  . $conjunction
802
+						  . $this->get_i18n_datetime('DTT_EVT_end', $tm_format);
803
+				break;
804
+			// all other conditions
805
+			default:
806
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
807
+						  . $conjunction
808
+						  . $this->get_i18n_datetime('DTT_EVT_end', $full_format);
809
+				break;
810
+		}
811
+		return $output;
812
+	}
813
+
814
+
815
+	/**
816
+	 * This echos the results of date and time range.
817
+	 *
818
+	 * @see date_and_time_range() for more details on purpose.
819
+	 * @param string $dt_format
820
+	 * @param string $tm_format
821
+	 * @param string $conjunction
822
+	 * @return void
823
+	 * @throws ReflectionException
824
+	 * @throws InvalidArgumentException
825
+	 * @throws InvalidInterfaceException
826
+	 * @throws InvalidDataTypeException
827
+	 * @throws EE_Error
828
+	 */
829
+	public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ')
830
+	{
831
+		echo $this->date_and_time_range($dt_format, $tm_format, $conjunction);
832
+	}
833
+
834
+
835
+	/**
836
+	 * get start date and start time
837
+	 *
838
+	 * @param    string $dt_format - string representation of date format defaults to 'F j, Y'
839
+	 * @param    string $tm_format - string representation of time format defaults to 'g:i a'
840
+	 * @return    mixed    string on success, FALSE on fail
841
+	 * @throws ReflectionException
842
+	 * @throws InvalidArgumentException
843
+	 * @throws InvalidInterfaceException
844
+	 * @throws InvalidDataTypeException
845
+	 * @throws EE_Error
846
+	 */
847
+	public function start_date_and_time($dt_format = '', $tm_format = '')
848
+	{
849
+		return $this->_show_datetime('', 'start', $dt_format, $tm_format);
850
+	}
851
+
852
+
853
+	/**
854
+	 * @param string $dt_frmt
855
+	 * @param string $tm_format
856
+	 * @throws ReflectionException
857
+	 * @throws InvalidArgumentException
858
+	 * @throws InvalidInterfaceException
859
+	 * @throws InvalidDataTypeException
860
+	 * @throws EE_Error
861
+	 */
862
+	public function e_start_date_and_time($dt_frmt = '', $tm_format = '')
863
+	{
864
+		$this->_show_datetime('', 'start', $dt_frmt, $tm_format, true);
865
+	}
866
+
867
+
868
+	/**
869
+	 * Shows the length of the event (start to end time).
870
+	 * Can be shown in 'seconds','minutes','hours', or 'days'.
871
+	 * By default, rounds up. (So if you use 'days', and then event
872
+	 * only occurs for 1 hour, it will return 1 day).
873
+	 *
874
+	 * @param string $units 'seconds','minutes','hours','days'
875
+	 * @param bool   $round_up
876
+	 * @return float|int|mixed
877
+	 * @throws ReflectionException
878
+	 * @throws InvalidArgumentException
879
+	 * @throws InvalidInterfaceException
880
+	 * @throws InvalidDataTypeException
881
+	 * @throws EE_Error
882
+	 */
883
+	public function length($units = 'seconds', $round_up = false)
884
+	{
885
+		$start = $this->get_raw('DTT_EVT_start');
886
+		$end = $this->get_raw('DTT_EVT_end');
887
+		$length_in_units = $end - $start;
888
+		switch ($units) {
889
+			// NOTE: We purposefully don't use "break;" in order to chain the divisions
890
+			/** @noinspection PhpMissingBreakStatementInspection */
891
+			// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
892
+			case 'days':
893
+				$length_in_units /= 24;
894
+			/** @noinspection PhpMissingBreakStatementInspection */
895
+			case 'hours':
896
+				// fall through is intentional
897
+				$length_in_units /= 60;
898
+			/** @noinspection PhpMissingBreakStatementInspection */
899
+			case 'minutes':
900
+				// fall through is intentional
901
+				$length_in_units /= 60;
902
+			case 'seconds':
903
+			default:
904
+				$length_in_units = ceil($length_in_units);
905
+		}
906
+		// phpcs:enable
907
+		if ($round_up) {
908
+			$length_in_units = max($length_in_units, 1);
909
+		}
910
+		return $length_in_units;
911
+	}
912
+
913
+
914
+	/**
915
+	 *        get end date and time
916
+	 *
917
+	 * @param string $dt_frmt   - string representation of date format defaults to 'F j, Y'
918
+	 * @param string $tm_format - string representation of time format defaults to 'g:i a'
919
+	 * @return    mixed                string on success, FALSE on fail
920
+	 * @throws ReflectionException
921
+	 * @throws InvalidArgumentException
922
+	 * @throws InvalidInterfaceException
923
+	 * @throws InvalidDataTypeException
924
+	 * @throws EE_Error
925
+	 */
926
+	public function end_date_and_time($dt_frmt = '', $tm_format = '')
927
+	{
928
+		return $this->_show_datetime('', 'end', $dt_frmt, $tm_format);
929
+	}
930
+
931
+
932
+	/**
933
+	 * @param string $dt_frmt
934
+	 * @param string $tm_format
935
+	 * @throws ReflectionException
936
+	 * @throws InvalidArgumentException
937
+	 * @throws InvalidInterfaceException
938
+	 * @throws InvalidDataTypeException
939
+	 * @throws EE_Error
940
+	 */
941
+	public function e_end_date_and_time($dt_frmt = '', $tm_format = '')
942
+	{
943
+		$this->_show_datetime('', 'end', $dt_frmt, $tm_format, true);
944
+	}
945
+
946
+
947
+	/**
948
+	 *        get start timestamp
949
+	 *
950
+	 * @return        int
951
+	 * @throws ReflectionException
952
+	 * @throws InvalidArgumentException
953
+	 * @throws InvalidInterfaceException
954
+	 * @throws InvalidDataTypeException
955
+	 * @throws EE_Error
956
+	 */
957
+	public function start()
958
+	{
959
+		return $this->get_raw('DTT_EVT_start');
960
+	}
961
+
962
+
963
+	/**
964
+	 *        get end timestamp
965
+	 *
966
+	 * @return        int
967
+	 * @throws ReflectionException
968
+	 * @throws InvalidArgumentException
969
+	 * @throws InvalidInterfaceException
970
+	 * @throws InvalidDataTypeException
971
+	 * @throws EE_Error
972
+	 */
973
+	public function end()
974
+	{
975
+		return $this->get_raw('DTT_EVT_end');
976
+	}
977
+
978
+
979
+	/**
980
+	 *    get the registration limit for this datetime slot
981
+	 *
982
+	 * @return        mixed        int on success, FALSE on fail
983
+	 * @throws ReflectionException
984
+	 * @throws InvalidArgumentException
985
+	 * @throws InvalidInterfaceException
986
+	 * @throws InvalidDataTypeException
987
+	 * @throws EE_Error
988
+	 */
989
+	public function reg_limit()
990
+	{
991
+		return $this->get_raw('DTT_reg_limit');
992
+	}
993
+
994
+
995
+	/**
996
+	 *    have the tickets sold for this datetime, met or exceed the registration limit ?
997
+	 *
998
+	 * @return        boolean
999
+	 * @throws ReflectionException
1000
+	 * @throws InvalidArgumentException
1001
+	 * @throws InvalidInterfaceException
1002
+	 * @throws InvalidDataTypeException
1003
+	 * @throws EE_Error
1004
+	 */
1005
+	public function sold_out()
1006
+	{
1007
+		return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit();
1008
+	}
1009
+
1010
+
1011
+	/**
1012
+	 * return the total number of spaces remaining at this venue.
1013
+	 * This only takes the venue's capacity into account, NOT the tickets available for sale
1014
+	 *
1015
+	 * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left
1016
+	 *                               Because if all tickets attached to this datetime have no spaces left,
1017
+	 *                               then this datetime IS effectively sold out.
1018
+	 *                               However, there are cases where we just want to know the spaces
1019
+	 *                               remaining for this particular datetime, hence the flag.
1020
+	 * @return int
1021
+	 * @throws ReflectionException
1022
+	 * @throws InvalidArgumentException
1023
+	 * @throws InvalidInterfaceException
1024
+	 * @throws InvalidDataTypeException
1025
+	 * @throws EE_Error
1026
+	 */
1027
+	public function spaces_remaining($consider_tickets = false)
1028
+	{
1029
+		// tickets remaining available for purchase
1030
+		// no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF
1031
+		$dtt_remaining = $this->reg_limit() - $this->sold_and_reserved();
1032
+		if (! $consider_tickets) {
1033
+			return $dtt_remaining;
1034
+		}
1035
+		$tickets_remaining = $this->tickets_remaining();
1036
+		return min($dtt_remaining, $tickets_remaining);
1037
+	}
1038
+
1039
+
1040
+	/**
1041
+	 * Counts the total tickets available
1042
+	 * (from all the different types of tickets which are available for this datetime).
1043
+	 *
1044
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1045
+	 * @return int
1046
+	 * @throws ReflectionException
1047
+	 * @throws InvalidArgumentException
1048
+	 * @throws InvalidInterfaceException
1049
+	 * @throws InvalidDataTypeException
1050
+	 * @throws EE_Error
1051
+	 */
1052
+	public function tickets_remaining($query_params = array())
1053
+	{
1054
+		$sum = 0;
1055
+		$tickets = $this->tickets($query_params);
1056
+		if (! empty($tickets)) {
1057
+			foreach ($tickets as $ticket) {
1058
+				if ($ticket instanceof EE_Ticket) {
1059
+					// get the actual amount of tickets that can be sold
1060
+					$qty = $ticket->qty('saleable');
1061
+					if ($qty === EE_INF) {
1062
+						return EE_INF;
1063
+					}
1064
+					// no negative ticket quantities plz
1065
+					if ($qty > 0) {
1066
+						$sum += $qty;
1067
+					}
1068
+				}
1069
+			}
1070
+		}
1071
+		return $sum;
1072
+	}
1073
+
1074
+
1075
+	/**
1076
+	 * Gets the count of all the tickets available at this datetime (not ticket types)
1077
+	 * before any were sold
1078
+	 *
1079
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1080
+	 * @return int
1081
+	 * @throws ReflectionException
1082
+	 * @throws InvalidArgumentException
1083
+	 * @throws InvalidInterfaceException
1084
+	 * @throws InvalidDataTypeException
1085
+	 * @throws EE_Error
1086
+	 */
1087
+	public function sum_tickets_initially_available($query_params = array())
1088
+	{
1089
+		return $this->sum_related('Ticket', $query_params, 'TKT_qty');
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 * Returns the lesser-of-the two: spaces remaining at this datetime, or
1095
+	 * the total tickets remaining (a sum of the tickets remaining for each ticket type
1096
+	 * that is available for this datetime).
1097
+	 *
1098
+	 * @return int
1099
+	 * @throws ReflectionException
1100
+	 * @throws InvalidArgumentException
1101
+	 * @throws InvalidInterfaceException
1102
+	 * @throws InvalidDataTypeException
1103
+	 * @throws EE_Error
1104
+	 */
1105
+	public function total_tickets_available_at_this_datetime()
1106
+	{
1107
+		return $this->spaces_remaining(true);
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 * This simply compares the internal dtt for the given string with NOW
1113
+	 * and determines if the date is upcoming or not.
1114
+	 *
1115
+	 * @access public
1116
+	 * @return boolean
1117
+	 * @throws ReflectionException
1118
+	 * @throws InvalidArgumentException
1119
+	 * @throws InvalidInterfaceException
1120
+	 * @throws InvalidDataTypeException
1121
+	 * @throws EE_Error
1122
+	 */
1123
+	public function is_upcoming()
1124
+	{
1125
+		return ($this->get_raw('DTT_EVT_start') > time());
1126
+	}
1127
+
1128
+
1129
+	/**
1130
+	 * This simply compares the internal datetime for the given string with NOW
1131
+	 * and returns if the date is active (i.e. start and end time)
1132
+	 *
1133
+	 * @return boolean
1134
+	 * @throws ReflectionException
1135
+	 * @throws InvalidArgumentException
1136
+	 * @throws InvalidInterfaceException
1137
+	 * @throws InvalidDataTypeException
1138
+	 * @throws EE_Error
1139
+	 */
1140
+	public function is_active()
1141
+	{
1142
+		return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time());
1143
+	}
1144
+
1145
+
1146
+	/**
1147
+	 * This simply compares the internal dtt for the given string with NOW
1148
+	 * and determines if the date is expired or not.
1149
+	 *
1150
+	 * @return boolean
1151
+	 * @throws ReflectionException
1152
+	 * @throws InvalidArgumentException
1153
+	 * @throws InvalidInterfaceException
1154
+	 * @throws InvalidDataTypeException
1155
+	 * @throws EE_Error
1156
+	 */
1157
+	public function is_expired()
1158
+	{
1159
+		return ($this->get_raw('DTT_EVT_end') < time());
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * This returns the active status for whether an event is active, upcoming, or expired
1165
+	 *
1166
+	 * @return int return value will be one of the EE_Datetime status constants.
1167
+	 * @throws ReflectionException
1168
+	 * @throws InvalidArgumentException
1169
+	 * @throws InvalidInterfaceException
1170
+	 * @throws InvalidDataTypeException
1171
+	 * @throws EE_Error
1172
+	 */
1173
+	public function get_active_status()
1174
+	{
1175
+		$total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime();
1176
+		if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) {
1177
+			return EE_Datetime::sold_out;
1178
+		}
1179
+		if ($this->is_expired()) {
1180
+			return EE_Datetime::expired;
1181
+		}
1182
+		if ($this->is_upcoming()) {
1183
+			return EE_Datetime::upcoming;
1184
+		}
1185
+		if ($this->is_active()) {
1186
+			return EE_Datetime::active;
1187
+		}
1188
+		return null;
1189
+	}
1190
+
1191
+
1192
+	/**
1193
+	 * This returns a nice display name for the datetime that is contingent on the span between the dates and times.
1194
+	 *
1195
+	 * @param  boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty.
1196
+	 * @return string
1197
+	 * @throws ReflectionException
1198
+	 * @throws InvalidArgumentException
1199
+	 * @throws InvalidInterfaceException
1200
+	 * @throws InvalidDataTypeException
1201
+	 * @throws EE_Error
1202
+	 */
1203
+	public function get_dtt_display_name($use_dtt_name = false)
1204
+	{
1205
+		if ($use_dtt_name) {
1206
+			$dtt_name = $this->name();
1207
+			if (! empty($dtt_name)) {
1208
+				return $dtt_name;
1209
+			}
1210
+		}
1211
+		// first condition is to see if the months are different
1212
+		if (
1213
+			date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end'))
1214
+		) {
1215
+			$display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a');
1216
+			// next condition is if its the same month but different day
1217
+		} else {
1218
+			if (
1219
+				date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end'))
1220
+				&& date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end'))
1221
+			) {
1222
+				$display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y');
1223
+			} else {
1224
+				$display_date = $this->start_date('F j\, Y')
1225
+								. ' @ '
1226
+								. $this->start_date('g:i a')
1227
+								. ' - '
1228
+								. $this->end_date('g:i a');
1229
+			}
1230
+		}
1231
+		return $display_date;
1232
+	}
1233
+
1234
+
1235
+	/**
1236
+	 * Gets all the tickets for this datetime
1237
+	 *
1238
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1239
+	 * @return EE_Base_Class[]|EE_Ticket[]
1240
+	 * @throws ReflectionException
1241
+	 * @throws InvalidArgumentException
1242
+	 * @throws InvalidInterfaceException
1243
+	 * @throws InvalidDataTypeException
1244
+	 * @throws EE_Error
1245
+	 */
1246
+	public function tickets($query_params = array())
1247
+	{
1248
+		return $this->get_many_related('Ticket', $query_params);
1249
+	}
1250
+
1251
+
1252
+	/**
1253
+	 * Gets all the ticket types currently available for purchase
1254
+	 *
1255
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
+	 * @return EE_Ticket[]
1257
+	 * @throws ReflectionException
1258
+	 * @throws InvalidArgumentException
1259
+	 * @throws InvalidInterfaceException
1260
+	 * @throws InvalidDataTypeException
1261
+	 * @throws EE_Error
1262
+	 */
1263
+	public function ticket_types_available_for_purchase($query_params = array())
1264
+	{
1265
+		// first check if datetime is valid
1266
+		if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) {
1267
+			return array();
1268
+		}
1269
+		if (empty($query_params)) {
1270
+			$query_params = array(
1271
+				array(
1272
+					'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')),
1273
+					'TKT_end_date'   => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
1274
+					'TKT_deleted'    => false,
1275
+				),
1276
+			);
1277
+		}
1278
+		return $this->tickets($query_params);
1279
+	}
1280
+
1281
+
1282
+	/**
1283
+	 * @return EE_Base_Class|EE_Event
1284
+	 * @throws ReflectionException
1285
+	 * @throws InvalidArgumentException
1286
+	 * @throws InvalidInterfaceException
1287
+	 * @throws InvalidDataTypeException
1288
+	 * @throws EE_Error
1289
+	 */
1290
+	public function event()
1291
+	{
1292
+		return $this->get_first_related('Event');
1293
+	}
1294
+
1295
+
1296
+	/**
1297
+	 * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime
1298
+	 * (via the tickets).
1299
+	 *
1300
+	 * @return int
1301
+	 * @throws ReflectionException
1302
+	 * @throws InvalidArgumentException
1303
+	 * @throws InvalidInterfaceException
1304
+	 * @throws InvalidDataTypeException
1305
+	 * @throws EE_Error
1306
+	 */
1307
+	public function update_sold()
1308
+	{
1309
+		$count_regs_for_this_datetime = EEM_Registration::instance()->count(
1310
+			array(
1311
+				array(
1312
+					'STS_ID'                 => EEM_Registration::status_id_approved,
1313
+					'REG_deleted'            => 0,
1314
+					'Ticket.Datetime.DTT_ID' => $this->ID(),
1315
+				),
1316
+			)
1317
+		);
1318
+		$this->set_sold($count_regs_for_this_datetime);
1319
+		$this->save();
1320
+		return $count_regs_for_this_datetime;
1321
+	}
1322
+
1323
+
1324
+	/**
1325
+	 * Adds a venue to this event
1326
+	 *
1327
+	 * @param int|EE_Venue /int $venue_id_or_obj
1328
+	 * @return EE_Base_Class|EE_Venue
1329
+	 * @throws EE_Error
1330
+	 * @throws ReflectionException
1331
+	 */
1332
+	public function add_venue($venue_id_or_obj): EE_Venue
1333
+	{
1334
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 * Removes a venue from the event
1340
+	 *
1341
+	 * @param EE_Venue /int $venue_id_or_obj
1342
+	 * @return EE_Base_Class|EE_Venue
1343
+	 * @throws EE_Error
1344
+	 * @throws ReflectionException
1345
+	 */
1346
+	public function remove_venue($venue_id_or_obj): EE_Venue
1347
+	{
1348
+		$venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
1349
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
1350
+	}
1351
+
1352
+
1353
+	/**
1354
+	 * Gets the venue related to the event. May provide additional $query_params if desired
1355
+	 *
1356
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1357
+	 * @return int
1358
+	 * @throws EE_Error
1359
+	 * @throws ReflectionException
1360
+	 */
1361
+	public function venue_ID(array $query_params = []): int
1362
+	{
1363
+		$venue = $this->get_first_related('Venue', $query_params);
1364
+		return $venue instanceof EE_Venue
1365
+			? $venue->ID()
1366
+			: 0;
1367
+	}
1368
+
1369
+
1370
+	/**
1371
+	 * Gets the venue related to the event. May provide additional $query_params if desired
1372
+	 *
1373
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1374
+	 * @return EE_Base_Class|EE_Venue
1375
+	 * @throws EE_Error
1376
+	 * @throws ReflectionException
1377
+	 */
1378
+	public function venue(array $query_params = [])
1379
+	{
1380
+		return $this->get_first_related('Venue', $query_params);
1381
+	}
1382
+
1383
+
1384
+	/**
1385
+	 * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1386
+	 * @param string                   $relationName
1387
+	 * @param array                    $extra_join_model_fields_n_values
1388
+	 * @param string|null              $cache_id
1389
+	 * @return EE_Base_Class
1390
+	 * @throws EE_Error
1391
+	 * @throws ReflectionException
1392
+	 * @since   $VID:$
1393
+	 */
1394
+	public function _add_relation_to(
1395
+		$otherObjectModelObjectOrID,
1396
+		$relationName,
1397
+		$extra_join_model_fields_n_values = [],
1398
+		$cache_id = null
1399
+	) {
1400
+		// if we're adding a new relation to a ticket
1401
+		if ($relationName === 'Ticket' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1402
+			/** @var EE_Ticket $ticket */
1403
+			$ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1404
+			$this->increaseSold($ticket->sold(), false);
1405
+			$this->increaseReserved($ticket->reserved());
1406
+			$this->save();
1407
+			$otherObjectModelObjectOrID = $ticket;
1408
+		}
1409
+		return parent::_add_relation_to(
1410
+			$otherObjectModelObjectOrID,
1411
+			$relationName,
1412
+			$extra_join_model_fields_n_values,
1413
+			$cache_id
1414
+		);
1415
+	}
1416
+
1417
+
1418
+	/**
1419
+	 * @param EE_Base_Class|int|string $otherObjectModelObjectOrID
1420
+	 * @param string                   $relationName
1421
+	 * @param array                    $where_query
1422
+	 * @return bool|EE_Base_Class|null
1423
+	 * @throws EE_Error
1424
+	 * @throws ReflectionException
1425
+	 * @since   $VID:$
1426
+	 */
1427
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = [])
1428
+	{
1429
+		if ($relationName === 'Ticket' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) {
1430
+			/** @var EE_Ticket $ticket */
1431
+			$ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID);
1432
+			$this->decreaseSold($ticket->sold());
1433
+			$this->decreaseReserved($ticket->reserved());
1434
+			$this->save();
1435
+			$otherObjectModelObjectOrID = $ticket;
1436
+		}
1437
+		return parent::_remove_relation_to(
1438
+			$otherObjectModelObjectOrID,
1439
+			$relationName,
1440
+			$where_query
1441
+		);
1442
+	}
1443
+
1444
+
1445
+	/**
1446
+	 * Removes ALL the related things for the $relationName.
1447
+	 *
1448
+	 * @param string $relationName
1449
+	 * @param array  $where_query_params
1450
+	 * @return EE_Base_Class
1451
+	 * @throws ReflectionException
1452
+	 * @throws InvalidArgumentException
1453
+	 * @throws InvalidInterfaceException
1454
+	 * @throws InvalidDataTypeException
1455
+	 * @throws EE_Error
1456
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
1457
+	 */
1458
+	public function _remove_relations($relationName, $where_query_params = [])
1459
+	{
1460
+		if ($relationName === 'Ticket') {
1461
+			$tickets = $this->tickets();
1462
+			foreach ($tickets as $ticket) {
1463
+				$this->decreaseSold($ticket->sold());
1464
+				$this->decreaseReserved($ticket->reserved());
1465
+				$this->save();
1466
+			}
1467
+		}
1468
+		return parent::_remove_relations($relationName, $where_query_params);
1469
+	}
1470
+
1471
+
1472
+	/*******************************************************************
1473 1473
      ***********************  DEPRECATED METHODS  **********************
1474 1474
      *******************************************************************/
1475 1475
 
1476 1476
 
1477
-    /**
1478
-     * Increments sold by amount passed by $qty, and persists it immediately to the database.
1479
-     *
1480
-     * @deprecated 4.9.80.p
1481
-     * @param int $qty
1482
-     * @return boolean
1483
-     * @throws ReflectionException
1484
-     * @throws InvalidArgumentException
1485
-     * @throws InvalidInterfaceException
1486
-     * @throws InvalidDataTypeException
1487
-     * @throws EE_Error
1488
-     */
1489
-    public function increase_sold($qty = 1)
1490
-    {
1491
-        EE_Error::doing_it_wrong(
1492
-            __FUNCTION__,
1493
-            esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'),
1494
-            '4.9.80.p',
1495
-            '5.0.0.p'
1496
-        );
1497
-        return $this->increaseSold($qty);
1498
-    }
1499
-
1500
-
1501
-    /**
1502
-     * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need
1503
-     * to save afterwards.)
1504
-     *
1505
-     * @deprecated 4.9.80.p
1506
-     * @param int $qty
1507
-     * @return boolean
1508
-     * @throws ReflectionException
1509
-     * @throws InvalidArgumentException
1510
-     * @throws InvalidInterfaceException
1511
-     * @throws InvalidDataTypeException
1512
-     * @throws EE_Error
1513
-     */
1514
-    public function decrease_sold($qty = 1)
1515
-    {
1516
-        EE_Error::doing_it_wrong(
1517
-            __FUNCTION__,
1518
-            esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'),
1519
-            '4.9.80.p',
1520
-            '5.0.0.p'
1521
-        );
1522
-        return $this->decreaseSold($qty);
1523
-    }
1524
-
1525
-
1526
-    /**
1527
-     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
1528
-     *
1529
-     * @deprecated 4.9.80.p
1530
-     * @param int $qty
1531
-     * @return boolean indicating success
1532
-     * @throws ReflectionException
1533
-     * @throws InvalidArgumentException
1534
-     * @throws InvalidInterfaceException
1535
-     * @throws InvalidDataTypeException
1536
-     * @throws EE_Error
1537
-     */
1538
-    public function increase_reserved($qty = 1)
1539
-    {
1540
-        EE_Error::doing_it_wrong(
1541
-            __FUNCTION__,
1542
-            esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'),
1543
-            '4.9.80.p',
1544
-            '5.0.0.p'
1545
-        );
1546
-        return $this->increaseReserved($qty);
1547
-    }
1548
-
1549
-
1550
-    /**
1551
-     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
1552
-     *
1553
-     * @deprecated 4.9.80.p
1554
-     * @param int $qty
1555
-     * @return boolean
1556
-     * @throws ReflectionException
1557
-     * @throws InvalidArgumentException
1558
-     * @throws InvalidInterfaceException
1559
-     * @throws InvalidDataTypeException
1560
-     * @throws EE_Error
1561
-     */
1562
-    public function decrease_reserved($qty = 1)
1563
-    {
1564
-        EE_Error::doing_it_wrong(
1565
-            __FUNCTION__,
1566
-            esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'),
1567
-            '4.9.80.p',
1568
-            '5.0.0.p'
1569
-        );
1570
-        return $this->decreaseReserved($qty);
1571
-    }
1477
+	/**
1478
+	 * Increments sold by amount passed by $qty, and persists it immediately to the database.
1479
+	 *
1480
+	 * @deprecated 4.9.80.p
1481
+	 * @param int $qty
1482
+	 * @return boolean
1483
+	 * @throws ReflectionException
1484
+	 * @throws InvalidArgumentException
1485
+	 * @throws InvalidInterfaceException
1486
+	 * @throws InvalidDataTypeException
1487
+	 * @throws EE_Error
1488
+	 */
1489
+	public function increase_sold($qty = 1)
1490
+	{
1491
+		EE_Error::doing_it_wrong(
1492
+			__FUNCTION__,
1493
+			esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'),
1494
+			'4.9.80.p',
1495
+			'5.0.0.p'
1496
+		);
1497
+		return $this->increaseSold($qty);
1498
+	}
1499
+
1500
+
1501
+	/**
1502
+	 * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need
1503
+	 * to save afterwards.)
1504
+	 *
1505
+	 * @deprecated 4.9.80.p
1506
+	 * @param int $qty
1507
+	 * @return boolean
1508
+	 * @throws ReflectionException
1509
+	 * @throws InvalidArgumentException
1510
+	 * @throws InvalidInterfaceException
1511
+	 * @throws InvalidDataTypeException
1512
+	 * @throws EE_Error
1513
+	 */
1514
+	public function decrease_sold($qty = 1)
1515
+	{
1516
+		EE_Error::doing_it_wrong(
1517
+			__FUNCTION__,
1518
+			esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'),
1519
+			'4.9.80.p',
1520
+			'5.0.0.p'
1521
+		);
1522
+		return $this->decreaseSold($qty);
1523
+	}
1524
+
1525
+
1526
+	/**
1527
+	 * Increments reserved by amount passed by $qty, and persists it immediately to the database.
1528
+	 *
1529
+	 * @deprecated 4.9.80.p
1530
+	 * @param int $qty
1531
+	 * @return boolean indicating success
1532
+	 * @throws ReflectionException
1533
+	 * @throws InvalidArgumentException
1534
+	 * @throws InvalidInterfaceException
1535
+	 * @throws InvalidDataTypeException
1536
+	 * @throws EE_Error
1537
+	 */
1538
+	public function increase_reserved($qty = 1)
1539
+	{
1540
+		EE_Error::doing_it_wrong(
1541
+			__FUNCTION__,
1542
+			esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'),
1543
+			'4.9.80.p',
1544
+			'5.0.0.p'
1545
+		);
1546
+		return $this->increaseReserved($qty);
1547
+	}
1548
+
1549
+
1550
+	/**
1551
+	 * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
1552
+	 *
1553
+	 * @deprecated 4.9.80.p
1554
+	 * @param int $qty
1555
+	 * @return boolean
1556
+	 * @throws ReflectionException
1557
+	 * @throws InvalidArgumentException
1558
+	 * @throws InvalidInterfaceException
1559
+	 * @throws InvalidDataTypeException
1560
+	 * @throws EE_Error
1561
+	 */
1562
+	public function decrease_reserved($qty = 1)
1563
+	{
1564
+		EE_Error::doing_it_wrong(
1565
+			__FUNCTION__,
1566
+			esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'),
1567
+			'4.9.80.p',
1568
+			'5.0.0.p'
1569
+		);
1570
+		return $this->decreaseReserved($qty);
1571
+	}
1572 1572
 }
Please login to merge, or discard this patch.
core/domain/services/graphql/types/RootQuery.php 2 patches
Indentation   +167 added lines, -167 removed lines patch added patch discarded remove patch
@@ -32,171 +32,171 @@
 block discarded – undo
32 32
 class RootQuery extends TypeBase
33 33
 {
34 34
 
35
-    /**
36
-     * RootQuery constructor.
37
-     */
38
-    public function __construct()
39
-    {
40
-        $this->setName('RootQuery');
41
-        $this->setIsCustomPostType(true);
42
-        parent::__construct();
43
-    }
44
-
45
-
46
-    /**
47
-     * @return GraphQLFieldInterface[]
48
-     */
49
-    public function getFields(): array
50
-    {
51
-        return [
52
-            new GraphQLOutputField(
53
-                lcfirst($this->namespace) . 'EventRelations',
54
-                'String',
55
-                null,
56
-                esc_html__('JSON encoded relational data of the models', 'event_espresso'),
57
-                null,
58
-                [$this, 'getEventRelationalData'],
59
-                [],
60
-                [
61
-                    'eventId' => [
62
-                        'type'        => ['non_null' => 'Int'],
63
-                        'description' => esc_html__('The event ID to get the relational data for.', 'event_espresso'),
64
-                    ],
65
-                ]
66
-            ),
67
-            new GraphQLOutputField(
68
-                lcfirst($this->namespace) . 'Datetime',
69
-                $this->namespace . 'Datetime',
70
-                null,
71
-                esc_html__('A datetime', 'event_espresso'),
72
-                null,
73
-                [$this, 'getDatetime'],
74
-                [],
75
-                [
76
-                    'id' => [
77
-                        'type'        => [
78
-                            'non_null' => 'ID',
79
-                        ],
80
-                        'description' => esc_html__('The globally unique identifier of the datetime.', 'event_espresso'),
81
-                    ],
82
-                ]
83
-            ),
84
-            new GraphQLOutputField(
85
-                lcfirst($this->namespace) . 'Ticket',
86
-                $this->namespace . 'Ticket',
87
-                null,
88
-                esc_html__('A ticket', 'event_espresso'),
89
-                null,
90
-                [$this, 'getTicket'],
91
-                [],
92
-                [
93
-                    'id' => [
94
-                        'type'        => [
95
-                            'non_null' => 'ID',
96
-                        ],
97
-                        'description' => esc_html__('The globally unique identifier of the ticket.', 'event_espresso'),
98
-                    ],
99
-                ]
100
-            ),
101
-        ];
102
-    }
103
-
104
-
105
-    /**
106
-     * @param mixed       $source  The source that's passed down the GraphQL queries
107
-     * @param array       $args    The inputArgs on the field
108
-     * @param AppContext  $context The AppContext passed down the GraphQL tree
109
-     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
110
-     * @return string
111
-     * @throws Exception
112
-     * @throws InvalidArgumentException
113
-     * @throws InvalidDataTypeException
114
-     * @throws InvalidInterfaceException
115
-     * @throws UserError
116
-     * @throws UnexpectedEntityException
117
-     * @since $VID:$
118
-     */
119
-    public function getEventRelationalData($source, array $args, AppContext $context, ResolveInfo $info): string
120
-    {
121
-        /**
122
-         * Throw an exception if there's no event ID
123
-         */
124
-        if (empty($args['eventId']) || ! absint($args['eventId'])) {
125
-            throw new UserError(esc_html__(
126
-                'No event ID was provided to get the relational data for',
127
-                'event_espresso'
128
-            ));
129
-        }
130
-
131
-        $eventId = absint($args['eventId']);
132
-        /** @var EventEntityRelations $event_entity_relations */
133
-        $event_entity_relations = LoaderFactory::getLoader()->getShared(
134
-            'EventEspresso\core\domain\services\admin\events\editor\EventEntityRelations'
135
-        );
136
-        return json_encode($event_entity_relations->getData($eventId));
137
-    }
138
-
139
-
140
-    /**
141
-     * @param mixed       $source  The source that's passed down the GraphQL queries
142
-     * @param array       $args    The inputArgs on the field
143
-     * @param AppContext  $context The AppContext passed down the GraphQL tree
144
-     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
145
-     * @return string
146
-     * @throws Exception
147
-     * @throws InvalidArgumentException
148
-     * @throws InvalidDataTypeException
149
-     * @throws InvalidInterfaceException
150
-     * @throws UserError
151
-     * @throws UnexpectedEntityException
152
-     * @since $VID:$
153
-     */
154
-    public function getDatetime($source, array $args, AppContext $context, ResolveInfo $info): EE_Datetime
155
-    {
156
-        $parts = Relay::fromGlobalId(sanitize_text_field($args['id']));
157
-
158
-        /**
159
-         * Throw an exception if there's no ID
160
-         */
161
-        if (empty($parts['id'])) {
162
-            throw new UserError(esc_html__(
163
-                'A missing or invalid ID was received.',
164
-                'event_espresso'
165
-            ));
166
-        }
167
-
168
-        return EEM_Datetime::instance()->get_one_by_ID(absint($parts['id']));
169
-    }
170
-
171
-
172
-    /**
173
-     * @param mixed       $source  The source that's passed down the GraphQL queries
174
-     * @param array       $args    The inputArgs on the field
175
-     * @param AppContext  $context The AppContext passed down the GraphQL tree
176
-     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
177
-     * @return string
178
-     * @throws Exception
179
-     * @throws InvalidArgumentException
180
-     * @throws InvalidDataTypeException
181
-     * @throws InvalidInterfaceException
182
-     * @throws UserError
183
-     * @throws UnexpectedEntityException
184
-     * @since $VID:$
185
-     */
186
-    public function getTicket($source, array $args, AppContext $context, ResolveInfo $info): EE_Ticket
187
-    {
188
-        $parts = Relay::fromGlobalId(sanitize_text_field($args['id']));
189
-
190
-        /**
191
-         * Throw an exception if there's no ID
192
-         */
193
-        if (empty($parts['id'])) {
194
-            throw new UserError(esc_html__(
195
-                'A missing or invalid ID was received.',
196
-                'event_espresso'
197
-            ));
198
-        }
199
-
200
-        return EEM_Ticket::instance()->get_one_by_ID(absint($parts['id']));
201
-    }
35
+	/**
36
+	 * RootQuery constructor.
37
+	 */
38
+	public function __construct()
39
+	{
40
+		$this->setName('RootQuery');
41
+		$this->setIsCustomPostType(true);
42
+		parent::__construct();
43
+	}
44
+
45
+
46
+	/**
47
+	 * @return GraphQLFieldInterface[]
48
+	 */
49
+	public function getFields(): array
50
+	{
51
+		return [
52
+			new GraphQLOutputField(
53
+				lcfirst($this->namespace) . 'EventRelations',
54
+				'String',
55
+				null,
56
+				esc_html__('JSON encoded relational data of the models', 'event_espresso'),
57
+				null,
58
+				[$this, 'getEventRelationalData'],
59
+				[],
60
+				[
61
+					'eventId' => [
62
+						'type'        => ['non_null' => 'Int'],
63
+						'description' => esc_html__('The event ID to get the relational data for.', 'event_espresso'),
64
+					],
65
+				]
66
+			),
67
+			new GraphQLOutputField(
68
+				lcfirst($this->namespace) . 'Datetime',
69
+				$this->namespace . 'Datetime',
70
+				null,
71
+				esc_html__('A datetime', 'event_espresso'),
72
+				null,
73
+				[$this, 'getDatetime'],
74
+				[],
75
+				[
76
+					'id' => [
77
+						'type'        => [
78
+							'non_null' => 'ID',
79
+						],
80
+						'description' => esc_html__('The globally unique identifier of the datetime.', 'event_espresso'),
81
+					],
82
+				]
83
+			),
84
+			new GraphQLOutputField(
85
+				lcfirst($this->namespace) . 'Ticket',
86
+				$this->namespace . 'Ticket',
87
+				null,
88
+				esc_html__('A ticket', 'event_espresso'),
89
+				null,
90
+				[$this, 'getTicket'],
91
+				[],
92
+				[
93
+					'id' => [
94
+						'type'        => [
95
+							'non_null' => 'ID',
96
+						],
97
+						'description' => esc_html__('The globally unique identifier of the ticket.', 'event_espresso'),
98
+					],
99
+				]
100
+			),
101
+		];
102
+	}
103
+
104
+
105
+	/**
106
+	 * @param mixed       $source  The source that's passed down the GraphQL queries
107
+	 * @param array       $args    The inputArgs on the field
108
+	 * @param AppContext  $context The AppContext passed down the GraphQL tree
109
+	 * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
110
+	 * @return string
111
+	 * @throws Exception
112
+	 * @throws InvalidArgumentException
113
+	 * @throws InvalidDataTypeException
114
+	 * @throws InvalidInterfaceException
115
+	 * @throws UserError
116
+	 * @throws UnexpectedEntityException
117
+	 * @since $VID:$
118
+	 */
119
+	public function getEventRelationalData($source, array $args, AppContext $context, ResolveInfo $info): string
120
+	{
121
+		/**
122
+		 * Throw an exception if there's no event ID
123
+		 */
124
+		if (empty($args['eventId']) || ! absint($args['eventId'])) {
125
+			throw new UserError(esc_html__(
126
+				'No event ID was provided to get the relational data for',
127
+				'event_espresso'
128
+			));
129
+		}
130
+
131
+		$eventId = absint($args['eventId']);
132
+		/** @var EventEntityRelations $event_entity_relations */
133
+		$event_entity_relations = LoaderFactory::getLoader()->getShared(
134
+			'EventEspresso\core\domain\services\admin\events\editor\EventEntityRelations'
135
+		);
136
+		return json_encode($event_entity_relations->getData($eventId));
137
+	}
138
+
139
+
140
+	/**
141
+	 * @param mixed       $source  The source that's passed down the GraphQL queries
142
+	 * @param array       $args    The inputArgs on the field
143
+	 * @param AppContext  $context The AppContext passed down the GraphQL tree
144
+	 * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
145
+	 * @return string
146
+	 * @throws Exception
147
+	 * @throws InvalidArgumentException
148
+	 * @throws InvalidDataTypeException
149
+	 * @throws InvalidInterfaceException
150
+	 * @throws UserError
151
+	 * @throws UnexpectedEntityException
152
+	 * @since $VID:$
153
+	 */
154
+	public function getDatetime($source, array $args, AppContext $context, ResolveInfo $info): EE_Datetime
155
+	{
156
+		$parts = Relay::fromGlobalId(sanitize_text_field($args['id']));
157
+
158
+		/**
159
+		 * Throw an exception if there's no ID
160
+		 */
161
+		if (empty($parts['id'])) {
162
+			throw new UserError(esc_html__(
163
+				'A missing or invalid ID was received.',
164
+				'event_espresso'
165
+			));
166
+		}
167
+
168
+		return EEM_Datetime::instance()->get_one_by_ID(absint($parts['id']));
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param mixed       $source  The source that's passed down the GraphQL queries
174
+	 * @param array       $args    The inputArgs on the field
175
+	 * @param AppContext  $context The AppContext passed down the GraphQL tree
176
+	 * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
177
+	 * @return string
178
+	 * @throws Exception
179
+	 * @throws InvalidArgumentException
180
+	 * @throws InvalidDataTypeException
181
+	 * @throws InvalidInterfaceException
182
+	 * @throws UserError
183
+	 * @throws UnexpectedEntityException
184
+	 * @since $VID:$
185
+	 */
186
+	public function getTicket($source, array $args, AppContext $context, ResolveInfo $info): EE_Ticket
187
+	{
188
+		$parts = Relay::fromGlobalId(sanitize_text_field($args['id']));
189
+
190
+		/**
191
+		 * Throw an exception if there's no ID
192
+		 */
193
+		if (empty($parts['id'])) {
194
+			throw new UserError(esc_html__(
195
+				'A missing or invalid ID was received.',
196
+				'event_espresso'
197
+			));
198
+		}
199
+
200
+		return EEM_Ticket::instance()->get_one_by_ID(absint($parts['id']));
201
+	}
202 202
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
     {
51 51
         return [
52 52
             new GraphQLOutputField(
53
-                lcfirst($this->namespace) . 'EventRelations',
53
+                lcfirst($this->namespace).'EventRelations',
54 54
                 'String',
55 55
                 null,
56 56
                 esc_html__('JSON encoded relational data of the models', 'event_espresso'),
@@ -65,8 +65,8 @@  discard block
 block discarded – undo
65 65
                 ]
66 66
             ),
67 67
             new GraphQLOutputField(
68
-                lcfirst($this->namespace) . 'Datetime',
69
-                $this->namespace . 'Datetime',
68
+                lcfirst($this->namespace).'Datetime',
69
+                $this->namespace.'Datetime',
70 70
                 null,
71 71
                 esc_html__('A datetime', 'event_espresso'),
72 72
                 null,
@@ -82,8 +82,8 @@  discard block
 block discarded – undo
82 82
                 ]
83 83
             ),
84 84
             new GraphQLOutputField(
85
-                lcfirst($this->namespace) . 'Ticket',
86
-                $this->namespace . 'Ticket',
85
+                lcfirst($this->namespace).'Ticket',
86
+                $this->namespace.'Ticket',
87 87
                 null,
88 88
                 esc_html__('A ticket', 'event_espresso'),
89 89
                 null,
Please login to merge, or discard this patch.