Completed
Branch BUG-10604-archived-ticket-sold... (47d5bb)
by
unknown
45:27 queued 34:06
created
core/db_classes/EE_Event.class.php 1 patch
Indentation   +1277 added lines, -1277 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -14,1369 +14,1369 @@  discard block
 block discarded – undo
14 14
 class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event
15 15
 {
16 16
 
17
-    /**
18
-     * cached value for the the logical active status for the event
19
-     *
20
-     * @see get_active_status()
21
-     * @var string
22
-     */
23
-    protected $_active_status = '';
24
-
25
-    /**
26
-     * This is just used for caching the Primary Datetime for the Event on initial retrieval
27
-     *
28
-     * @var EE_Datetime
29
-     */
30
-    protected $_Primary_Datetime;
31
-
32
-
33
-
34
-    /**
35
-     * @param array  $props_n_values          incoming values
36
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
37
-     *                                        used.)
38
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
39
-     *                                        date_format and the second value is the time format
40
-     * @return EE_Event
41
-     */
42
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
43
-    {
44
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
45
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
46
-    }
47
-
48
-
49
-
50
-    /**
51
-     * @param array  $props_n_values  incoming values from the database
52
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
53
-     *                                the website will be used.
54
-     * @return EE_Event
55
-     */
56
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
57
-    {
58
-        return new self($props_n_values, true, $timezone);
59
-    }
60
-
61
-
62
-
63
-    /**
64
-     * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
65
-     *
66
-     * @param string $field_name
67
-     * @param mixed  $field_value
68
-     * @param bool   $use_default
69
-     */
70
-    public function set($field_name, $field_value, $use_default = false)
71
-    {
72
-        switch ($field_name) {
73
-            case 'status' :
74
-                $this->set_status($field_value, $use_default);
75
-                break;
76
-            default :
77
-                parent::set($field_name, $field_value, $use_default);
78
-        }
79
-    }
80
-
81
-
82
-
83
-    /**
84
-     *    set_status
85
-     * Checks if event status is being changed to SOLD OUT
86
-     * and updates event meta data with previous event status
87
-     * so that we can revert things if/when the event is no longer sold out
88
-     *
89
-     * @access public
90
-     * @param string $new_status
91
-     * @param bool   $use_default
92
-     * @return bool|void
93
-     * @throws \EE_Error
94
-     */
95
-    public function set_status($new_status = null, $use_default = false)
96
-    {
97
-        // get current Event status
98
-        $old_status = $this->status();
99
-        // if status has changed
100
-        if ($old_status != $new_status) {
101
-            // TO sold_out
102
-            if ($new_status == EEM_Event::sold_out) {
103
-                // save the previous event status so that we can revert if the event is no longer sold out
104
-                $this->add_post_meta('_previous_event_status', $old_status);
105
-                do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
106
-                // OR FROM  sold_out
107
-            } else if ($old_status == EEM_Event::sold_out) {
108
-                $this->delete_post_meta('_previous_event_status');
109
-                do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
110
-            }
111
-            // update status
112
-            parent::set('status', $new_status, $use_default);
113
-            do_action('AHEE__EE_Event__set_status__after_update', $this);
114
-            return true;
115
-        } else {
116
-            // even though the old value matches the new value, it's still good to
117
-            // allow the parent set method to have a say
118
-            parent::set('status', $new_status, $use_default);
119
-            return true;
120
-        }
121
-    }
122
-
123
-
124
-
125
-    /**
126
-     * Gets all the datetimes for this event
127
-     *
128
-     * @param array $query_params like EEM_Base::get_all
129
-     * @return EE_Datetime[]
130
-     */
131
-    public function datetimes($query_params = array())
132
-    {
133
-        return $this->get_many_related('Datetime', $query_params);
134
-    }
135
-
136
-
137
-
138
-    /**
139
-     * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
140
-     *
141
-     * @return EE_Datetime[]
142
-     */
143
-    public function datetimes_in_chronological_order()
144
-    {
145
-        return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
146
-    }
147
-
148
-
149
-
150
-    /**
151
-     * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
152
-     * @darren, we should probably UNSET timezone on the EEM_Datetime model
153
-     * after running our query, so that this timezone isn't set for EVERY query
154
-     * on EEM_Datetime for the rest of the request, no?
155
-     *
156
-     * @param boolean $show_expired whether or not to include expired events
157
-     * @param boolean $show_deleted whether or not to include deleted events
158
-     * @param null    $limit
159
-     * @return \EE_Datetime[]
160
-     * @throws \EE_Error
161
-     */
162
-    public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
163
-    {
164
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
165
-            $this->ID(),
166
-            $show_expired,
167
-            $show_deleted,
168
-            $limit
169
-        );
170
-    }
171
-
172
-
173
-
174
-    /**
175
-     * Returns one related datetime. Mostly only used by some legacy code.
176
-     *
177
-     * @return EE_Datetime
178
-     */
179
-    public function first_datetime()
180
-    {
181
-        return $this->get_first_related('Datetime');
182
-    }
183
-
184
-
185
-
186
-    /**
187
-     * Returns the 'primary' datetime for the event
188
-     *
189
-     * @param bool $try_to_exclude_expired
190
-     * @param bool $try_to_exclude_deleted
191
-     * @return EE_Datetime
192
-     */
193
-    public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
194
-    {
195
-        if ( ! empty ($this->_Primary_Datetime)) {
196
-            return $this->_Primary_Datetime;
197
-        }
198
-        $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)
199
-                                               ->get_primary_datetime_for_event($this->ID(), $try_to_exclude_expired,
200
-                                                   $try_to_exclude_deleted);
201
-        return $this->_Primary_Datetime;
202
-    }
203
-
204
-
205
-
206
-    /**
207
-     * Gets all the tickets available for purchase of this event
208
-     *
209
-     * @param array $query_params like EEM_Base::get_all
210
-     * @return EE_Ticket[]
211
-     */
212
-    public function tickets($query_params = array())
213
-    {
214
-        //first get all datetimes
215
-        $datetimes = $this->datetimes_ordered();
216
-        if ( ! $datetimes) {
217
-            return array();
218
-        }
219
-        $datetime_ids = array();
220
-        foreach ($datetimes as $datetime) {
221
-            $datetime_ids[] = $datetime->ID();
222
-        }
223
-        $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
224
-        //if incoming $query_params has where conditions let's merge but not override existing.
225
-        if (is_array($query_params) && isset($query_params[0])) {
226
-            $where_params = array_merge($query_params[0], $where_params);
227
-            unset($query_params[0]);
228
-        }
229
-        //now add $where_params to $query_params
230
-        $query_params[0] = $where_params;
231
-        return EEM_Ticket::instance()->get_all($query_params);
232
-    }
233
-
234
-
235
-
236
-    /**
237
-     * @return bool
238
-     */
239
-    public function additional_limit()
240
-    {
241
-        return $this->get('EVT_additional_limit');
242
-    }
243
-
244
-
245
-
246
-    /**
247
-     * @return bool
248
-     */
249
-    public function allow_overflow()
250
-    {
251
-        return $this->get('EVT_allow_overflow');
252
-    }
253
-
254
-
255
-
256
-    /**
257
-     * @return bool
258
-     */
259
-    public function created()
260
-    {
261
-        return $this->get('EVT_created');
262
-    }
263
-
264
-
265
-
266
-    /**
267
-     * @return bool
268
-     */
269
-    public function description()
270
-    {
271
-        return $this->get('EVT_desc');
272
-    }
273
-
274
-
275
-
276
-    /**
277
-     * Runs do_shortcode and wpautop on the description
278
-     *
279
-     * @return string of html
280
-     */
281
-    public function description_filtered()
282
-    {
283
-        return $this->get_pretty('EVT_desc');
284
-    }
285
-
286
-
287
-
288
-    /**
289
-     * @return bool
290
-     */
291
-    public function display_description()
292
-    {
293
-        return $this->get('EVT_display_desc');
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     * @return bool
300
-     */
301
-    public function display_ticket_selector()
302
-    {
303
-        return (bool)$this->get('EVT_display_ticket_selector');
304
-    }
305
-
17
+	/**
18
+	 * cached value for the the logical active status for the event
19
+	 *
20
+	 * @see get_active_status()
21
+	 * @var string
22
+	 */
23
+	protected $_active_status = '';
24
+
25
+	/**
26
+	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
27
+	 *
28
+	 * @var EE_Datetime
29
+	 */
30
+	protected $_Primary_Datetime;
31
+
32
+
33
+
34
+	/**
35
+	 * @param array  $props_n_values          incoming values
36
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
37
+	 *                                        used.)
38
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
39
+	 *                                        date_format and the second value is the time format
40
+	 * @return EE_Event
41
+	 */
42
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
43
+	{
44
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
45
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
46
+	}
47
+
48
+
49
+
50
+	/**
51
+	 * @param array  $props_n_values  incoming values from the database
52
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
53
+	 *                                the website will be used.
54
+	 * @return EE_Event
55
+	 */
56
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
57
+	{
58
+		return new self($props_n_values, true, $timezone);
59
+	}
60
+
61
+
62
+
63
+	/**
64
+	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
65
+	 *
66
+	 * @param string $field_name
67
+	 * @param mixed  $field_value
68
+	 * @param bool   $use_default
69
+	 */
70
+	public function set($field_name, $field_value, $use_default = false)
71
+	{
72
+		switch ($field_name) {
73
+			case 'status' :
74
+				$this->set_status($field_value, $use_default);
75
+				break;
76
+			default :
77
+				parent::set($field_name, $field_value, $use_default);
78
+		}
79
+	}
80
+
81
+
82
+
83
+	/**
84
+	 *    set_status
85
+	 * Checks if event status is being changed to SOLD OUT
86
+	 * and updates event meta data with previous event status
87
+	 * so that we can revert things if/when the event is no longer sold out
88
+	 *
89
+	 * @access public
90
+	 * @param string $new_status
91
+	 * @param bool   $use_default
92
+	 * @return bool|void
93
+	 * @throws \EE_Error
94
+	 */
95
+	public function set_status($new_status = null, $use_default = false)
96
+	{
97
+		// get current Event status
98
+		$old_status = $this->status();
99
+		// if status has changed
100
+		if ($old_status != $new_status) {
101
+			// TO sold_out
102
+			if ($new_status == EEM_Event::sold_out) {
103
+				// save the previous event status so that we can revert if the event is no longer sold out
104
+				$this->add_post_meta('_previous_event_status', $old_status);
105
+				do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
106
+				// OR FROM  sold_out
107
+			} else if ($old_status == EEM_Event::sold_out) {
108
+				$this->delete_post_meta('_previous_event_status');
109
+				do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
110
+			}
111
+			// update status
112
+			parent::set('status', $new_status, $use_default);
113
+			do_action('AHEE__EE_Event__set_status__after_update', $this);
114
+			return true;
115
+		} else {
116
+			// even though the old value matches the new value, it's still good to
117
+			// allow the parent set method to have a say
118
+			parent::set('status', $new_status, $use_default);
119
+			return true;
120
+		}
121
+	}
122
+
123
+
124
+
125
+	/**
126
+	 * Gets all the datetimes for this event
127
+	 *
128
+	 * @param array $query_params like EEM_Base::get_all
129
+	 * @return EE_Datetime[]
130
+	 */
131
+	public function datetimes($query_params = array())
132
+	{
133
+		return $this->get_many_related('Datetime', $query_params);
134
+	}
135
+
136
+
137
+
138
+	/**
139
+	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
140
+	 *
141
+	 * @return EE_Datetime[]
142
+	 */
143
+	public function datetimes_in_chronological_order()
144
+	{
145
+		return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
146
+	}
147
+
148
+
149
+
150
+	/**
151
+	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
152
+	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
153
+	 * after running our query, so that this timezone isn't set for EVERY query
154
+	 * on EEM_Datetime for the rest of the request, no?
155
+	 *
156
+	 * @param boolean $show_expired whether or not to include expired events
157
+	 * @param boolean $show_deleted whether or not to include deleted events
158
+	 * @param null    $limit
159
+	 * @return \EE_Datetime[]
160
+	 * @throws \EE_Error
161
+	 */
162
+	public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
163
+	{
164
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
165
+			$this->ID(),
166
+			$show_expired,
167
+			$show_deleted,
168
+			$limit
169
+		);
170
+	}
171
+
172
+
173
+
174
+	/**
175
+	 * Returns one related datetime. Mostly only used by some legacy code.
176
+	 *
177
+	 * @return EE_Datetime
178
+	 */
179
+	public function first_datetime()
180
+	{
181
+		return $this->get_first_related('Datetime');
182
+	}
183
+
184
+
185
+
186
+	/**
187
+	 * Returns the 'primary' datetime for the event
188
+	 *
189
+	 * @param bool $try_to_exclude_expired
190
+	 * @param bool $try_to_exclude_deleted
191
+	 * @return EE_Datetime
192
+	 */
193
+	public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
194
+	{
195
+		if ( ! empty ($this->_Primary_Datetime)) {
196
+			return $this->_Primary_Datetime;
197
+		}
198
+		$this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)
199
+											   ->get_primary_datetime_for_event($this->ID(), $try_to_exclude_expired,
200
+												   $try_to_exclude_deleted);
201
+		return $this->_Primary_Datetime;
202
+	}
203
+
204
+
205
+
206
+	/**
207
+	 * Gets all the tickets available for purchase of this event
208
+	 *
209
+	 * @param array $query_params like EEM_Base::get_all
210
+	 * @return EE_Ticket[]
211
+	 */
212
+	public function tickets($query_params = array())
213
+	{
214
+		//first get all datetimes
215
+		$datetimes = $this->datetimes_ordered();
216
+		if ( ! $datetimes) {
217
+			return array();
218
+		}
219
+		$datetime_ids = array();
220
+		foreach ($datetimes as $datetime) {
221
+			$datetime_ids[] = $datetime->ID();
222
+		}
223
+		$where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
224
+		//if incoming $query_params has where conditions let's merge but not override existing.
225
+		if (is_array($query_params) && isset($query_params[0])) {
226
+			$where_params = array_merge($query_params[0], $where_params);
227
+			unset($query_params[0]);
228
+		}
229
+		//now add $where_params to $query_params
230
+		$query_params[0] = $where_params;
231
+		return EEM_Ticket::instance()->get_all($query_params);
232
+	}
233
+
234
+
235
+
236
+	/**
237
+	 * @return bool
238
+	 */
239
+	public function additional_limit()
240
+	{
241
+		return $this->get('EVT_additional_limit');
242
+	}
243
+
244
+
245
+
246
+	/**
247
+	 * @return bool
248
+	 */
249
+	public function allow_overflow()
250
+	{
251
+		return $this->get('EVT_allow_overflow');
252
+	}
253
+
254
+
255
+
256
+	/**
257
+	 * @return bool
258
+	 */
259
+	public function created()
260
+	{
261
+		return $this->get('EVT_created');
262
+	}
263
+
264
+
265
+
266
+	/**
267
+	 * @return bool
268
+	 */
269
+	public function description()
270
+	{
271
+		return $this->get('EVT_desc');
272
+	}
273
+
274
+
275
+
276
+	/**
277
+	 * Runs do_shortcode and wpautop on the description
278
+	 *
279
+	 * @return string of html
280
+	 */
281
+	public function description_filtered()
282
+	{
283
+		return $this->get_pretty('EVT_desc');
284
+	}
285
+
286
+
287
+
288
+	/**
289
+	 * @return bool
290
+	 */
291
+	public function display_description()
292
+	{
293
+		return $this->get('EVT_display_desc');
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 * @return bool
300
+	 */
301
+	public function display_ticket_selector()
302
+	{
303
+		return (bool)$this->get('EVT_display_ticket_selector');
304
+	}
305
+
306 306
 
307 307
 
308
-    /**
309
-     * @return bool
310
-     */
311
-    public function external_url()
312
-    {
313
-        return $this->get('EVT_external_URL');
314
-    }
308
+	/**
309
+	 * @return bool
310
+	 */
311
+	public function external_url()
312
+	{
313
+		return $this->get('EVT_external_URL');
314
+	}
315 315
 
316 316
 
317 317
 
318
-    /**
319
-     * @return bool
320
-     */
321
-    public function member_only()
322
-    {
323
-        return $this->get('EVT_member_only');
324
-    }
318
+	/**
319
+	 * @return bool
320
+	 */
321
+	public function member_only()
322
+	{
323
+		return $this->get('EVT_member_only');
324
+	}
325 325
 
326 326
 
327 327
 
328
-    /**
329
-     * @return bool
330
-     */
331
-    public function phone()
332
-    {
333
-        return $this->get('EVT_phone');
334
-    }
328
+	/**
329
+	 * @return bool
330
+	 */
331
+	public function phone()
332
+	{
333
+		return $this->get('EVT_phone');
334
+	}
335 335
 
336 336
 
337 337
 
338
-    /**
339
-     * @return bool
340
-     */
341
-    public function modified()
342
-    {
343
-        return $this->get('EVT_modified');
344
-    }
338
+	/**
339
+	 * @return bool
340
+	 */
341
+	public function modified()
342
+	{
343
+		return $this->get('EVT_modified');
344
+	}
345 345
 
346 346
 
347 347
 
348
-    /**
349
-     * @return bool
350
-     */
351
-    public function name()
352
-    {
353
-        return $this->get('EVT_name');
354
-    }
348
+	/**
349
+	 * @return bool
350
+	 */
351
+	public function name()
352
+	{
353
+		return $this->get('EVT_name');
354
+	}
355 355
 
356 356
 
357 357
 
358
-    /**
359
-     * @return bool
360
-     */
361
-    public function order()
362
-    {
363
-        return $this->get('EVT_order');
364
-    }
358
+	/**
359
+	 * @return bool
360
+	 */
361
+	public function order()
362
+	{
363
+		return $this->get('EVT_order');
364
+	}
365 365
 
366 366
 
367 367
 
368
-    /**
369
-     * @return bool|string
370
-     */
371
-    public function default_registration_status()
372
-    {
373
-        $event_default_registration_status = $this->get('EVT_default_registration_status');
374
-        return ! empty($event_default_registration_status) ? $event_default_registration_status
375
-            : EE_Registry::instance()->CFG->registration->default_STS_ID;
376
-    }
368
+	/**
369
+	 * @return bool|string
370
+	 */
371
+	public function default_registration_status()
372
+	{
373
+		$event_default_registration_status = $this->get('EVT_default_registration_status');
374
+		return ! empty($event_default_registration_status) ? $event_default_registration_status
375
+			: EE_Registry::instance()->CFG->registration->default_STS_ID;
376
+	}
377 377
 
378 378
 
379 379
 
380
-    /**
381
-     * @param int  $num_words
382
-     * @param null $more
383
-     * @param bool $not_full_desc
384
-     * @return bool|string
385
-     */
386
-    public function short_description($num_words = 55, $more = null, $not_full_desc = false)
387
-    {
388
-        $short_desc = $this->get('EVT_short_desc');
389
-        if ( ! empty($short_desc) || $not_full_desc) {
390
-            return $short_desc;
391
-        } else {
392
-            $full_desc = $this->get('EVT_desc');
393
-            return wp_trim_words($full_desc, $num_words, $more);
394
-        }
395
-    }
380
+	/**
381
+	 * @param int  $num_words
382
+	 * @param null $more
383
+	 * @param bool $not_full_desc
384
+	 * @return bool|string
385
+	 */
386
+	public function short_description($num_words = 55, $more = null, $not_full_desc = false)
387
+	{
388
+		$short_desc = $this->get('EVT_short_desc');
389
+		if ( ! empty($short_desc) || $not_full_desc) {
390
+			return $short_desc;
391
+		} else {
392
+			$full_desc = $this->get('EVT_desc');
393
+			return wp_trim_words($full_desc, $num_words, $more);
394
+		}
395
+	}
396 396
 
397 397
 
398 398
 
399
-    /**
400
-     * @return bool
401
-     */
402
-    public function slug()
403
-    {
404
-        return $this->get('EVT_slug');
405
-    }
399
+	/**
400
+	 * @return bool
401
+	 */
402
+	public function slug()
403
+	{
404
+		return $this->get('EVT_slug');
405
+	}
406 406
 
407 407
 
408 408
 
409
-    /**
410
-     * @return bool
411
-     */
412
-    public function timezone_string()
413
-    {
414
-        return $this->get('EVT_timezone_string');
415
-    }
409
+	/**
410
+	 * @return bool
411
+	 */
412
+	public function timezone_string()
413
+	{
414
+		return $this->get('EVT_timezone_string');
415
+	}
416 416
 
417 417
 
418 418
 
419
-    /**
420
-     * @return bool
421
-     */
422
-    public function visible_on()
423
-    {
424
-        return $this->get('EVT_visible_on');
425
-    }
419
+	/**
420
+	 * @return bool
421
+	 */
422
+	public function visible_on()
423
+	{
424
+		return $this->get('EVT_visible_on');
425
+	}
426 426
 
427 427
 
428 428
 
429
-    /**
430
-     * @return int
431
-     */
432
-    public function wp_user()
433
-    {
434
-        return $this->get('EVT_wp_user');
435
-    }
429
+	/**
430
+	 * @return int
431
+	 */
432
+	public function wp_user()
433
+	{
434
+		return $this->get('EVT_wp_user');
435
+	}
436 436
 
437 437
 
438 438
 
439
-    /**
440
-     * @return bool
441
-     */
442
-    public function donations()
443
-    {
444
-        return $this->get('EVT_donations');
445
-    }
439
+	/**
440
+	 * @return bool
441
+	 */
442
+	public function donations()
443
+	{
444
+		return $this->get('EVT_donations');
445
+	}
446 446
 
447 447
 
448 448
 
449
-    /**
450
-     * @param $limit
451
-     */
452
-    public function set_additional_limit($limit)
453
-    {
454
-        $this->set('EVT_additional_limit', $limit);
455
-    }
449
+	/**
450
+	 * @param $limit
451
+	 */
452
+	public function set_additional_limit($limit)
453
+	{
454
+		$this->set('EVT_additional_limit', $limit);
455
+	}
456 456
 
457 457
 
458 458
 
459
-    /**
460
-     * @param $created
461
-     */
462
-    public function set_created($created)
463
-    {
464
-        $this->set('EVT_created', $created);
465
-    }
459
+	/**
460
+	 * @param $created
461
+	 */
462
+	public function set_created($created)
463
+	{
464
+		$this->set('EVT_created', $created);
465
+	}
466 466
 
467 467
 
468 468
 
469
-    /**
470
-     * @param $desc
471
-     */
472
-    public function set_description($desc)
473
-    {
474
-        $this->set('EVT_desc', $desc);
475
-    }
469
+	/**
470
+	 * @param $desc
471
+	 */
472
+	public function set_description($desc)
473
+	{
474
+		$this->set('EVT_desc', $desc);
475
+	}
476 476
 
477 477
 
478 478
 
479
-    /**
480
-     * @param $display_desc
481
-     */
482
-    public function set_display_description($display_desc)
483
-    {
484
-        $this->set('EVT_display_desc', $display_desc);
485
-    }
479
+	/**
480
+	 * @param $display_desc
481
+	 */
482
+	public function set_display_description($display_desc)
483
+	{
484
+		$this->set('EVT_display_desc', $display_desc);
485
+	}
486 486
 
487 487
 
488 488
 
489
-    /**
490
-     * @param $display_ticket_selector
491
-     */
492
-    public function set_display_ticket_selector($display_ticket_selector)
493
-    {
494
-        $this->set('EVT_display_ticket_selector', $display_ticket_selector);
495
-    }
489
+	/**
490
+	 * @param $display_ticket_selector
491
+	 */
492
+	public function set_display_ticket_selector($display_ticket_selector)
493
+	{
494
+		$this->set('EVT_display_ticket_selector', $display_ticket_selector);
495
+	}
496 496
 
497 497
 
498 498
 
499
-    /**
500
-     * @param $external_url
501
-     */
502
-    public function set_external_url($external_url)
503
-    {
504
-        $this->set('EVT_external_URL', $external_url);
505
-    }
499
+	/**
500
+	 * @param $external_url
501
+	 */
502
+	public function set_external_url($external_url)
503
+	{
504
+		$this->set('EVT_external_URL', $external_url);
505
+	}
506 506
 
507 507
 
508 508
 
509
-    /**
510
-     * @param $member_only
511
-     */
512
-    public function set_member_only($member_only)
513
-    {
514
-        $this->set('EVT_member_only', $member_only);
515
-    }
509
+	/**
510
+	 * @param $member_only
511
+	 */
512
+	public function set_member_only($member_only)
513
+	{
514
+		$this->set('EVT_member_only', $member_only);
515
+	}
516 516
 
517 517
 
518 518
 
519
-    /**
520
-     * @param $event_phone
521
-     */
522
-    public function set_event_phone($event_phone)
523
-    {
524
-        $this->set('EVT_phone', $event_phone);
525
-    }
519
+	/**
520
+	 * @param $event_phone
521
+	 */
522
+	public function set_event_phone($event_phone)
523
+	{
524
+		$this->set('EVT_phone', $event_phone);
525
+	}
526 526
 
527 527
 
528 528
 
529
-    /**
530
-     * @param $modified
531
-     */
532
-    public function set_modified($modified)
533
-    {
534
-        $this->set('EVT_modified', $modified);
535
-    }
529
+	/**
530
+	 * @param $modified
531
+	 */
532
+	public function set_modified($modified)
533
+	{
534
+		$this->set('EVT_modified', $modified);
535
+	}
536 536
 
537 537
 
538 538
 
539
-    /**
540
-     * @param $name
541
-     */
542
-    public function set_name($name)
543
-    {
544
-        $this->set('EVT_name', $name);
545
-    }
539
+	/**
540
+	 * @param $name
541
+	 */
542
+	public function set_name($name)
543
+	{
544
+		$this->set('EVT_name', $name);
545
+	}
546 546
 
547 547
 
548 548
 
549
-    /**
550
-     * @param $order
551
-     */
552
-    public function set_order($order)
553
-    {
554
-        $this->set('EVT_order', $order);
555
-    }
549
+	/**
550
+	 * @param $order
551
+	 */
552
+	public function set_order($order)
553
+	{
554
+		$this->set('EVT_order', $order);
555
+	}
556 556
 
557 557
 
558 558
 
559
-    /**
560
-     * @param $short_desc
561
-     */
562
-    public function set_short_description($short_desc)
563
-    {
564
-        $this->set('EVT_short_desc', $short_desc);
565
-    }
559
+	/**
560
+	 * @param $short_desc
561
+	 */
562
+	public function set_short_description($short_desc)
563
+	{
564
+		$this->set('EVT_short_desc', $short_desc);
565
+	}
566 566
 
567 567
 
568 568
 
569
-    /**
570
-     * @param $slug
571
-     */
572
-    public function set_slug($slug)
573
-    {
574
-        $this->set('EVT_slug', $slug);
575
-    }
569
+	/**
570
+	 * @param $slug
571
+	 */
572
+	public function set_slug($slug)
573
+	{
574
+		$this->set('EVT_slug', $slug);
575
+	}
576 576
 
577 577
 
578 578
 
579
-    /**
580
-     * @param $timezone_string
581
-     */
582
-    public function set_timezone_string($timezone_string)
583
-    {
584
-        $this->set('EVT_timezone_string', $timezone_string);
585
-    }
579
+	/**
580
+	 * @param $timezone_string
581
+	 */
582
+	public function set_timezone_string($timezone_string)
583
+	{
584
+		$this->set('EVT_timezone_string', $timezone_string);
585
+	}
586 586
 
587 587
 
588 588
 
589
-    /**
590
-     * @param $visible_on
591
-     */
592
-    public function set_visible_on($visible_on)
593
-    {
594
-        $this->set('EVT_visible_on', $visible_on);
595
-    }
589
+	/**
590
+	 * @param $visible_on
591
+	 */
592
+	public function set_visible_on($visible_on)
593
+	{
594
+		$this->set('EVT_visible_on', $visible_on);
595
+	}
596 596
 
597 597
 
598 598
 
599
-    /**
600
-     * @param $wp_user
601
-     */
602
-    public function set_wp_user($wp_user)
603
-    {
604
-        $this->set('EVT_wp_user', $wp_user);
605
-    }
599
+	/**
600
+	 * @param $wp_user
601
+	 */
602
+	public function set_wp_user($wp_user)
603
+	{
604
+		$this->set('EVT_wp_user', $wp_user);
605
+	}
606 606
 
607 607
 
608
-
609
-    /**
610
-     * @param $default_registration_status
611
-     */
612
-    public function set_default_registration_status($default_registration_status)
613
-    {
614
-        $this->set('EVT_default_registration_status', $default_registration_status);
615
-    }
616
-
617
-
618
-
619
-    /**
620
-     * @param $donations
621
-     */
622
-    public function set_donations($donations)
623
-    {
624
-        $this->set('EVT_donations', $donations);
625
-    }
626
-
627
-
628
-
629
-    /**
630
-     * Adds a venue to this event
631
-     *
632
-     * @param EE_Venue /int $venue_id_or_obj
633
-     * @return EE_Venue
634
-     */
635
-    public function add_venue($venue_id_or_obj)
636
-    {
637
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
638
-    }
639
-
640
-
641
-
642
-    /**
643
-     * Removes a venue from the event
644
-     *
645
-     * @param EE_Venue /int $venue_id_or_obj
646
-     * @return EE_Venue
647
-     */
648
-    public function remove_venue($venue_id_or_obj)
649
-    {
650
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
651
-    }
652
-
653
-
654
-
655
-    /**
656
-     * Gets all the venues related ot the event. May provide additional $query_params if desired
657
-     *
658
-     * @param array $query_params like EEM_Base::get_all's $query_params
659
-     * @return EE_Venue[]
660
-     */
661
-    public function venues($query_params = array())
662
-    {
663
-        return $this->get_many_related('Venue', $query_params);
664
-    }
665
-
666
-
667
-
668
-    /**
669
-     * check if event id is present and if event is published
670
-     *
671
-     * @access public
672
-     * @return boolean true yes, false no
673
-     */
674
-    private function _has_ID_and_is_published()
675
-    {
676
-        // first check if event id is present and not NULL, then check if this event is published (or any of the equivalent "published" statuses)
677
-        return ($this->ID() && $this->ID() !== null
678
-                && ($this->status() == 'publish'
679
-                    || $this->status()
680
-                       == EEM_Event::sold_out
681
-                    || $this->status() == EEM_Event::postponed
682
-                    || $this->status() == EEM_Event::cancelled)) ? true : false;
683
-    }
684
-
685
-
686
-
687
-    /**
688
-     * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
689
-     *
690
-     * @access public
691
-     * @return boolean true yes, false no
692
-     */
693
-    public function is_upcoming()
694
-    {
695
-        // check if event id is present and if this event is published
696
-        if ($this->is_inactive()) {
697
-            return false;
698
-        }
699
-        // set initial value
700
-        $upcoming = false;
701
-        //next let's get all datetimes and loop through them
702
-        $datetimes = $this->datetimes_in_chronological_order();
703
-        foreach ($datetimes as $datetime) {
704
-            if ($datetime instanceof EE_Datetime) {
705
-                //if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
706
-                if ($datetime->is_expired()) {
707
-                    continue;
708
-                }
709
-                //if this dtt is active then we return false.
710
-                if ($datetime->is_active()) {
711
-                    return false;
712
-                }
713
-                //otherwise let's check upcoming status
714
-                $upcoming = $datetime->is_upcoming();
715
-            }
716
-        }
717
-        return $upcoming;
718
-    }
719
-
720
-
721
-
722
-    /**
723
-     * @return bool
724
-     */
725
-    public function is_active()
726
-    {
727
-        // check if event id is present and if this event is published
728
-        if ($this->is_inactive()) {
729
-            return false;
730
-        }
731
-        // set initial value
732
-        $active = false;
733
-        //next let's get all datetimes and loop through them
734
-        $datetimes = $this->datetimes_in_chronological_order();
735
-        foreach ($datetimes as $datetime) {
736
-            if ($datetime instanceof EE_Datetime) {
737
-                //if this dtt is expired then we continue cause one of the other datetimes might be active.
738
-                if ($datetime->is_expired()) {
739
-                    continue;
740
-                }
741
-                //if this dtt is upcoming then we return false.
742
-                if ($datetime->is_upcoming()) {
743
-                    return false;
744
-                }
745
-                //otherwise let's check active status
746
-                $active = $datetime->is_active();
747
-            }
748
-        }
749
-        return $active;
750
-    }
751
-
752
-
753
-
754
-    /**
755
-     * @return bool
756
-     */
757
-    public function is_expired()
758
-    {
759
-        // check if event id is present and if this event is published
760
-        if ($this->is_inactive()) {
761
-            return false;
762
-        }
763
-        // set initial value
764
-        $expired = false;
765
-        //first let's get all datetimes and loop through them
766
-        $datetimes = $this->datetimes_in_chronological_order();
767
-        foreach ($datetimes as $datetime) {
768
-            if ($datetime instanceof EE_Datetime) {
769
-                //if this dtt is upcoming or active then we return false.
770
-                if ($datetime->is_upcoming() || $datetime->is_active()) {
771
-                    return false;
772
-                }
773
-                //otherwise let's check active status
774
-                $expired = $datetime->is_expired();
775
-            }
776
-        }
777
-        return $expired;
778
-    }
779
-
780
-
781
-
782
-    /**
783
-     * @return bool
784
-     */
785
-    public function is_inactive()
786
-    {
787
-        // check if event id is present and if this event is published
788
-        if ($this->_has_ID_and_is_published()) {
789
-            return false;
790
-        }
791
-        return true;
792
-    }
793
-
794
-
795
-
796
-    /**
797
-     * perform_sold_out_status_check
798
-     * checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
799
-     * available... if NOT, then the event status will get toggled to 'sold_out'
800
-     *
801
-     * @access public
802
-     * @return bool    return the ACTUAL sold out state.
803
-     * @throws \EE_Error
804
-     */
805
-    public function perform_sold_out_status_check()
806
-    {
807
-        // get all unexpired untrashed tickets
808
-        $tickets = $this->tickets(array(
809
-            array(
810
-                'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
811
-                'TKT_deleted' => false,
812
-            ),
813
-        ));
814
-        // if all the tickets are just expired, then don't update the event status to sold out
815
-        if (empty($tickets)) {
816
-            return true;
817
-        }
818
-        // set initial value
819
-        $spaces_remaining = 0;
820
-        foreach ($tickets as $ticket) {
821
-            if ($ticket instanceof EE_Ticket) {
822
-                $spaces_remaining += $ticket->qty('saleable');
823
-            }
824
-        }
825
-        if ($spaces_remaining === 0) {
826
-            $this->set_status(EEM_Event::sold_out);
827
-            if ( ! is_admin() || (is_admin() && defined('DOING_AJAX'))) {
828
-                $this->save();
829
-            }
830
-            $sold_out = true;
831
-        } else {
832
-            $sold_out = false;
833
-            // was event previously marked as sold out ?
834
-            if ($this->status() === EEM_Event::sold_out) {
835
-                // revert status to previous value, if it was set
836
-                $previous_event_status = $this->get_post_meta('_previous_event_status', true);
837
-                if ($previous_event_status) {
838
-                    $this->set_status($previous_event_status);
839
-                }
840
-            }
841
-        }
842
-        //note: I considered changing the EEM_Event status away from sold_out if this status check reveals that it's no longer sold out (yet the status is still set as sold out) but the problem is... what do we change the status BACK to?  We can't always assume that the previous event status was 'published' because this status check is always done in the admin and its entirely possible the event admin manually changes to sold_out status from some other status.  We also don't want a draft event to become a "publish event" because the sold out check reveals its NOT sold out.
843
-        // So I'll forgo the automatic switch away from sold out status for now and instead just return the $sold out status... so this check can be used to validate the TRUE sold out status regardless of what the Event status is set to.
844
-        return $sold_out;
845
-    }
846
-
847
-
848
-
849
-    /**
850
-     * This returns the total remaining spaces for sale on this event.
851
-     * ############################
852
-     * VERY IMPORTANT FOR DEVELOPERS:
853
-     * While included here, this method is still being tested internally, so its signature and behaviour COULD change.
854
-     * While this comment block is in place, usage is at your own risk and know that it may change in future builds.
855
-     * ############################
856
-     *
857
-     * @uses EE_Event::total_available_spaces()
858
-     * @return float|int  (EE_INF is returned as float)
859
-     */
860
-    public function spaces_remaining_for_sale()
861
-    {
862
-        //first get total available spaces including consideration for tickets that have already sold.
863
-        $spaces_available = $this->total_available_spaces(true);
864
-        //if total available = 0, then exit right away because that means everything is expired.
865
-        if ($spaces_available === 0) {
866
-            return 0;
867
-        }
868
-        //subtract total approved registrations from spaces available to get how many are remaining.
869
-        $spots_taken = EEM_Registration::instance()->count(array(
870
-            array(
871
-                'EVT_ID' => $this->ID(),
872
-                'STS_ID' => EEM_Registration::status_id_approved,
873
-            ),
874
-        ), 'REG_ID', true);
875
-        $spaces_remaining = $spaces_available - $spots_taken;
876
-        return $spaces_remaining > 0 ? $spaces_remaining : 0;
877
-    }
878
-
879
-
880
-
881
-    /**
882
-     * This returns the total spaces available for an event while considering all the qtys on the tickets and the reg
883
-     * limits on the datetimes attached to this event.
884
-     * ############################
885
-     * VERY IMPORTANT FOR DEVELOPERS:
886
-     * While included here, this method is still being tested internally, so its signature and behaviour COULD change.
887
-     * While this comment block is in place, usage is at your own risk and know that it may change in future builds.
888
-     * ############################
889
-     * Note: by "spaces available" we are not returning how many spaces remain.  That is a calculation involving using
890
-     * the value from this method and subtracting the approved registrations for the event.
891
-     *
892
-     * @param   bool $current_total_available       Whether to consider any tickets that have already sold in our
893
-     *                                              calculation. If this is false, then we return the most tickets that
894
-     *                                              could ever be sold for this event with the datetime and tickets
895
-     *                                              setup on the event under optimal selling conditions.  Otherwise we
896
-     *                                              return a live calculation of spaces available based on tickets
897
-     *                                              sold.  Depending on setup and stage of sales, this may appear to
898
-     *                                              equal remaining tickets.  However, the more tickets are sold out,
899
-     *                                              the more accurate the "live" total is.
900
-     * @return  int|float  (Note: if EE_INF is returned its considered a float by PHP)
901
-     */
902
-    public function total_available_spaces($current_total_available = false)
903
-    {
904
-        $spaces_available = 0;
905
-        //first get all tickets on the event and include expired tickets
906
-        $tickets = $this->tickets(array('default_where_conditions' => 'none'));
907
-        $ticket_sums = array();
908
-        $datetime_limits = array();
909
-        //loop through tickets and normalize them
910
-        foreach ($tickets as $ticket) {
911
-            $datetimes = $ticket->datetimes(array('order_by' => array('DTT_reg_limit' => 'ASC')));
912
-            if (empty($datetimes)) {
913
-                continue;
914
-            }
915
-            //first datetime should be the lowest datetime
916
-            $least_datetime = reset($datetimes);
917
-            //lets reset the ticket quantity to be the lower of either the lowest datetime reg limit or the ticket quantity
918
-            //IF datetimes sold (and we're not doing current live total available, then use spaces remaining for datetime, not reg_limit.
919
-            if ($current_total_available) {
920
-                if ($ticket->is_remaining()) {
921
-                    $remaining = $ticket->remaining();
922
-                } else {
923
-                    $spaces_available += $ticket->sold();
924
-                    //and we don't cache this ticket to our list because its sold out.
925
-                    continue;
926
-                }
927
-            } else {
928
-                $remaining = min($ticket->qty(), $least_datetime->reg_limit());
929
-            }
930
-            //if $ticket_limit == infinity then let's drop out right away and just return that because any infinity amount trumps all other "available" amounts.
931
-            if ($remaining === EE_INF) {
932
-                return EE_INF;
933
-            }
934
-            //multiply normalized $tkt quantity by the number of datetimes on the ticket as the "sum"
935
-            //also include the sum of all the datetime reg limits on the ticket for breaking ties.
936
-            $ticket_sums[$ticket->ID()]['sum'] = $remaining * count($datetimes);
937
-            $ticket_sums[$ticket->ID()]['datetime_sums'] = 0;
938
-            foreach ($datetimes as $datetime) {
939
-                if ($datetime->reg_limit() === EE_INF) {
940
-                    $ticket_sums[$ticket->ID()]['datetime_sums'] = EE_INF;
941
-                } else {
942
-                    $ticket_sums[$ticket->ID()]['datetime_sums'] += $current_total_available
943
-                        ? $datetime->spaces_remaining() : $datetime->reg_limit();
944
-                }
945
-                $datetime_limits[$datetime->ID()] = $current_total_available ? $datetime->spaces_remaining()
946
-                    : $datetime->reg_limit();
947
-            }
948
-            $ticket_sums[$ticket->ID()]['ticket'] = $ticket;
949
-        }
950
-        //The order is sorted by lowest available first (which is calculated for each ticket by multiplying the normalized
951
-        //ticket quantity by the number of datetimes on the ticket).  For tie-breakers, then the next sort is based on the
952
-        //ticket with the greatest sum of all remaining datetime->spaces_remaining() ( or $datetime->reg_limit() if not
953
-        //$current_total_available ) for the datetimes on the ticket.
954
-        usort($ticket_sums, function ($a, $b) {
955
-            if ($a['sum'] == $b['sum']) {
956
-                if ($a['datetime_sums'] == $b['datetime_sums']) {
957
-                    return 0;
958
-                }
959
-                return $a['datetime_sums'] < $b['datetime_sums'] ? 1 : -1;
960
-            }
961
-            return ($a['sum'] < $b['sum']) ? -1 : 1;
962
-        });
963
-        //now let's loop through the sorted tickets and simulate sellouts
964
-        foreach ($ticket_sums as $ticket_info) {
965
-            if ($ticket_info['ticket'] instanceof EE_Ticket) {
966
-                $datetimes = $ticket_info['ticket']->datetimes(array('order_by' => array('DTT_reg_limit' => 'ASC')));
967
-                //need to sort these $datetimes by remaining (only if $current_total_available)
968
-                //setup datetimes for simulation
969
-                $ticket_datetimes_remaining = array();
970
-                foreach ($datetimes as $datetime) {
971
-                    $ticket_datetimes_remaining[$datetime->ID()]['rem'] = $datetime_limits[$datetime->ID()];
972
-                    $ticket_datetimes_remaining[$datetime->ID()]['datetime'] = $datetime;
973
-                }
974
-                usort($ticket_datetimes_remaining, function ($a, $b) {
975
-                    if ($a['rem'] == $b['rem']) {
976
-                        return 0;
977
-                    }
978
-                    return ($a['rem'] < $b['rem']) ? -1 : 1;
979
-                });
980
-                //get the remaining on the first datetime (which should be the one with the least remaining) and that is
981
-                //what we add to the spaces_available running total.  Then we need to decrease the remaining on our datetime tracker.
982
-                $lowest_datetime = reset($ticket_datetimes_remaining);
983
-                //need to get the lower of; what the remaining is on the lowest datetime, and the remaining on the ticket.
984
-                // If this ends up being 0 (because of previous tickets in our simulation selling out), then it has already
985
-                // been tracked on $spaces available and this ticket is now sold out for the simulation, so we can continue
986
-                // to the next ticket.
987
-                if ($current_total_available) {
988
-                    $remaining = min($lowest_datetime['rem'], $ticket_info['ticket']->remaining());
989
-                } else {
990
-                    $remaining = min($lowest_datetime['rem'], $ticket_info['ticket']->qty());
991
-                }
992
-                //if $remaining is infinite that means that all datetimes on this ticket are infinite but we've made it here because all
993
-                //tickets have a quantity.  So we don't have to track datetimes, we can just use ticket quantities for total
994
-                //available.
995
-                if ($remaining === EE_INF) {
996
-                    $spaces_available += $ticket_info['ticket']->qty();
997
-                    continue;
998
-                }
999
-                //if ticket has sold amounts then we also need to add that (but only if doing live counts)
1000
-                if ($current_total_available) {
1001
-                    $spaces_available += $ticket_info['ticket']->sold();
1002
-                }
1003
-                if ($remaining <= 0) {
1004
-                    continue;
1005
-                } else {
1006
-                    $spaces_available += $remaining;
1007
-                }
1008
-                //loop through the datetimes and sell them out!
1009
-                foreach ($ticket_datetimes_remaining as $datetime_info) {
1010
-                    if ($datetime_info['datetime'] instanceof EE_Datetime) {
1011
-                        $datetime_limits[$datetime_info['datetime']->ID()] += -$remaining;
1012
-                    }
1013
-                }
1014
-            }
1015
-        }
1016
-        return $spaces_available;
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     * Checks if the event is set to sold out
1023
-     *
1024
-     * @param  bool $actual whether or not to perform calculations to not only figure the actual status but also to
1025
-     *                      flip the status if necessary to sold out If false, we just check the existing status of the
1026
-     *                      event
1027
-     * @return boolean
1028
-     */
1029
-    public function is_sold_out($actual = false)
1030
-    {
1031
-        if ( ! $actual) {
1032
-            return $this->status() == EEM_Event::sold_out;
1033
-        } else {
1034
-            return $this->perform_sold_out_status_check();
1035
-        }
1036
-    }
1037
-
1038
-
1039
-
1040
-    /**
1041
-     * Checks if the event is marked as postponed
1042
-     *
1043
-     * @return boolean
1044
-     */
1045
-    public function is_postponed()
1046
-    {
1047
-        return $this->status() == EEM_Event::postponed;
1048
-    }
1049
-
1050
-
1051
-
1052
-    /**
1053
-     * Checks if the event is marked as cancelled
1054
-     *
1055
-     * @return boolean
1056
-     */
1057
-    public function is_cancelled()
1058
-    {
1059
-        return $this->status() == EEM_Event::cancelled;
1060
-    }
1061
-
1062
-
1063
-
1064
-    /**
1065
-     * Get the logical active status in a hierarchical order for all the datetimes.  Note
1066
-     * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1067
-     * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1068
-     * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1069
-     * the event is considered expired.
1070
-     * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1071
-     * status set on the EVENT when it is not published and thus is done
1072
-     *
1073
-     * @param bool $reset
1074
-     * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1075
-     */
1076
-    public function get_active_status($reset = false)
1077
-    {
1078
-        // if the active status has already been set, then just use that value (unless we are resetting it)
1079
-        if ( ! empty($this->_active_status) && ! $reset) {
1080
-            return $this->_active_status;
1081
-        }
1082
-        //first check if event id is present on this object
1083
-        if ( ! $this->ID()) {
1084
-            return false;
1085
-        }
1086
-        $where_params_for_event = array(array('EVT_ID' => $this->ID()));
1087
-        //if event is published:
1088
-        if ($this->status() === 'publish') {
1089
-            //active?
1090
-            if (EEM_Datetime::instance()->get_datetime_count_for_status(EE_Datetime::active, $where_params_for_event)
1091
-                > 0
1092
-            ) {
1093
-                $this->_active_status = EE_Datetime::active;
1094
-            } else {
1095
-                //upcoming?
1096
-                if (EEM_Datetime::instance()
1097
-                                ->get_datetime_count_for_status(EE_Datetime::upcoming, $where_params_for_event) > 0
1098
-                ) {
1099
-                    $this->_active_status = EE_Datetime::upcoming;
1100
-                } else {
1101
-                    //expired?
1102
-                    if (EEM_Datetime::instance()
1103
-                                    ->get_datetime_count_for_status(EE_Datetime::expired, $where_params_for_event) > 0
1104
-                    ) {
1105
-                        $this->_active_status = EE_Datetime::expired;
1106
-                    } else {
1107
-                        //it would be odd if things make it this far because it basically means there are no datetime's
1108
-                        //attached to the event.  So in this case it will just be considered inactive.
1109
-                        $this->_active_status = EE_Datetime::inactive;
1110
-                    }
1111
-                }
1112
-            }
1113
-        } else {
1114
-            //the event is not published, so let's just set it's active status according to its' post status
1115
-            switch ($this->status()) {
1116
-                case EEM_Event::sold_out :
1117
-                    $this->_active_status = EE_Datetime::sold_out;
1118
-                    break;
1119
-                case EEM_Event::cancelled :
1120
-                    $this->_active_status = EE_Datetime::cancelled;
1121
-                    break;
1122
-                case EEM_Event::postponed :
1123
-                    $this->_active_status = EE_Datetime::postponed;
1124
-                    break;
1125
-                default :
1126
-                    $this->_active_status = EE_Datetime::inactive;
1127
-            }
1128
-        }
1129
-        return $this->_active_status;
1130
-    }
1131
-
1132
-
1133
-
1134
-    /**
1135
-     *    pretty_active_status
1136
-     *
1137
-     * @access public
1138
-     * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1139
-     * @return mixed void|string
1140
-     */
1141
-    public function pretty_active_status($echo = true)
1142
-    {
1143
-        $active_status = $this->get_active_status();
1144
-        $status = '<span class="ee-status event-active-status-'
1145
-                  . $active_status
1146
-                  . '">'
1147
-                  . EEH_Template::pretty_status($active_status, false, 'sentence')
1148
-                  . '</span>';
1149
-        if ($echo) {
1150
-            echo $status;
1151
-            return '';
1152
-        }
1153
-        return $status;
1154
-    }
1155
-
1156
-
1157
-
1158
-    /**
1159
-     * @return bool|int
1160
-     */
1161
-    public function get_number_of_tickets_sold()
1162
-    {
1163
-        $tkt_sold = 0;
1164
-        if ( ! $this->ID()) {
1165
-            return 0;
1166
-        }
1167
-        $datetimes = $this->datetimes();
1168
-        foreach ($datetimes as $datetime) {
1169
-            if ($datetime instanceof EE_Datetime) {
1170
-                $tkt_sold += $datetime->sold();
1171
-            }
1172
-        }
1173
-        return $tkt_sold;
1174
-    }
1175
-
1176
-
1177
-
1178
-    /**
1179
-     * This just returns a count of all the registrations for this event
1180
-     *
1181
-     * @access  public
1182
-     * @return int
1183
-     */
1184
-    public function get_count_of_all_registrations()
1185
-    {
1186
-        return EEM_Event::instance()->count_related($this, 'Registration');
1187
-    }
1188
-
1189
-
1190
-
1191
-    /**
1192
-     * This returns the ticket with the earliest start time that is available for this event (across all datetimes
1193
-     * attached to the event)
1194
-     *
1195
-     * @return EE_Ticket
1196
-     */
1197
-    public function get_ticket_with_earliest_start_time()
1198
-    {
1199
-        $where['Datetime.EVT_ID'] = $this->ID();
1200
-        $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1201
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1202
-    }
1203
-
1204
-
1205
-
1206
-    /**
1207
-     * This returns the ticket with the latest end time that is available for this event (across all datetimes attached
1208
-     * to the event)
1209
-     *
1210
-     * @return EE_Ticket
1211
-     */
1212
-    public function get_ticket_with_latest_end_time()
1213
-    {
1214
-        $where['Datetime.EVT_ID'] = $this->ID();
1215
-        $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1216
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1217
-    }
1218
-
1219
-
1220
-
1221
-    /**
1222
-     * This returns whether there are any tickets on sale for this event.
1223
-     *
1224
-     * @return bool true = YES tickets on sale.
1225
-     */
1226
-    public function tickets_on_sale()
1227
-    {
1228
-        $earliest_ticket = $this->get_ticket_with_earliest_start_time();
1229
-        $latest_ticket = $this->get_ticket_with_latest_end_time();
1230
-        if ( ! $latest_ticket instanceof EE_Ticket && ! $earliest_ticket instanceof EE_Ticket) {
1231
-            return false;
1232
-        }
1233
-        //check on sale for these two tickets.
1234
-        if ($latest_ticket->is_on_sale() || $earliest_ticket->is_on_sale()) {
1235
-            return true;
1236
-        }
1237
-        return false;
1238
-    }
1239
-
1240
-
1241
-
1242
-    /**
1243
-     * Gets the URL for viewing this event on the front-end. Overrides parent
1244
-     * to check for an external URL first
1245
-     *
1246
-     * @return string
1247
-     */
1248
-    public function get_permalink()
1249
-    {
1250
-        if ($this->external_url()) {
1251
-            return $this->external_url();
1252
-        } else {
1253
-            return parent::get_permalink();
1254
-        }
1255
-    }
1256
-
1257
-
1258
-
1259
-    /**
1260
-     * Gets the first term for 'espresso_event_categories' we can find
1261
-     *
1262
-     * @param array $query_params like EEM_Base::get_all
1263
-     * @return EE_Term
1264
-     */
1265
-    public function first_event_category($query_params = array())
1266
-    {
1267
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1268
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1269
-        return EEM_Term::instance()->get_one($query_params);
1270
-    }
1271
-
1272
-
1273
-
1274
-    /**
1275
-     * Gets all terms for 'espresso_event_categories' we can find
1276
-     *
1277
-     * @param array $query_params
1278
-     * @return EE_Term[]
1279
-     */
1280
-    public function get_all_event_categories($query_params = array())
1281
-    {
1282
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1283
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1284
-        return EEM_Term::instance()->get_all($query_params);
1285
-    }
1286
-
1287
-
1288
-
1289
-    /**
1290
-     * Gets all the question groups, ordering them by QSG_order ascending
1291
-     *
1292
-     * @param array $query_params @see EEM_Base::get_all
1293
-     * @return EE_Question_Group[]
1294
-     */
1295
-    public function question_groups($query_params = array())
1296
-    {
1297
-        $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1298
-        return $this->get_many_related('Question_Group', $query_params);
1299
-    }
1300
-
1301
-
1302
-
1303
-    /**
1304
-     * Implementation for EEI_Has_Icon interface method.
1305
-     *
1306
-     * @see EEI_Visual_Representation for comments
1307
-     * @return string
1308
-     */
1309
-    public function get_icon()
1310
-    {
1311
-        return '<span class="dashicons dashicons-flag"></span>';
1312
-    }
1313
-
1314
-
1315
-
1316
-    /**
1317
-     * Implementation for EEI_Admin_Links interface method.
1318
-     *
1319
-     * @see EEI_Admin_Links for comments
1320
-     * @return string
1321
-     */
1322
-    public function get_admin_details_link()
1323
-    {
1324
-        return $this->get_admin_edit_link();
1325
-    }
1326
-
1327
-
1328
-
1329
-    /**
1330
-     * Implementation for EEI_Admin_Links interface method.
1331
-     *
1332
-     * @see EEI_Admin_Links for comments
1333
-     * @return string
1334
-     */
1335
-    public function get_admin_edit_link()
1336
-    {
1337
-        return EEH_URL::add_query_args_and_nonce(array(
1338
-            'page'   => 'espresso_events',
1339
-            'action' => 'edit',
1340
-            'post'   => $this->ID(),
1341
-        ),
1342
-            admin_url('admin.php')
1343
-        );
1344
-    }
1345
-
1346
-
1347
-
1348
-    /**
1349
-     * Implementation for EEI_Admin_Links interface method.
1350
-     *
1351
-     * @see EEI_Admin_Links for comments
1352
-     * @return string
1353
-     */
1354
-    public function get_admin_settings_link()
1355
-    {
1356
-        return EEH_URL::add_query_args_and_nonce(array(
1357
-            'page'   => 'espresso_events',
1358
-            'action' => 'default_event_settings',
1359
-        ),
1360
-            admin_url('admin.php')
1361
-        );
1362
-    }
1363
-
1364
-
1365
-
1366
-    /**
1367
-     * Implementation for EEI_Admin_Links interface method.
1368
-     *
1369
-     * @see EEI_Admin_Links for comments
1370
-     * @return string
1371
-     */
1372
-    public function get_admin_overview_link()
1373
-    {
1374
-        return EEH_URL::add_query_args_and_nonce(array(
1375
-            'page'   => 'espresso_events',
1376
-            'action' => 'default'
1377
-        ),
1378
-            admin_url('admin.php')
1379
-        );
1380
-    }
608
+
609
+	/**
610
+	 * @param $default_registration_status
611
+	 */
612
+	public function set_default_registration_status($default_registration_status)
613
+	{
614
+		$this->set('EVT_default_registration_status', $default_registration_status);
615
+	}
616
+
617
+
618
+
619
+	/**
620
+	 * @param $donations
621
+	 */
622
+	public function set_donations($donations)
623
+	{
624
+		$this->set('EVT_donations', $donations);
625
+	}
626
+
627
+
628
+
629
+	/**
630
+	 * Adds a venue to this event
631
+	 *
632
+	 * @param EE_Venue /int $venue_id_or_obj
633
+	 * @return EE_Venue
634
+	 */
635
+	public function add_venue($venue_id_or_obj)
636
+	{
637
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
638
+	}
639
+
640
+
641
+
642
+	/**
643
+	 * Removes a venue from the event
644
+	 *
645
+	 * @param EE_Venue /int $venue_id_or_obj
646
+	 * @return EE_Venue
647
+	 */
648
+	public function remove_venue($venue_id_or_obj)
649
+	{
650
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
651
+	}
652
+
653
+
654
+
655
+	/**
656
+	 * Gets all the venues related ot the event. May provide additional $query_params if desired
657
+	 *
658
+	 * @param array $query_params like EEM_Base::get_all's $query_params
659
+	 * @return EE_Venue[]
660
+	 */
661
+	public function venues($query_params = array())
662
+	{
663
+		return $this->get_many_related('Venue', $query_params);
664
+	}
665
+
666
+
667
+
668
+	/**
669
+	 * check if event id is present and if event is published
670
+	 *
671
+	 * @access public
672
+	 * @return boolean true yes, false no
673
+	 */
674
+	private function _has_ID_and_is_published()
675
+	{
676
+		// first check if event id is present and not NULL, then check if this event is published (or any of the equivalent "published" statuses)
677
+		return ($this->ID() && $this->ID() !== null
678
+				&& ($this->status() == 'publish'
679
+					|| $this->status()
680
+					   == EEM_Event::sold_out
681
+					|| $this->status() == EEM_Event::postponed
682
+					|| $this->status() == EEM_Event::cancelled)) ? true : false;
683
+	}
684
+
685
+
686
+
687
+	/**
688
+	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
689
+	 *
690
+	 * @access public
691
+	 * @return boolean true yes, false no
692
+	 */
693
+	public function is_upcoming()
694
+	{
695
+		// check if event id is present and if this event is published
696
+		if ($this->is_inactive()) {
697
+			return false;
698
+		}
699
+		// set initial value
700
+		$upcoming = false;
701
+		//next let's get all datetimes and loop through them
702
+		$datetimes = $this->datetimes_in_chronological_order();
703
+		foreach ($datetimes as $datetime) {
704
+			if ($datetime instanceof EE_Datetime) {
705
+				//if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
706
+				if ($datetime->is_expired()) {
707
+					continue;
708
+				}
709
+				//if this dtt is active then we return false.
710
+				if ($datetime->is_active()) {
711
+					return false;
712
+				}
713
+				//otherwise let's check upcoming status
714
+				$upcoming = $datetime->is_upcoming();
715
+			}
716
+		}
717
+		return $upcoming;
718
+	}
719
+
720
+
721
+
722
+	/**
723
+	 * @return bool
724
+	 */
725
+	public function is_active()
726
+	{
727
+		// check if event id is present and if this event is published
728
+		if ($this->is_inactive()) {
729
+			return false;
730
+		}
731
+		// set initial value
732
+		$active = false;
733
+		//next let's get all datetimes and loop through them
734
+		$datetimes = $this->datetimes_in_chronological_order();
735
+		foreach ($datetimes as $datetime) {
736
+			if ($datetime instanceof EE_Datetime) {
737
+				//if this dtt is expired then we continue cause one of the other datetimes might be active.
738
+				if ($datetime->is_expired()) {
739
+					continue;
740
+				}
741
+				//if this dtt is upcoming then we return false.
742
+				if ($datetime->is_upcoming()) {
743
+					return false;
744
+				}
745
+				//otherwise let's check active status
746
+				$active = $datetime->is_active();
747
+			}
748
+		}
749
+		return $active;
750
+	}
751
+
752
+
753
+
754
+	/**
755
+	 * @return bool
756
+	 */
757
+	public function is_expired()
758
+	{
759
+		// check if event id is present and if this event is published
760
+		if ($this->is_inactive()) {
761
+			return false;
762
+		}
763
+		// set initial value
764
+		$expired = false;
765
+		//first let's get all datetimes and loop through them
766
+		$datetimes = $this->datetimes_in_chronological_order();
767
+		foreach ($datetimes as $datetime) {
768
+			if ($datetime instanceof EE_Datetime) {
769
+				//if this dtt is upcoming or active then we return false.
770
+				if ($datetime->is_upcoming() || $datetime->is_active()) {
771
+					return false;
772
+				}
773
+				//otherwise let's check active status
774
+				$expired = $datetime->is_expired();
775
+			}
776
+		}
777
+		return $expired;
778
+	}
779
+
780
+
781
+
782
+	/**
783
+	 * @return bool
784
+	 */
785
+	public function is_inactive()
786
+	{
787
+		// check if event id is present and if this event is published
788
+		if ($this->_has_ID_and_is_published()) {
789
+			return false;
790
+		}
791
+		return true;
792
+	}
793
+
794
+
795
+
796
+	/**
797
+	 * perform_sold_out_status_check
798
+	 * checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
799
+	 * available... if NOT, then the event status will get toggled to 'sold_out'
800
+	 *
801
+	 * @access public
802
+	 * @return bool    return the ACTUAL sold out state.
803
+	 * @throws \EE_Error
804
+	 */
805
+	public function perform_sold_out_status_check()
806
+	{
807
+		// get all unexpired untrashed tickets
808
+		$tickets = $this->tickets(array(
809
+			array(
810
+				'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
811
+				'TKT_deleted' => false,
812
+			),
813
+		));
814
+		// if all the tickets are just expired, then don't update the event status to sold out
815
+		if (empty($tickets)) {
816
+			return true;
817
+		}
818
+		// set initial value
819
+		$spaces_remaining = 0;
820
+		foreach ($tickets as $ticket) {
821
+			if ($ticket instanceof EE_Ticket) {
822
+				$spaces_remaining += $ticket->qty('saleable');
823
+			}
824
+		}
825
+		if ($spaces_remaining === 0) {
826
+			$this->set_status(EEM_Event::sold_out);
827
+			if ( ! is_admin() || (is_admin() && defined('DOING_AJAX'))) {
828
+				$this->save();
829
+			}
830
+			$sold_out = true;
831
+		} else {
832
+			$sold_out = false;
833
+			// was event previously marked as sold out ?
834
+			if ($this->status() === EEM_Event::sold_out) {
835
+				// revert status to previous value, if it was set
836
+				$previous_event_status = $this->get_post_meta('_previous_event_status', true);
837
+				if ($previous_event_status) {
838
+					$this->set_status($previous_event_status);
839
+				}
840
+			}
841
+		}
842
+		//note: I considered changing the EEM_Event status away from sold_out if this status check reveals that it's no longer sold out (yet the status is still set as sold out) but the problem is... what do we change the status BACK to?  We can't always assume that the previous event status was 'published' because this status check is always done in the admin and its entirely possible the event admin manually changes to sold_out status from some other status.  We also don't want a draft event to become a "publish event" because the sold out check reveals its NOT sold out.
843
+		// So I'll forgo the automatic switch away from sold out status for now and instead just return the $sold out status... so this check can be used to validate the TRUE sold out status regardless of what the Event status is set to.
844
+		return $sold_out;
845
+	}
846
+
847
+
848
+
849
+	/**
850
+	 * This returns the total remaining spaces for sale on this event.
851
+	 * ############################
852
+	 * VERY IMPORTANT FOR DEVELOPERS:
853
+	 * While included here, this method is still being tested internally, so its signature and behaviour COULD change.
854
+	 * While this comment block is in place, usage is at your own risk and know that it may change in future builds.
855
+	 * ############################
856
+	 *
857
+	 * @uses EE_Event::total_available_spaces()
858
+	 * @return float|int  (EE_INF is returned as float)
859
+	 */
860
+	public function spaces_remaining_for_sale()
861
+	{
862
+		//first get total available spaces including consideration for tickets that have already sold.
863
+		$spaces_available = $this->total_available_spaces(true);
864
+		//if total available = 0, then exit right away because that means everything is expired.
865
+		if ($spaces_available === 0) {
866
+			return 0;
867
+		}
868
+		//subtract total approved registrations from spaces available to get how many are remaining.
869
+		$spots_taken = EEM_Registration::instance()->count(array(
870
+			array(
871
+				'EVT_ID' => $this->ID(),
872
+				'STS_ID' => EEM_Registration::status_id_approved,
873
+			),
874
+		), 'REG_ID', true);
875
+		$spaces_remaining = $spaces_available - $spots_taken;
876
+		return $spaces_remaining > 0 ? $spaces_remaining : 0;
877
+	}
878
+
879
+
880
+
881
+	/**
882
+	 * This returns the total spaces available for an event while considering all the qtys on the tickets and the reg
883
+	 * limits on the datetimes attached to this event.
884
+	 * ############################
885
+	 * VERY IMPORTANT FOR DEVELOPERS:
886
+	 * While included here, this method is still being tested internally, so its signature and behaviour COULD change.
887
+	 * While this comment block is in place, usage is at your own risk and know that it may change in future builds.
888
+	 * ############################
889
+	 * Note: by "spaces available" we are not returning how many spaces remain.  That is a calculation involving using
890
+	 * the value from this method and subtracting the approved registrations for the event.
891
+	 *
892
+	 * @param   bool $current_total_available       Whether to consider any tickets that have already sold in our
893
+	 *                                              calculation. If this is false, then we return the most tickets that
894
+	 *                                              could ever be sold for this event with the datetime and tickets
895
+	 *                                              setup on the event under optimal selling conditions.  Otherwise we
896
+	 *                                              return a live calculation of spaces available based on tickets
897
+	 *                                              sold.  Depending on setup and stage of sales, this may appear to
898
+	 *                                              equal remaining tickets.  However, the more tickets are sold out,
899
+	 *                                              the more accurate the "live" total is.
900
+	 * @return  int|float  (Note: if EE_INF is returned its considered a float by PHP)
901
+	 */
902
+	public function total_available_spaces($current_total_available = false)
903
+	{
904
+		$spaces_available = 0;
905
+		//first get all tickets on the event and include expired tickets
906
+		$tickets = $this->tickets(array('default_where_conditions' => 'none'));
907
+		$ticket_sums = array();
908
+		$datetime_limits = array();
909
+		//loop through tickets and normalize them
910
+		foreach ($tickets as $ticket) {
911
+			$datetimes = $ticket->datetimes(array('order_by' => array('DTT_reg_limit' => 'ASC')));
912
+			if (empty($datetimes)) {
913
+				continue;
914
+			}
915
+			//first datetime should be the lowest datetime
916
+			$least_datetime = reset($datetimes);
917
+			//lets reset the ticket quantity to be the lower of either the lowest datetime reg limit or the ticket quantity
918
+			//IF datetimes sold (and we're not doing current live total available, then use spaces remaining for datetime, not reg_limit.
919
+			if ($current_total_available) {
920
+				if ($ticket->is_remaining()) {
921
+					$remaining = $ticket->remaining();
922
+				} else {
923
+					$spaces_available += $ticket->sold();
924
+					//and we don't cache this ticket to our list because its sold out.
925
+					continue;
926
+				}
927
+			} else {
928
+				$remaining = min($ticket->qty(), $least_datetime->reg_limit());
929
+			}
930
+			//if $ticket_limit == infinity then let's drop out right away and just return that because any infinity amount trumps all other "available" amounts.
931
+			if ($remaining === EE_INF) {
932
+				return EE_INF;
933
+			}
934
+			//multiply normalized $tkt quantity by the number of datetimes on the ticket as the "sum"
935
+			//also include the sum of all the datetime reg limits on the ticket for breaking ties.
936
+			$ticket_sums[$ticket->ID()]['sum'] = $remaining * count($datetimes);
937
+			$ticket_sums[$ticket->ID()]['datetime_sums'] = 0;
938
+			foreach ($datetimes as $datetime) {
939
+				if ($datetime->reg_limit() === EE_INF) {
940
+					$ticket_sums[$ticket->ID()]['datetime_sums'] = EE_INF;
941
+				} else {
942
+					$ticket_sums[$ticket->ID()]['datetime_sums'] += $current_total_available
943
+						? $datetime->spaces_remaining() : $datetime->reg_limit();
944
+				}
945
+				$datetime_limits[$datetime->ID()] = $current_total_available ? $datetime->spaces_remaining()
946
+					: $datetime->reg_limit();
947
+			}
948
+			$ticket_sums[$ticket->ID()]['ticket'] = $ticket;
949
+		}
950
+		//The order is sorted by lowest available first (which is calculated for each ticket by multiplying the normalized
951
+		//ticket quantity by the number of datetimes on the ticket).  For tie-breakers, then the next sort is based on the
952
+		//ticket with the greatest sum of all remaining datetime->spaces_remaining() ( or $datetime->reg_limit() if not
953
+		//$current_total_available ) for the datetimes on the ticket.
954
+		usort($ticket_sums, function ($a, $b) {
955
+			if ($a['sum'] == $b['sum']) {
956
+				if ($a['datetime_sums'] == $b['datetime_sums']) {
957
+					return 0;
958
+				}
959
+				return $a['datetime_sums'] < $b['datetime_sums'] ? 1 : -1;
960
+			}
961
+			return ($a['sum'] < $b['sum']) ? -1 : 1;
962
+		});
963
+		//now let's loop through the sorted tickets and simulate sellouts
964
+		foreach ($ticket_sums as $ticket_info) {
965
+			if ($ticket_info['ticket'] instanceof EE_Ticket) {
966
+				$datetimes = $ticket_info['ticket']->datetimes(array('order_by' => array('DTT_reg_limit' => 'ASC')));
967
+				//need to sort these $datetimes by remaining (only if $current_total_available)
968
+				//setup datetimes for simulation
969
+				$ticket_datetimes_remaining = array();
970
+				foreach ($datetimes as $datetime) {
971
+					$ticket_datetimes_remaining[$datetime->ID()]['rem'] = $datetime_limits[$datetime->ID()];
972
+					$ticket_datetimes_remaining[$datetime->ID()]['datetime'] = $datetime;
973
+				}
974
+				usort($ticket_datetimes_remaining, function ($a, $b) {
975
+					if ($a['rem'] == $b['rem']) {
976
+						return 0;
977
+					}
978
+					return ($a['rem'] < $b['rem']) ? -1 : 1;
979
+				});
980
+				//get the remaining on the first datetime (which should be the one with the least remaining) and that is
981
+				//what we add to the spaces_available running total.  Then we need to decrease the remaining on our datetime tracker.
982
+				$lowest_datetime = reset($ticket_datetimes_remaining);
983
+				//need to get the lower of; what the remaining is on the lowest datetime, and the remaining on the ticket.
984
+				// If this ends up being 0 (because of previous tickets in our simulation selling out), then it has already
985
+				// been tracked on $spaces available and this ticket is now sold out for the simulation, so we can continue
986
+				// to the next ticket.
987
+				if ($current_total_available) {
988
+					$remaining = min($lowest_datetime['rem'], $ticket_info['ticket']->remaining());
989
+				} else {
990
+					$remaining = min($lowest_datetime['rem'], $ticket_info['ticket']->qty());
991
+				}
992
+				//if $remaining is infinite that means that all datetimes on this ticket are infinite but we've made it here because all
993
+				//tickets have a quantity.  So we don't have to track datetimes, we can just use ticket quantities for total
994
+				//available.
995
+				if ($remaining === EE_INF) {
996
+					$spaces_available += $ticket_info['ticket']->qty();
997
+					continue;
998
+				}
999
+				//if ticket has sold amounts then we also need to add that (but only if doing live counts)
1000
+				if ($current_total_available) {
1001
+					$spaces_available += $ticket_info['ticket']->sold();
1002
+				}
1003
+				if ($remaining <= 0) {
1004
+					continue;
1005
+				} else {
1006
+					$spaces_available += $remaining;
1007
+				}
1008
+				//loop through the datetimes and sell them out!
1009
+				foreach ($ticket_datetimes_remaining as $datetime_info) {
1010
+					if ($datetime_info['datetime'] instanceof EE_Datetime) {
1011
+						$datetime_limits[$datetime_info['datetime']->ID()] += -$remaining;
1012
+					}
1013
+				}
1014
+			}
1015
+		}
1016
+		return $spaces_available;
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 * Checks if the event is set to sold out
1023
+	 *
1024
+	 * @param  bool $actual whether or not to perform calculations to not only figure the actual status but also to
1025
+	 *                      flip the status if necessary to sold out If false, we just check the existing status of the
1026
+	 *                      event
1027
+	 * @return boolean
1028
+	 */
1029
+	public function is_sold_out($actual = false)
1030
+	{
1031
+		if ( ! $actual) {
1032
+			return $this->status() == EEM_Event::sold_out;
1033
+		} else {
1034
+			return $this->perform_sold_out_status_check();
1035
+		}
1036
+	}
1037
+
1038
+
1039
+
1040
+	/**
1041
+	 * Checks if the event is marked as postponed
1042
+	 *
1043
+	 * @return boolean
1044
+	 */
1045
+	public function is_postponed()
1046
+	{
1047
+		return $this->status() == EEM_Event::postponed;
1048
+	}
1049
+
1050
+
1051
+
1052
+	/**
1053
+	 * Checks if the event is marked as cancelled
1054
+	 *
1055
+	 * @return boolean
1056
+	 */
1057
+	public function is_cancelled()
1058
+	{
1059
+		return $this->status() == EEM_Event::cancelled;
1060
+	}
1061
+
1062
+
1063
+
1064
+	/**
1065
+	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
1066
+	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1067
+	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1068
+	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1069
+	 * the event is considered expired.
1070
+	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1071
+	 * status set on the EVENT when it is not published and thus is done
1072
+	 *
1073
+	 * @param bool $reset
1074
+	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1075
+	 */
1076
+	public function get_active_status($reset = false)
1077
+	{
1078
+		// if the active status has already been set, then just use that value (unless we are resetting it)
1079
+		if ( ! empty($this->_active_status) && ! $reset) {
1080
+			return $this->_active_status;
1081
+		}
1082
+		//first check if event id is present on this object
1083
+		if ( ! $this->ID()) {
1084
+			return false;
1085
+		}
1086
+		$where_params_for_event = array(array('EVT_ID' => $this->ID()));
1087
+		//if event is published:
1088
+		if ($this->status() === 'publish') {
1089
+			//active?
1090
+			if (EEM_Datetime::instance()->get_datetime_count_for_status(EE_Datetime::active, $where_params_for_event)
1091
+				> 0
1092
+			) {
1093
+				$this->_active_status = EE_Datetime::active;
1094
+			} else {
1095
+				//upcoming?
1096
+				if (EEM_Datetime::instance()
1097
+								->get_datetime_count_for_status(EE_Datetime::upcoming, $where_params_for_event) > 0
1098
+				) {
1099
+					$this->_active_status = EE_Datetime::upcoming;
1100
+				} else {
1101
+					//expired?
1102
+					if (EEM_Datetime::instance()
1103
+									->get_datetime_count_for_status(EE_Datetime::expired, $where_params_for_event) > 0
1104
+					) {
1105
+						$this->_active_status = EE_Datetime::expired;
1106
+					} else {
1107
+						//it would be odd if things make it this far because it basically means there are no datetime's
1108
+						//attached to the event.  So in this case it will just be considered inactive.
1109
+						$this->_active_status = EE_Datetime::inactive;
1110
+					}
1111
+				}
1112
+			}
1113
+		} else {
1114
+			//the event is not published, so let's just set it's active status according to its' post status
1115
+			switch ($this->status()) {
1116
+				case EEM_Event::sold_out :
1117
+					$this->_active_status = EE_Datetime::sold_out;
1118
+					break;
1119
+				case EEM_Event::cancelled :
1120
+					$this->_active_status = EE_Datetime::cancelled;
1121
+					break;
1122
+				case EEM_Event::postponed :
1123
+					$this->_active_status = EE_Datetime::postponed;
1124
+					break;
1125
+				default :
1126
+					$this->_active_status = EE_Datetime::inactive;
1127
+			}
1128
+		}
1129
+		return $this->_active_status;
1130
+	}
1131
+
1132
+
1133
+
1134
+	/**
1135
+	 *    pretty_active_status
1136
+	 *
1137
+	 * @access public
1138
+	 * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1139
+	 * @return mixed void|string
1140
+	 */
1141
+	public function pretty_active_status($echo = true)
1142
+	{
1143
+		$active_status = $this->get_active_status();
1144
+		$status = '<span class="ee-status event-active-status-'
1145
+				  . $active_status
1146
+				  . '">'
1147
+				  . EEH_Template::pretty_status($active_status, false, 'sentence')
1148
+				  . '</span>';
1149
+		if ($echo) {
1150
+			echo $status;
1151
+			return '';
1152
+		}
1153
+		return $status;
1154
+	}
1155
+
1156
+
1157
+
1158
+	/**
1159
+	 * @return bool|int
1160
+	 */
1161
+	public function get_number_of_tickets_sold()
1162
+	{
1163
+		$tkt_sold = 0;
1164
+		if ( ! $this->ID()) {
1165
+			return 0;
1166
+		}
1167
+		$datetimes = $this->datetimes();
1168
+		foreach ($datetimes as $datetime) {
1169
+			if ($datetime instanceof EE_Datetime) {
1170
+				$tkt_sold += $datetime->sold();
1171
+			}
1172
+		}
1173
+		return $tkt_sold;
1174
+	}
1175
+
1176
+
1177
+
1178
+	/**
1179
+	 * This just returns a count of all the registrations for this event
1180
+	 *
1181
+	 * @access  public
1182
+	 * @return int
1183
+	 */
1184
+	public function get_count_of_all_registrations()
1185
+	{
1186
+		return EEM_Event::instance()->count_related($this, 'Registration');
1187
+	}
1188
+
1189
+
1190
+
1191
+	/**
1192
+	 * This returns the ticket with the earliest start time that is available for this event (across all datetimes
1193
+	 * attached to the event)
1194
+	 *
1195
+	 * @return EE_Ticket
1196
+	 */
1197
+	public function get_ticket_with_earliest_start_time()
1198
+	{
1199
+		$where['Datetime.EVT_ID'] = $this->ID();
1200
+		$query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1201
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1202
+	}
1203
+
1204
+
1205
+
1206
+	/**
1207
+	 * This returns the ticket with the latest end time that is available for this event (across all datetimes attached
1208
+	 * to the event)
1209
+	 *
1210
+	 * @return EE_Ticket
1211
+	 */
1212
+	public function get_ticket_with_latest_end_time()
1213
+	{
1214
+		$where['Datetime.EVT_ID'] = $this->ID();
1215
+		$query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1216
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1217
+	}
1218
+
1219
+
1220
+
1221
+	/**
1222
+	 * This returns whether there are any tickets on sale for this event.
1223
+	 *
1224
+	 * @return bool true = YES tickets on sale.
1225
+	 */
1226
+	public function tickets_on_sale()
1227
+	{
1228
+		$earliest_ticket = $this->get_ticket_with_earliest_start_time();
1229
+		$latest_ticket = $this->get_ticket_with_latest_end_time();
1230
+		if ( ! $latest_ticket instanceof EE_Ticket && ! $earliest_ticket instanceof EE_Ticket) {
1231
+			return false;
1232
+		}
1233
+		//check on sale for these two tickets.
1234
+		if ($latest_ticket->is_on_sale() || $earliest_ticket->is_on_sale()) {
1235
+			return true;
1236
+		}
1237
+		return false;
1238
+	}
1239
+
1240
+
1241
+
1242
+	/**
1243
+	 * Gets the URL for viewing this event on the front-end. Overrides parent
1244
+	 * to check for an external URL first
1245
+	 *
1246
+	 * @return string
1247
+	 */
1248
+	public function get_permalink()
1249
+	{
1250
+		if ($this->external_url()) {
1251
+			return $this->external_url();
1252
+		} else {
1253
+			return parent::get_permalink();
1254
+		}
1255
+	}
1256
+
1257
+
1258
+
1259
+	/**
1260
+	 * Gets the first term for 'espresso_event_categories' we can find
1261
+	 *
1262
+	 * @param array $query_params like EEM_Base::get_all
1263
+	 * @return EE_Term
1264
+	 */
1265
+	public function first_event_category($query_params = array())
1266
+	{
1267
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1268
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1269
+		return EEM_Term::instance()->get_one($query_params);
1270
+	}
1271
+
1272
+
1273
+
1274
+	/**
1275
+	 * Gets all terms for 'espresso_event_categories' we can find
1276
+	 *
1277
+	 * @param array $query_params
1278
+	 * @return EE_Term[]
1279
+	 */
1280
+	public function get_all_event_categories($query_params = array())
1281
+	{
1282
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1283
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1284
+		return EEM_Term::instance()->get_all($query_params);
1285
+	}
1286
+
1287
+
1288
+
1289
+	/**
1290
+	 * Gets all the question groups, ordering them by QSG_order ascending
1291
+	 *
1292
+	 * @param array $query_params @see EEM_Base::get_all
1293
+	 * @return EE_Question_Group[]
1294
+	 */
1295
+	public function question_groups($query_params = array())
1296
+	{
1297
+		$query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1298
+		return $this->get_many_related('Question_Group', $query_params);
1299
+	}
1300
+
1301
+
1302
+
1303
+	/**
1304
+	 * Implementation for EEI_Has_Icon interface method.
1305
+	 *
1306
+	 * @see EEI_Visual_Representation for comments
1307
+	 * @return string
1308
+	 */
1309
+	public function get_icon()
1310
+	{
1311
+		return '<span class="dashicons dashicons-flag"></span>';
1312
+	}
1313
+
1314
+
1315
+
1316
+	/**
1317
+	 * Implementation for EEI_Admin_Links interface method.
1318
+	 *
1319
+	 * @see EEI_Admin_Links for comments
1320
+	 * @return string
1321
+	 */
1322
+	public function get_admin_details_link()
1323
+	{
1324
+		return $this->get_admin_edit_link();
1325
+	}
1326
+
1327
+
1328
+
1329
+	/**
1330
+	 * Implementation for EEI_Admin_Links interface method.
1331
+	 *
1332
+	 * @see EEI_Admin_Links for comments
1333
+	 * @return string
1334
+	 */
1335
+	public function get_admin_edit_link()
1336
+	{
1337
+		return EEH_URL::add_query_args_and_nonce(array(
1338
+			'page'   => 'espresso_events',
1339
+			'action' => 'edit',
1340
+			'post'   => $this->ID(),
1341
+		),
1342
+			admin_url('admin.php')
1343
+		);
1344
+	}
1345
+
1346
+
1347
+
1348
+	/**
1349
+	 * Implementation for EEI_Admin_Links interface method.
1350
+	 *
1351
+	 * @see EEI_Admin_Links for comments
1352
+	 * @return string
1353
+	 */
1354
+	public function get_admin_settings_link()
1355
+	{
1356
+		return EEH_URL::add_query_args_and_nonce(array(
1357
+			'page'   => 'espresso_events',
1358
+			'action' => 'default_event_settings',
1359
+		),
1360
+			admin_url('admin.php')
1361
+		);
1362
+	}
1363
+
1364
+
1365
+
1366
+	/**
1367
+	 * Implementation for EEI_Admin_Links interface method.
1368
+	 *
1369
+	 * @see EEI_Admin_Links for comments
1370
+	 * @return string
1371
+	 */
1372
+	public function get_admin_overview_link()
1373
+	{
1374
+		return EEH_URL::add_query_args_and_nonce(array(
1375
+			'page'   => 'espresso_events',
1376
+			'action' => 'default'
1377
+		),
1378
+			admin_url('admin.php')
1379
+		);
1380
+	}
1381 1381
 
1382 1382
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket.class.php 2 patches
Indentation   +585 added lines, -585 removed lines patch added patch discarded remove patch
@@ -61,15 +61,15 @@  discard block
 block discarded – undo
61 61
 
62 62
 
63 63
 
64
-    /**
65
-     * @param array  $props_n_values          incoming values
66
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
-     *                                        used.)
68
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
-     *                                        date_format and the second value is the time format
70
-     * @return EE_Ticket
71
-     * @throws \EE_Error
72
-     */
64
+	/**
65
+	 * @param array  $props_n_values          incoming values
66
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
+	 *                                        used.)
68
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
+	 *                                        date_format and the second value is the time format
70
+	 * @return EE_Ticket
71
+	 * @throws \EE_Error
72
+	 */
73 73
 	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74 74
 		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75 75
 		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
@@ -77,36 +77,36 @@  discard block
 block discarded – undo
77 77
 
78 78
 
79 79
 
80
-    /**
81
-     * @param array  $props_n_values  incoming values from the database
82
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
-     *                                the website will be used.
84
-     * @return EE_Ticket
85
-     * @throws \EE_Error
86
-     */
80
+	/**
81
+	 * @param array  $props_n_values  incoming values from the database
82
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
+	 *                                the website will be used.
84
+	 * @return EE_Ticket
85
+	 * @throws \EE_Error
86
+	 */
87 87
 	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88 88
 		return new self( $props_n_values, TRUE, $timezone );
89 89
 	}
90 90
 
91 91
 
92 92
 
93
-    /**
94
-     * @return bool
95
-     * @throws \EE_Error
96
-     */
93
+	/**
94
+	 * @return bool
95
+	 * @throws \EE_Error
96
+	 */
97 97
 	public function parent() {
98 98
 		return $this->get( 'TKT_parent' );
99 99
 	}
100 100
 
101 101
 
102 102
 
103
-    /**
104
-     * return if a ticket has quantities available for purchase
105
-     *
106
-     * @param  int $DTT_ID the primary key for a particular datetime
107
-     * @return boolean
108
-     * @throws \EE_Error
109
-     */
103
+	/**
104
+	 * return if a ticket has quantities available for purchase
105
+	 *
106
+	 * @param  int $DTT_ID the primary key for a particular datetime
107
+	 * @return boolean
108
+	 * @throws \EE_Error
109
+	 */
110 110
 	public function available( $DTT_ID = 0 ) {
111 111
 		// are we checking availability for a particular datetime ?
112 112
 		if ( $DTT_ID ) {
@@ -123,14 +123,14 @@  discard block
 block discarded – undo
123 123
 
124 124
 
125 125
 
126
-    /**
127
-     * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
-     *
129
-     * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
-     * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
-     * @return mixed status int if the display string isn't requested
132
-     * @throws \EE_Error
133
-     */
126
+	/**
127
+	 * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
+	 *
129
+	 * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
+	 * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
+	 * @return mixed status int if the display string isn't requested
132
+	 * @throws \EE_Error
133
+	 */
134 134
 	public function ticket_status( $display = FALSE, $remaining = null ) {
135 135
 		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136 136
 		if ( ! $remaining ) {
@@ -153,14 +153,14 @@  discard block
 block discarded – undo
153 153
 
154 154
 
155 155
 
156
-    /**
157
-     * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
-     *
159
-     * @access public
160
-     * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
-     * @return boolean         true = tickets remaining, false not.
162
-     * @throws \EE_Error
163
-     */
156
+	/**
157
+	 * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
+	 *
159
+	 * @access public
160
+	 * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
+	 * @return boolean         true = tickets remaining, false not.
162
+	 * @throws \EE_Error
163
+	 */
164 164
 	public function is_remaining( $DTT_ID = 0 ) {
165 165
 		$num_remaining = $this->remaining( $DTT_ID );
166 166
 		if ( $num_remaining === 0 ) {
@@ -174,76 +174,76 @@  discard block
 block discarded – undo
174 174
 
175 175
 
176 176
 
177
-    /**
178
-     * return the total number of tickets available for purchase
179
-     *
180
-     * @param  int $DTT_ID the primary key for a particular datetime.
181
-     *                     set to 0 for all related datetimes
182
-     * @return int
183
-     * @throws \EE_Error
184
-     */
177
+	/**
178
+	 * return the total number of tickets available for purchase
179
+	 *
180
+	 * @param  int $DTT_ID the primary key for a particular datetime.
181
+	 *                     set to 0 for all related datetimes
182
+	 * @return int
183
+	 * @throws \EE_Error
184
+	 */
185 185
 	public function remaining( $DTT_ID = 0 ) {
186 186
 		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
187 187
 	}
188 188
 
189 189
 
190 190
 
191
-    /**
192
-     * Gets min
193
-     *
194
-     * @return int
195
-     * @throws \EE_Error
196
-     */
191
+	/**
192
+	 * Gets min
193
+	 *
194
+	 * @return int
195
+	 * @throws \EE_Error
196
+	 */
197 197
 	public function min() {
198 198
 		return $this->get( 'TKT_min' );
199 199
 	}
200 200
 
201 201
 
202 202
 
203
-    /**
204
-     * return if a ticket is no longer available cause its available dates have expired.
205
-     *
206
-     * @return boolean
207
-     * @throws \EE_Error
208
-     */
203
+	/**
204
+	 * return if a ticket is no longer available cause its available dates have expired.
205
+	 *
206
+	 * @return boolean
207
+	 * @throws \EE_Error
208
+	 */
209 209
 	public function is_expired() {
210 210
 		return ( $this->get_raw( 'TKT_end_date' ) < time() );
211 211
 	}
212 212
 
213 213
 
214 214
 
215
-    /**
216
-     * Return if a ticket is yet to go on sale or not
217
-     *
218
-     * @return boolean
219
-     * @throws \EE_Error
220
-     */
215
+	/**
216
+	 * Return if a ticket is yet to go on sale or not
217
+	 *
218
+	 * @return boolean
219
+	 * @throws \EE_Error
220
+	 */
221 221
 	public function is_pending() {
222 222
 		return ( $this->get_raw( 'TKT_start_date' ) > time() );
223 223
 	}
224 224
 
225 225
 
226 226
 
227
-    /**
228
-     * Return if a ticket is on sale or not
229
-     *
230
-     * @return boolean
231
-     * @throws \EE_Error
232
-     */
227
+	/**
228
+	 * Return if a ticket is on sale or not
229
+	 *
230
+	 * @return boolean
231
+	 * @throws \EE_Error
232
+	 */
233 233
 	public function is_on_sale() {
234 234
 		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
235 235
 	}
236 236
 
237 237
 
238 238
 
239
-    /**
240
-     * This returns the chronologically last datetime that this ticket is associated with
241
-     *
242
-     * @param string $dt_frmt
243
-     * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
-     * @return string
245
-     * @throws \EE_Error
246
-     */
239
+	/**
240
+	 * This returns the chronologically last datetime that this ticket is associated with
241
+	 *
242
+	 * @param string $dt_frmt
243
+	 * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
+	 * @return string
245
+	 * @throws \EE_Error
246
+	 */
247 247
 	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248 248
 		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249 249
 		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
@@ -253,12 +253,12 @@  discard block
 block discarded – undo
253 253
 
254 254
 
255 255
 
256
-    /**
257
-     * This returns the chronologically first datetime that this ticket is associated with
258
-     *
259
-     * @return EE_Datetime
260
-     * @throws \EE_Error
261
-     */
256
+	/**
257
+	 * This returns the chronologically first datetime that this ticket is associated with
258
+	 *
259
+	 * @return EE_Datetime
260
+	 * @throws \EE_Error
261
+	 */
262 262
 	public function first_datetime() {
263 263
 		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264 264
 		return reset( $datetimes );
@@ -266,14 +266,14 @@  discard block
 block discarded – undo
266 266
 
267 267
 
268 268
 
269
-    /**
270
-     * Gets all the datetimes this ticket can be used for attending.
271
-     * Unless otherwise specified, orders datetimes by start date.
272
-     *
273
-     * @param array $query_params see EEM_Base::get_all()
274
-     * @return EE_Datetime[]|EE_Base_Class[]
275
-     * @throws \EE_Error
276
-     */
269
+	/**
270
+	 * Gets all the datetimes this ticket can be used for attending.
271
+	 * Unless otherwise specified, orders datetimes by start date.
272
+	 *
273
+	 * @param array $query_params see EEM_Base::get_all()
274
+	 * @return EE_Datetime[]|EE_Base_Class[]
275
+	 * @throws \EE_Error
276
+	 */
277 277
 	public function datetimes( $query_params = array() ) {
278 278
 		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279 279
 			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
@@ -283,12 +283,12 @@  discard block
 block discarded – undo
283 283
 
284 284
 
285 285
 
286
-    /**
287
-     * This returns the chronologically last datetime that this ticket is associated with
288
-     *
289
-     * @return EE_Datetime
290
-     * @throws \EE_Error
291
-     */
286
+	/**
287
+	 * This returns the chronologically last datetime that this ticket is associated with
288
+	 *
289
+	 * @return EE_Datetime
290
+	 * @throws \EE_Error
291
+	 */
292 292
 	public function last_datetime() {
293 293
 		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294 294
 		return end( $datetimes );
@@ -296,19 +296,19 @@  discard block
 block discarded – undo
296 296
 
297 297
 
298 298
 
299
-    /**
300
-     * This returns the total tickets sold depending on the given parameters.
301
-     *
302
-     * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
-     *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
-     *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
-     *                        'datetime' = total ticket sales in the datetime_ticket table.
306
-     *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
-     *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
-     * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
-     * @return mixed (array|int)          how many tickets have sold
310
-     * @throws \EE_Error
311
-     */
299
+	/**
300
+	 * This returns the total tickets sold depending on the given parameters.
301
+	 *
302
+	 * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
+	 *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
+	 *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
+	 *                        'datetime' = total ticket sales in the datetime_ticket table.
306
+	 *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
+	 *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
+	 * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
+	 * @return mixed (array|int)          how many tickets have sold
310
+	 * @throws \EE_Error
311
+	 */
312 312
 	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
@@ -333,12 +333,12 @@  discard block
 block discarded – undo
333 333
 
334 334
 
335 335
 
336
-    /**
337
-     * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
-     *
339
-     * @return EE_Ticket[]
340
-     * @throws \EE_Error
341
-     */
336
+	/**
337
+	 * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
+	 *
339
+	 * @return EE_Ticket[]
340
+	 * @throws \EE_Error
341
+	 */
342 342
 	protected function _all_tickets_sold() {
343 343
 		$datetimes = $this->get_many_related( 'Datetime' );
344 344
 		$tickets_sold = array();
@@ -354,29 +354,29 @@  discard block
 block discarded – undo
354 354
 
355 355
 
356 356
 
357
-    /**
358
-     * This returns the base price object for the ticket.
359
-     *
360
-     * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
-     * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
-     * @throws \EE_Error
363
-     */
357
+	/**
358
+	 * This returns the base price object for the ticket.
359
+	 *
360
+	 * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
+	 * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
+	 * @throws \EE_Error
363
+	 */
364 364
 	public function base_price( $return_array = FALSE ) {
365 365
 		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+			? $this->get_many_related( 'Price', array( $_where ) )
368
+			: $this->get_first_related( 'Price', array( $_where ) );
369 369
 	}
370 370
 
371 371
 
372 372
 
373
-    /**
374
-     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
-     *
376
-     * @access public
377
-     * @return EE_Price[]
378
-     * @throws \EE_Error
379
-     */
373
+	/**
374
+	 * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
+	 *
376
+	 * @access public
377
+	 * @return EE_Price[]
378
+	 * @throws \EE_Error
379
+	 */
380 380
 	public function price_modifiers() {
381 381
 		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382 382
 		return $this->prices( $query_params );
@@ -384,132 +384,132 @@  discard block
 block discarded – undo
384 384
 
385 385
 
386 386
 
387
-    /**
388
-     * Gets all the prices that combine to form the final price of this ticket
389
-     *
390
-     * @param array $query_params like EEM_Base::get_all
391
-     * @return EE_Price[]|EE_Base_Class[]
392
-     * @throws \EE_Error
393
-     */
387
+	/**
388
+	 * Gets all the prices that combine to form the final price of this ticket
389
+	 *
390
+	 * @param array $query_params like EEM_Base::get_all
391
+	 * @return EE_Price[]|EE_Base_Class[]
392
+	 * @throws \EE_Error
393
+	 */
394 394
 	public function prices( $query_params = array() ) {
395 395
 		return $this->get_many_related( 'Price', $query_params );
396 396
 	}
397 397
 
398 398
 
399 399
 
400
-    /**
401
-     * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
-     *
403
-     * @param array $query_params see EEM_Base::get_all()
404
-     * @return EE_Datetime_Ticket|EE_Base_Class[]
405
-     * @throws \EE_Error
406
-     */
400
+	/**
401
+	 * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
+	 *
403
+	 * @param array $query_params see EEM_Base::get_all()
404
+	 * @return EE_Datetime_Ticket|EE_Base_Class[]
405
+	 * @throws \EE_Error
406
+	 */
407 407
 	public function datetime_tickets( $query_params = array() ) {
408 408
 		return $this->get_many_related( 'Datetime_Ticket', $query_params );
409 409
 	}
410 410
 
411 411
 
412 412
 
413
-    /**
414
-     * Gets all the datetimes from the db ordered by DTT_order
415
-     *
416
-     * @param boolean $show_expired
417
-     * @param boolean $show_deleted
418
-     * @return EE_Datetime[]
419
-     * @throws \EE_Error
420
-     */
413
+	/**
414
+	 * Gets all the datetimes from the db ordered by DTT_order
415
+	 *
416
+	 * @param boolean $show_expired
417
+	 * @param boolean $show_deleted
418
+	 * @return EE_Datetime[]
419
+	 * @throws \EE_Error
420
+	 */
421 421
 	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422 422
 		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
423 423
 	}
424 424
 
425 425
 
426 426
 
427
-    /**
428
-     * Gets ID
429
-     *
430
-     * @return string
431
-     * @throws \EE_Error
432
-     */
427
+	/**
428
+	 * Gets ID
429
+	 *
430
+	 * @return string
431
+	 * @throws \EE_Error
432
+	 */
433 433
 	public function ID() {
434 434
 		return $this->get( 'TKT_ID' );
435 435
 	}
436 436
 
437 437
 
438 438
 
439
-    /**
440
-     * get the author of the ticket.
441
-     *
442
-     * @since 4.5.0
443
-     * @return int
444
-     * @throws \EE_Error
445
-     */
439
+	/**
440
+	 * get the author of the ticket.
441
+	 *
442
+	 * @since 4.5.0
443
+	 * @return int
444
+	 * @throws \EE_Error
445
+	 */
446 446
 	public function wp_user() {
447 447
 		return $this->get('TKT_wp_user');
448 448
 	}
449 449
 
450 450
 
451 451
 
452
-    /**
453
-     * Gets the template for the ticket
454
-     *
455
-     * @return EE_Ticket_Template|EE_Base_Class
456
-     * @throws \EE_Error
457
-     */
452
+	/**
453
+	 * Gets the template for the ticket
454
+	 *
455
+	 * @return EE_Ticket_Template|EE_Base_Class
456
+	 * @throws \EE_Error
457
+	 */
458 458
 	public function template() {
459 459
 		return $this->get_first_related( 'Ticket_Template' );
460 460
 	}
461 461
 
462 462
 
463 463
 
464
-    /**
465
-     * Simply returns an array of EE_Price objects that are taxes.
466
-     *
467
-     * @return EE_Price[]
468
-     * @throws \EE_Error
469
-     */
464
+	/**
465
+	 * Simply returns an array of EE_Price objects that are taxes.
466
+	 *
467
+	 * @return EE_Price[]
468
+	 * @throws \EE_Error
469
+	 */
470 470
 	public function get_ticket_taxes_for_admin() {
471 471
 		return EE_Taxes::get_taxes_for_admin();
472 472
 	}
473 473
 
474 474
 
475 475
 
476
-    /**
477
-     * @return float
478
-     * @throws \EE_Error
479
-     */
476
+	/**
477
+	 * @return float
478
+	 * @throws \EE_Error
479
+	 */
480 480
 	public function ticket_price() {
481 481
 		return $this->get( 'TKT_price' );
482 482
 	}
483 483
 
484 484
 
485 485
 
486
-    /**
487
-     * @return mixed
488
-     * @throws \EE_Error
489
-     */
486
+	/**
487
+	 * @return mixed
488
+	 * @throws \EE_Error
489
+	 */
490 490
 	public function pretty_price() {
491 491
 		return $this->get_pretty( 'TKT_price' );
492 492
 	}
493 493
 
494 494
 
495 495
 
496
-    /**
497
-     * @return bool
498
-     * @throws \EE_Error
499
-     */
496
+	/**
497
+	 * @return bool
498
+	 * @throws \EE_Error
499
+	 */
500 500
 	public function is_free() {
501 501
 		return $this->get_ticket_total_with_taxes() === (float) 0;
502 502
 	}
503 503
 
504 504
 
505 505
 
506
-    /**
507
-     * get_ticket_total_with_taxes
508
-     *
509
-     * @param bool $no_cache
510
-     * @return float
511
-     * @throws \EE_Error
512
-     */
506
+	/**
507
+	 * get_ticket_total_with_taxes
508
+	 *
509
+	 * @param bool $no_cache
510
+	 * @return float
511
+	 * @throws \EE_Error
512
+	 */
513 513
 	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514 514
 		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
@@ -526,201 +526,201 @@  discard block
 block discarded – undo
526 526
 
527 527
 
528 528
 
529
-    /**
530
-     * @return float
531
-     * @throws \EE_Error
532
-     */
529
+	/**
530
+	 * @return float
531
+	 * @throws \EE_Error
532
+	 */
533 533
 	public function get_ticket_subtotal() {
534 534
 		return EE_Taxes::get_subtotal_for_admin( $this );
535 535
 	}
536 536
 
537 537
 
538 538
 
539
-    /**
540
-     * Returns the total taxes applied to this ticket
541
-     *
542
-     * @return float
543
-     * @throws \EE_Error
544
-     */
539
+	/**
540
+	 * Returns the total taxes applied to this ticket
541
+	 *
542
+	 * @return float
543
+	 * @throws \EE_Error
544
+	 */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546 546
 		return EE_Taxes::get_total_taxes_for_admin( $this );
547 547
 	}
548 548
 
549 549
 
550 550
 
551
-    /**
552
-     * Sets name
553
-     *
554
-     * @param string $name
555
-     * @throws \EE_Error
556
-     */
551
+	/**
552
+	 * Sets name
553
+	 *
554
+	 * @param string $name
555
+	 * @throws \EE_Error
556
+	 */
557 557
 	public function set_name( $name ) {
558 558
 		$this->set( 'TKT_name', $name );
559 559
 	}
560 560
 
561 561
 
562 562
 
563
-    /**
564
-     * Gets description
565
-     *
566
-     * @return string
567
-     * @throws \EE_Error
568
-     */
563
+	/**
564
+	 * Gets description
565
+	 *
566
+	 * @return string
567
+	 * @throws \EE_Error
568
+	 */
569 569
 	public function description() {
570 570
 		return $this->get( 'TKT_description' );
571 571
 	}
572 572
 
573 573
 
574 574
 
575
-    /**
576
-     * Sets description
577
-     *
578
-     * @param string $description
579
-     * @throws \EE_Error
580
-     */
575
+	/**
576
+	 * Sets description
577
+	 *
578
+	 * @param string $description
579
+	 * @throws \EE_Error
580
+	 */
581 581
 	public function set_description( $description ) {
582 582
 		$this->set( 'TKT_description', $description );
583 583
 	}
584 584
 
585 585
 
586 586
 
587
-    /**
588
-     * Gets start_date
589
-     *
590
-     * @param string $dt_frmt
591
-     * @param string $tm_frmt
592
-     * @return string
593
-     * @throws \EE_Error
594
-     */
587
+	/**
588
+	 * Gets start_date
589
+	 *
590
+	 * @param string $dt_frmt
591
+	 * @param string $tm_frmt
592
+	 * @return string
593
+	 * @throws \EE_Error
594
+	 */
595 595
 	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596 596
 		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
597 597
 	}
598 598
 
599 599
 
600 600
 
601
-    /**
602
-     * Sets start_date
603
-     *
604
-     * @param string $start_date
605
-     * @return void
606
-     * @throws \EE_Error
607
-     */
601
+	/**
602
+	 * Sets start_date
603
+	 *
604
+	 * @param string $start_date
605
+	 * @return void
606
+	 * @throws \EE_Error
607
+	 */
608 608
 	public function set_start_date( $start_date ) {
609 609
 		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
610 610
 	}
611 611
 
612 612
 
613 613
 
614
-    /**
615
-     * Gets end_date
616
-     *
617
-     * @param string $dt_frmt
618
-     * @param string $tm_frmt
619
-     * @return string
620
-     * @throws \EE_Error
621
-     */
614
+	/**
615
+	 * Gets end_date
616
+	 *
617
+	 * @param string $dt_frmt
618
+	 * @param string $tm_frmt
619
+	 * @return string
620
+	 * @throws \EE_Error
621
+	 */
622 622
 	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623 623
 		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
624 624
 	}
625 625
 
626 626
 
627 627
 
628
-    /**
629
-     * Sets end_date
630
-     *
631
-     * @param string $end_date
632
-     * @return void
633
-     * @throws \EE_Error
634
-     */
628
+	/**
629
+	 * Sets end_date
630
+	 *
631
+	 * @param string $end_date
632
+	 * @return void
633
+	 * @throws \EE_Error
634
+	 */
635 635
 	public function set_end_date( $end_date ) {
636 636
 		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
637 637
 	}
638 638
 
639 639
 
640 640
 
641
-    /**
642
-     * Sets sell until time
643
-     *
644
-     * @since 4.5.0
645
-     * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
-     * @throws \EE_Error
647
-     */
641
+	/**
642
+	 * Sets sell until time
643
+	 *
644
+	 * @since 4.5.0
645
+	 * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
+	 * @throws \EE_Error
647
+	 */
648 648
 	public function set_end_time( $time ) {
649 649
 		$this->_set_time_for( $time, 'TKT_end_date' );
650 650
 	}
651 651
 
652 652
 
653 653
 
654
-    /**
655
-     * Sets min
656
-     *
657
-     * @param int $min
658
-     * @return void
659
-     * @throws \EE_Error
660
-     */
654
+	/**
655
+	 * Sets min
656
+	 *
657
+	 * @param int $min
658
+	 * @return void
659
+	 * @throws \EE_Error
660
+	 */
661 661
 	public function set_min( $min ) {
662 662
 		$this->set( 'TKT_min', $min );
663 663
 	}
664 664
 
665 665
 
666 666
 
667
-    /**
668
-     * Gets max
669
-     *
670
-     * @return int
671
-     * @throws \EE_Error
672
-     */
667
+	/**
668
+	 * Gets max
669
+	 *
670
+	 * @return int
671
+	 * @throws \EE_Error
672
+	 */
673 673
 	public function max() {
674 674
 		return $this->get( 'TKT_max' );
675 675
 	}
676 676
 
677 677
 
678 678
 
679
-    /**
680
-     * Sets max
681
-     *
682
-     * @param int $max
683
-     * @return void
684
-     * @throws \EE_Error
685
-     */
679
+	/**
680
+	 * Sets max
681
+	 *
682
+	 * @param int $max
683
+	 * @return void
684
+	 * @throws \EE_Error
685
+	 */
686 686
 	public function set_max( $max ) {
687 687
 		$this->set( 'TKT_max', $max );
688 688
 	}
689 689
 
690 690
 
691 691
 
692
-    /**
693
-     * Sets price
694
-     *
695
-     * @param float $price
696
-     * @return void
697
-     * @throws \EE_Error
698
-     */
692
+	/**
693
+	 * Sets price
694
+	 *
695
+	 * @param float $price
696
+	 * @return void
697
+	 * @throws \EE_Error
698
+	 */
699 699
 	public function set_price( $price ) {
700 700
 		$this->set( 'TKT_price', $price );
701 701
 	}
702 702
 
703 703
 
704 704
 
705
-    /**
706
-     * Gets sold
707
-     *
708
-     * @return int
709
-     * @throws \EE_Error
710
-     */
705
+	/**
706
+	 * Gets sold
707
+	 *
708
+	 * @return int
709
+	 * @throws \EE_Error
710
+	 */
711 711
 	public function sold() {
712 712
 		return $this->get_raw( 'TKT_sold' );
713 713
 	}
714 714
 
715 715
 
716 716
 
717
-    /**
718
-     * Sets sold
719
-     *
720
-     * @param int $sold
721
-     * @return void
722
-     * @throws \EE_Error
723
-     */
717
+	/**
718
+	 * Sets sold
719
+	 *
720
+	 * @param int $sold
721
+	 * @return void
722
+	 * @throws \EE_Error
723
+	 */
724 724
 	public function set_sold( $sold ) {
725 725
 		// sold can not go below zero
726 726
 		$sold = max( 0, $sold );
@@ -729,13 +729,13 @@  discard block
 block discarded – undo
729 729
 
730 730
 
731 731
 
732
-    /**
733
-     * increments sold by amount passed by $qty
734
-     *
735
-     * @param int $qty
736
-     * @return void
737
-     * @throws \EE_Error
738
-     */
732
+	/**
733
+	 * increments sold by amount passed by $qty
734
+	 *
735
+	 * @param int $qty
736
+	 * @return void
737
+	 * @throws \EE_Error
738
+	 */
739 739
 	public function increase_sold( $qty = 1 ) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
@@ -747,13 +747,13 @@  discard block
 block discarded – undo
747 747
 
748 748
 
749 749
 
750
-    /**
751
-     * Increases sold on related datetimes
752
-     *
753
-     * @param int $qty
754
-     * @return void
755
-     * @throws \EE_Error
756
-     */
750
+	/**
751
+	 * Increases sold on related datetimes
752
+	 *
753
+	 * @param int $qty
754
+	 * @return void
755
+	 * @throws \EE_Error
756
+	 */
757 757
 	protected function _increase_sold_for_datetimes( $qty = 1 ) {
758 758
 		$datetimes = $this->datetimes();
759 759
 		if ( is_array( $datetimes ) ) {
@@ -768,13 +768,13 @@  discard block
 block discarded – undo
768 768
 
769 769
 
770 770
 
771
-    /**
772
-     * decrements (subtracts) sold by amount passed by $qty
773
-     *
774
-     * @param int $qty
775
-     * @return void
776
-     * @throws \EE_Error
777
-     */
771
+	/**
772
+	 * decrements (subtracts) sold by amount passed by $qty
773
+	 *
774
+	 * @param int $qty
775
+	 * @return void
776
+	 * @throws \EE_Error
777
+	 */
778 778
 	public function decrease_sold( $qty = 1 ) {
779 779
 		$sold = $this->sold() - $qty;
780 780
 		$this->_decrease_sold_for_datetimes( $qty );
@@ -783,13 +783,13 @@  discard block
 block discarded – undo
783 783
 
784 784
 
785 785
 
786
-    /**
787
-     * Decreases sold on related datetimes
788
-     *
789
-     * @param int $qty
790
-     * @return void
791
-     * @throws \EE_Error
792
-     */
786
+	/**
787
+	 * Decreases sold on related datetimes
788
+	 *
789
+	 * @param int $qty
790
+	 * @return void
791
+	 * @throws \EE_Error
792
+	 */
793 793
 	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
794 794
 		$datetimes = $this->datetimes();
795 795
 		if ( is_array( $datetimes ) ) {
@@ -804,25 +804,25 @@  discard block
 block discarded – undo
804 804
 
805 805
 
806 806
 
807
-    /**
808
-     * Gets qty of reserved tickets
809
-     *
810
-     * @return int
811
-     * @throws \EE_Error
812
-     */
807
+	/**
808
+	 * Gets qty of reserved tickets
809
+	 *
810
+	 * @return int
811
+	 * @throws \EE_Error
812
+	 */
813 813
 	public function reserved() {
814 814
 		return $this->get_raw( 'TKT_reserved' );
815 815
 	}
816 816
 
817 817
 
818 818
 
819
-    /**
820
-     * Sets reserved
821
-     *
822
-     * @param int $reserved
823
-     * @return void
824
-     * @throws \EE_Error
825
-     */
819
+	/**
820
+	 * Sets reserved
821
+	 *
822
+	 * @param int $reserved
823
+	 * @return void
824
+	 * @throws \EE_Error
825
+	 */
826 826
 	public function set_reserved( $reserved ) {
827 827
 		// reserved can not go below zero
828 828
 		$reserved = max( 0, (int) $reserved );
@@ -831,13 +831,13 @@  discard block
 block discarded – undo
831 831
 
832 832
 
833 833
 
834
-    /**
835
-     * increments reserved by amount passed by $qty
836
-     *
837
-     * @param int $qty
838
-     * @return void
839
-     * @throws \EE_Error
840
-     */
834
+	/**
835
+	 * increments reserved by amount passed by $qty
836
+	 *
837
+	 * @param int $qty
838
+	 * @return void
839
+	 * @throws \EE_Error
840
+	 */
841 841
 	public function increase_reserved( $qty = 1 ) {
842 842
 		$qty = absint( $qty );
843 843
 		$reserved = $this->reserved() + $qty;
@@ -847,13 +847,13 @@  discard block
 block discarded – undo
847 847
 
848 848
 
849 849
 
850
-    /**
851
-     * Increases sold on related datetimes
852
-     *
853
-     * @param int $qty
854
-     * @return void
855
-     * @throws \EE_Error
856
-     */
850
+	/**
851
+	 * Increases sold on related datetimes
852
+	 *
853
+	 * @param int $qty
854
+	 * @return void
855
+	 * @throws \EE_Error
856
+	 */
857 857
 	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
858 858
 		$datetimes = $this->datetimes();
859 859
 		if ( is_array( $datetimes ) ) {
@@ -868,14 +868,14 @@  discard block
 block discarded – undo
868 868
 
869 869
 
870 870
 
871
-    /**
872
-     * decrements (subtracts) reserved by amount passed by $qty
873
-     *
874
-     * @param int  $qty
875
-     * @param bool $adjust_datetimes
876
-     * @return void
877
-     * @throws \EE_Error
878
-     */
871
+	/**
872
+	 * decrements (subtracts) reserved by amount passed by $qty
873
+	 *
874
+	 * @param int  $qty
875
+	 * @param bool $adjust_datetimes
876
+	 * @return void
877
+	 * @throws \EE_Error
878
+	 */
879 879
 	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
880 880
 		$reserved = $this->reserved() - absint( $qty );
881 881
 		if ( $adjust_datetimes ) {
@@ -886,13 +886,13 @@  discard block
 block discarded – undo
886 886
 
887 887
 
888 888
 
889
-    /**
890
-     * Increases sold on related datetimes
891
-     *
892
-     * @param int $qty
893
-     * @return void
894
-     * @throws \EE_Error
895
-     */
889
+	/**
890
+	 * Increases sold on related datetimes
891
+	 *
892
+	 * @param int $qty
893
+	 * @return void
894
+	 * @throws \EE_Error
895
+	 */
896 896
 	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
897 897
 		$datetimes = $this->datetimes();
898 898
 		if ( is_array( $datetimes ) ) {
@@ -907,18 +907,18 @@  discard block
 block discarded – undo
907 907
 
908 908
 
909 909
 
910
-    /**
911
-     * Gets ticket quantity
912
-     *
913
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
914
-     *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
915
-     *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
916
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
917
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
918
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
919
-     * @return int
920
-     * @throws \EE_Error
921
-     */
910
+	/**
911
+	 * Gets ticket quantity
912
+	 *
913
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
914
+	 *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
915
+	 *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
916
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
917
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
918
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
919
+	 * @return int
920
+	 * @throws \EE_Error
921
+	 */
922 922
 	public function qty( $context = '' ) {
923 923
 		switch ( $context ) {
924 924
 			case 'reg_limit' :
@@ -932,19 +932,19 @@  discard block
 block discarded – undo
932 932
 
933 933
 
934 934
 
935
-    /**
936
-     * Gets ticket quantity
937
-     *
938
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
939
-     *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
940
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
943
-     * @param  int   $DTT_ID      the primary key for a particular datetime.
944
-     *                            set to 0 for all related datetimes
945
-     * @return int
946
-     * @throws \EE_Error
947
-     */
935
+	/**
936
+	 * Gets ticket quantity
937
+	 *
938
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
939
+	 *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
940
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
943
+	 * @param  int   $DTT_ID      the primary key for a particular datetime.
944
+	 *                            set to 0 for all related datetimes
945
+	 * @return int
946
+	 * @throws \EE_Error
947
+	 */
948 948
 	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
949 949
 		$raw = $this->get_raw( 'TKT_qty' );
950 950
 		// return immediately if it's zero
@@ -1003,9 +1003,9 @@  discard block
 block discarded – undo
1003 1003
 			$qty = max( $qty - $sold_and_reserved_for_this_ticket, 0 );
1004 1004
 			// echo "\n . qty: " . $qty . '<br />';
1005 1005
 		}
1006
-        // echo "\nFINAL QTY: " . $qty . "<br /><br />";
1007
-        // echo is_admin() && ! did_action('admin_notices') ? '</div>' : '';
1008
-        return $qty;
1006
+		// echo "\nFINAL QTY: " . $qty . "<br /><br />";
1007
+		// echo is_admin() && ! did_action('admin_notices') ? '</div>' : '';
1008
+		return $qty;
1009 1009
 	}
1010 1010
 
1011 1011
 
@@ -1029,212 +1029,212 @@  discard block
 block discarded – undo
1029 1029
 
1030 1030
 
1031 1031
 
1032
-    /**
1033
-     * Gets uses
1034
-     *
1035
-     * @return int
1036
-     * @throws \EE_Error
1037
-     */
1032
+	/**
1033
+	 * Gets uses
1034
+	 *
1035
+	 * @return int
1036
+	 * @throws \EE_Error
1037
+	 */
1038 1038
 	public function uses() {
1039 1039
 		return $this->get( 'TKT_uses' );
1040 1040
 	}
1041 1041
 
1042 1042
 
1043 1043
 
1044
-    /**
1045
-     * Sets uses
1046
-     *
1047
-     * @param int $uses
1048
-     * @return void
1049
-     * @throws \EE_Error
1050
-     */
1044
+	/**
1045
+	 * Sets uses
1046
+	 *
1047
+	 * @param int $uses
1048
+	 * @return void
1049
+	 * @throws \EE_Error
1050
+	 */
1051 1051
 	public function set_uses( $uses ) {
1052 1052
 		$this->set( 'TKT_uses', $uses );
1053 1053
 	}
1054 1054
 
1055 1055
 
1056 1056
 
1057
-    /**
1058
-     * returns whether ticket is required or not.
1059
-     *
1060
-     * @return boolean
1061
-     * @throws \EE_Error
1062
-     */
1057
+	/**
1058
+	 * returns whether ticket is required or not.
1059
+	 *
1060
+	 * @return boolean
1061
+	 * @throws \EE_Error
1062
+	 */
1063 1063
 	public function required() {
1064 1064
 		return $this->get( 'TKT_required' );
1065 1065
 	}
1066 1066
 
1067 1067
 
1068 1068
 
1069
-    /**
1070
-     * sets the TKT_required property
1071
-     *
1072
-     * @param boolean $required
1073
-     * @return void
1074
-     * @throws \EE_Error
1075
-     */
1069
+	/**
1070
+	 * sets the TKT_required property
1071
+	 *
1072
+	 * @param boolean $required
1073
+	 * @return void
1074
+	 * @throws \EE_Error
1075
+	 */
1076 1076
 	public function set_required( $required ) {
1077 1077
 		$this->set( 'TKT_required', $required );
1078 1078
 	}
1079 1079
 
1080 1080
 
1081 1081
 
1082
-    /**
1083
-     * Gets taxable
1084
-     *
1085
-     * @return boolean
1086
-     * @throws \EE_Error
1087
-     */
1082
+	/**
1083
+	 * Gets taxable
1084
+	 *
1085
+	 * @return boolean
1086
+	 * @throws \EE_Error
1087
+	 */
1088 1088
 	public function taxable() {
1089 1089
 		return $this->get( 'TKT_taxable' );
1090 1090
 	}
1091 1091
 
1092 1092
 
1093 1093
 
1094
-    /**
1095
-     * Sets taxable
1096
-     *
1097
-     * @param boolean $taxable
1098
-     * @return void
1099
-     * @throws \EE_Error
1100
-     */
1094
+	/**
1095
+	 * Sets taxable
1096
+	 *
1097
+	 * @param boolean $taxable
1098
+	 * @return void
1099
+	 * @throws \EE_Error
1100
+	 */
1101 1101
 	public function set_taxable( $taxable ) {
1102 1102
 		$this->set( 'TKT_taxable', $taxable );
1103 1103
 	}
1104 1104
 
1105 1105
 
1106 1106
 
1107
-    /**
1108
-     * Gets is_default
1109
-     *
1110
-     * @return boolean
1111
-     * @throws \EE_Error
1112
-     */
1107
+	/**
1108
+	 * Gets is_default
1109
+	 *
1110
+	 * @return boolean
1111
+	 * @throws \EE_Error
1112
+	 */
1113 1113
 	public function is_default() {
1114 1114
 		return $this->get( 'TKT_is_default' );
1115 1115
 	}
1116 1116
 
1117 1117
 
1118 1118
 
1119
-    /**
1120
-     * Sets is_default
1121
-     *
1122
-     * @param boolean $is_default
1123
-     * @return void
1124
-     * @throws \EE_Error
1125
-     */
1119
+	/**
1120
+	 * Sets is_default
1121
+	 *
1122
+	 * @param boolean $is_default
1123
+	 * @return void
1124
+	 * @throws \EE_Error
1125
+	 */
1126 1126
 	public function set_is_default( $is_default ) {
1127 1127
 		$this->set( 'TKT_is_default', $is_default );
1128 1128
 	}
1129 1129
 
1130 1130
 
1131 1131
 
1132
-    /**
1133
-     * Gets order
1134
-     *
1135
-     * @return int
1136
-     * @throws \EE_Error
1137
-     */
1132
+	/**
1133
+	 * Gets order
1134
+	 *
1135
+	 * @return int
1136
+	 * @throws \EE_Error
1137
+	 */
1138 1138
 	public function order() {
1139 1139
 		return $this->get( 'TKT_order' );
1140 1140
 	}
1141 1141
 
1142 1142
 
1143 1143
 
1144
-    /**
1145
-     * Sets order
1146
-     *
1147
-     * @param int $order
1148
-     * @return void
1149
-     * @throws \EE_Error
1150
-     */
1144
+	/**
1145
+	 * Sets order
1146
+	 *
1147
+	 * @param int $order
1148
+	 * @return void
1149
+	 * @throws \EE_Error
1150
+	 */
1151 1151
 	public function set_order( $order ) {
1152 1152
 		$this->set( 'TKT_order', $order );
1153 1153
 	}
1154 1154
 
1155 1155
 
1156 1156
 
1157
-    /**
1158
-     * Gets row
1159
-     *
1160
-     * @return int
1161
-     * @throws \EE_Error
1162
-     */
1157
+	/**
1158
+	 * Gets row
1159
+	 *
1160
+	 * @return int
1161
+	 * @throws \EE_Error
1162
+	 */
1163 1163
 	public function row() {
1164 1164
 		return $this->get( 'TKT_row' );
1165 1165
 	}
1166 1166
 
1167 1167
 
1168 1168
 
1169
-    /**
1170
-     * Sets row
1171
-     *
1172
-     * @param int $row
1173
-     * @return void
1174
-     * @throws \EE_Error
1175
-     */
1169
+	/**
1170
+	 * Sets row
1171
+	 *
1172
+	 * @param int $row
1173
+	 * @return void
1174
+	 * @throws \EE_Error
1175
+	 */
1176 1176
 	public function set_row( $row ) {
1177 1177
 		$this->set( 'TKT_row', $row );
1178 1178
 	}
1179 1179
 
1180 1180
 
1181 1181
 
1182
-    /**
1183
-     * Gets deleted
1184
-     *
1185
-     * @return boolean
1186
-     * @throws \EE_Error
1187
-     */
1182
+	/**
1183
+	 * Gets deleted
1184
+	 *
1185
+	 * @return boolean
1186
+	 * @throws \EE_Error
1187
+	 */
1188 1188
 	public function deleted() {
1189 1189
 		return $this->get( 'TKT_deleted' );
1190 1190
 	}
1191 1191
 
1192 1192
 
1193 1193
 
1194
-    /**
1195
-     * Sets deleted
1196
-     *
1197
-     * @param boolean $deleted
1198
-     * @return void
1199
-     * @throws \EE_Error
1200
-     */
1194
+	/**
1195
+	 * Sets deleted
1196
+	 *
1197
+	 * @param boolean $deleted
1198
+	 * @return void
1199
+	 * @throws \EE_Error
1200
+	 */
1201 1201
 	public function set_deleted( $deleted ) {
1202 1202
 		$this->set( 'TKT_deleted', $deleted );
1203 1203
 	}
1204 1204
 
1205 1205
 
1206 1206
 
1207
-    /**
1208
-     * Gets parent
1209
-     *
1210
-     * @return int
1211
-     * @throws \EE_Error
1212
-     */
1207
+	/**
1208
+	 * Gets parent
1209
+	 *
1210
+	 * @return int
1211
+	 * @throws \EE_Error
1212
+	 */
1213 1213
 	public function parent_ID() {
1214 1214
 		return $this->get( 'TKT_parent' );
1215 1215
 	}
1216 1216
 
1217 1217
 
1218 1218
 
1219
-    /**
1220
-     * Sets parent
1221
-     *
1222
-     * @param int $parent
1223
-     * @return void
1224
-     * @throws \EE_Error
1225
-     */
1219
+	/**
1220
+	 * Sets parent
1221
+	 *
1222
+	 * @param int $parent
1223
+	 * @return void
1224
+	 * @throws \EE_Error
1225
+	 */
1226 1226
 	public function set_parent_ID( $parent ) {
1227 1227
 		$this->set( 'TKT_parent', $parent );
1228 1228
 	}
1229 1229
 
1230 1230
 
1231 1231
 
1232
-    /**
1233
-     * Gets a string which is handy for showing in gateways etc that describes the ticket.
1234
-     *
1235
-     * @return string
1236
-     * @throws \EE_Error
1237
-     */
1232
+	/**
1233
+	 * Gets a string which is handy for showing in gateways etc that describes the ticket.
1234
+	 *
1235
+	 * @return string
1236
+	 * @throws \EE_Error
1237
+	 */
1238 1238
 	public function name_and_info() {
1239 1239
 		$times = array();
1240 1240
 		foreach ( $this->datetimes() as $datetime ) {
@@ -1245,67 +1245,67 @@  discard block
 block discarded – undo
1245 1245
 
1246 1246
 
1247 1247
 
1248
-    /**
1249
-     * Gets name
1250
-     *
1251
-     * @return string
1252
-     * @throws \EE_Error
1253
-     */
1248
+	/**
1249
+	 * Gets name
1250
+	 *
1251
+	 * @return string
1252
+	 * @throws \EE_Error
1253
+	 */
1254 1254
 	public function name() {
1255 1255
 		return $this->get( 'TKT_name' );
1256 1256
 	}
1257 1257
 
1258 1258
 
1259 1259
 
1260
-    /**
1261
-     * Gets price
1262
-     *
1263
-     * @return float
1264
-     * @throws \EE_Error
1265
-     */
1260
+	/**
1261
+	 * Gets price
1262
+	 *
1263
+	 * @return float
1264
+	 * @throws \EE_Error
1265
+	 */
1266 1266
 	public function price() {
1267 1267
 		return $this->get( 'TKT_price' );
1268 1268
 	}
1269 1269
 
1270 1270
 
1271 1271
 
1272
-    /**
1273
-     * Gets all the registrations for this ticket
1274
-     *
1275
-     * @param array $query_params like EEM_Base::get_all's
1276
-     * @return EE_Registration[]|EE_Base_Class[]
1277
-     * @throws \EE_Error
1278
-     */
1272
+	/**
1273
+	 * Gets all the registrations for this ticket
1274
+	 *
1275
+	 * @param array $query_params like EEM_Base::get_all's
1276
+	 * @return EE_Registration[]|EE_Base_Class[]
1277
+	 * @throws \EE_Error
1278
+	 */
1279 1279
 	public function registrations( $query_params = array() ) {
1280 1280
 		return $this->get_many_related( 'Registration', $query_params );
1281 1281
 	}
1282 1282
 
1283 1283
 
1284 1284
 
1285
-    /**
1286
-     * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1287
-     * into account
1288
-     *
1289
-     * @return int
1290
-     * @throws \EE_Error
1291
-     */
1285
+	/**
1286
+	 * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1287
+	 * into account
1288
+	 *
1289
+	 * @return int
1290
+	 * @throws \EE_Error
1291
+	 */
1292 1292
 	public function update_tickets_sold() {
1293
-        $count_regs_for_this_ticket = $this->count_registrations(
1294
-            array(
1295
-                array(
1296
-                    'STS_ID'      => EEM_Registration::status_id_approved,
1297
-                    'REG_deleted' => 0,
1298
-                ),
1299
-            )
1300
-        );
1301
-        $sold = $this->sold();
1302
-        if ($count_regs_for_this_ticket > $sold) {
1303
-            $this->increase_sold($count_regs_for_this_ticket - $sold);
1304
-            $this->save();
1305
-        } else if ($count_regs_for_this_ticket < $sold) {
1306
-            $this->decrease_sold($count_regs_for_this_ticket - $sold);
1307
-            $this->save();
1308
-        }
1293
+		$count_regs_for_this_ticket = $this->count_registrations(
1294
+			array(
1295
+				array(
1296
+					'STS_ID'      => EEM_Registration::status_id_approved,
1297
+					'REG_deleted' => 0,
1298
+				),
1299
+			)
1300
+		);
1301
+		$sold = $this->sold();
1302
+		if ($count_regs_for_this_ticket > $sold) {
1303
+			$this->increase_sold($count_regs_for_this_ticket - $sold);
1304
+			$this->save();
1305
+		} else if ($count_regs_for_this_ticket < $sold) {
1306
+			$this->decrease_sold($count_regs_for_this_ticket - $sold);
1307
+			$this->save();
1308
+		}
1309 1309
 		return $count_regs_for_this_ticket;
1310 1310
 	}
1311 1311
 
@@ -1333,21 +1333,21 @@  discard block
 block discarded – undo
1333 1333
 
1334 1334
 
1335 1335
 
1336
-    /**
1337
-     * Implementation of the EEI_Event_Relation interface method
1338
-     *
1339
-     * @see EEI_Event_Relation for comments
1340
-     * @return EE_Event
1341
-     * @throws \EE_Error
1342
-     * @throws UnexpectedEntityException
1343
-     */
1336
+	/**
1337
+	 * Implementation of the EEI_Event_Relation interface method
1338
+	 *
1339
+	 * @see EEI_Event_Relation for comments
1340
+	 * @return EE_Event
1341
+	 * @throws \EE_Error
1342
+	 * @throws UnexpectedEntityException
1343
+	 */
1344 1344
 	public function get_related_event() {
1345 1345
 		//get one datetime to use for getting the event
1346 1346
 		$datetime = $this->first_datetime();
1347 1347
 		if ( ! $datetime instanceof \EE_Datetime ) {
1348 1348
 			throw new UnexpectedEntityException(
1349 1349
 				$datetime,
1350
-                'EE_Datetime',
1350
+				'EE_Datetime',
1351 1351
 				sprintf(
1352 1352
 					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1353 1353
 					$this->name()
@@ -1358,7 +1358,7 @@  discard block
 block discarded – undo
1358 1358
 		if ( ! $event instanceof \EE_Event ) {
1359 1359
 			throw new UnexpectedEntityException(
1360 1360
 				$event,
1361
-                'EE_Event',
1361
+				'EE_Event',
1362 1362
 				sprintf(
1363 1363
 					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1364 1364
 					$this->name()
@@ -1370,14 +1370,14 @@  discard block
 block discarded – undo
1370 1370
 
1371 1371
 
1372 1372
 
1373
-    /**
1374
-     * Implementation of the EEI_Event_Relation interface method
1375
-     *
1376
-     * @see EEI_Event_Relation for comments
1377
-     * @return string
1378
-     * @throws UnexpectedEntityException
1379
-     * @throws \EE_Error
1380
-     */
1373
+	/**
1374
+	 * Implementation of the EEI_Event_Relation interface method
1375
+	 *
1376
+	 * @see EEI_Event_Relation for comments
1377
+	 * @return string
1378
+	 * @throws UnexpectedEntityException
1379
+	 * @throws \EE_Error
1380
+	 */
1381 1381
 	public function get_event_name() {
1382 1382
 		$event = $this->get_related_event();
1383 1383
 		return $event instanceof EE_Event ? $event->name() : '';
@@ -1385,14 +1385,14 @@  discard block
 block discarded – undo
1385 1385
 
1386 1386
 
1387 1387
 
1388
-    /**
1389
-     * Implementation of the EEI_Event_Relation interface method
1390
-     *
1391
-     * @see EEI_Event_Relation for comments
1392
-     * @return int
1393
-     * @throws UnexpectedEntityException
1394
-     * @throws \EE_Error
1395
-     */
1388
+	/**
1389
+	 * Implementation of the EEI_Event_Relation interface method
1390
+	 *
1391
+	 * @see EEI_Event_Relation for comments
1392
+	 * @return int
1393
+	 * @throws UnexpectedEntityException
1394
+	 * @throws \EE_Error
1395
+	 */
1396 1396
 	public function get_event_ID() {
1397 1397
 		$event = $this->get_related_event();
1398 1398
 		return $event instanceof EE_Event ? $event->ID() : 0;
Please login to merge, or discard this patch.
Spacing   +203 added lines, -203 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php use EventEspresso\core\exceptions\UnexpectedEntityException;
2 2
 
3
-if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
-	exit( 'No direct script access allowed' );
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 /**
7 7
  * Event Espresso
@@ -70,9 +70,9 @@  discard block
 block discarded – undo
70 70
      * @return EE_Ticket
71 71
      * @throws \EE_Error
72 72
      */
73
-	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74
-		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75
-		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
73
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) {
74
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76 76
 	}
77 77
 
78 78
 
@@ -84,8 +84,8 @@  discard block
 block discarded – undo
84 84
      * @return EE_Ticket
85 85
      * @throws \EE_Error
86 86
      */
87
-	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88
-		return new self( $props_n_values, TRUE, $timezone );
87
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null) {
88
+		return new self($props_n_values, TRUE, $timezone);
89 89
 	}
90 90
 
91 91
 
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
      * @throws \EE_Error
96 96
      */
97 97
 	public function parent() {
98
-		return $this->get( 'TKT_parent' );
98
+		return $this->get('TKT_parent');
99 99
 	}
100 100
 
101 101
 
@@ -107,13 +107,13 @@  discard block
 block discarded – undo
107 107
      * @return boolean
108 108
      * @throws \EE_Error
109 109
      */
110
-	public function available( $DTT_ID = 0 ) {
110
+	public function available($DTT_ID = 0) {
111 111
 		// are we checking availability for a particular datetime ?
112
-		if ( $DTT_ID ) {
112
+		if ($DTT_ID) {
113 113
 			// get that datetime object
114
-			$datetime = $this->get_first_related( 'Datetime', array( array( 'DTT_ID' => $DTT_ID ) ) );
114
+			$datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID)));
115 115
 			// if  ticket sales for this datetime have exceeded the reg limit...
116
-			if ( $datetime instanceof EE_Datetime && $datetime->sold_out() ) {
116
+			if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
117 117
 				return FALSE;
118 118
 			}
119 119
 		}
@@ -131,22 +131,22 @@  discard block
 block discarded – undo
131 131
      * @return mixed status int if the display string isn't requested
132 132
      * @throws \EE_Error
133 133
      */
134
-	public function ticket_status( $display = FALSE, $remaining = null ) {
135
-		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136
-		if ( ! $remaining ) {
137
-			return $display ? EEH_Template::pretty_status( EE_Ticket::sold_out, FALSE, 'sentence' ) : EE_Ticket::sold_out;
134
+	public function ticket_status($display = FALSE, $remaining = null) {
135
+		$remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
136
+		if ( ! $remaining) {
137
+			return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, FALSE, 'sentence') : EE_Ticket::sold_out;
138 138
 		}
139
-		if ( $this->get( 'TKT_deleted' ) ) {
140
-			return $display ? EEH_Template::pretty_status( EE_Ticket::archived, FALSE, 'sentence' ) : EE_Ticket::archived;
139
+		if ($this->get('TKT_deleted')) {
140
+			return $display ? EEH_Template::pretty_status(EE_Ticket::archived, FALSE, 'sentence') : EE_Ticket::archived;
141 141
 		}
142
-		if ( $this->is_expired() ) {
143
-			return $display ? EEH_Template::pretty_status( EE_Ticket::expired, FALSE, 'sentence' ) : EE_Ticket::expired;
142
+		if ($this->is_expired()) {
143
+			return $display ? EEH_Template::pretty_status(EE_Ticket::expired, FALSE, 'sentence') : EE_Ticket::expired;
144 144
 		}
145
-		if ( $this->is_pending() ) {
146
-			return $display ? EEH_Template::pretty_status( EE_Ticket::pending, FALSE, 'sentence' ) : EE_Ticket::pending;
145
+		if ($this->is_pending()) {
146
+			return $display ? EEH_Template::pretty_status(EE_Ticket::pending, FALSE, 'sentence') : EE_Ticket::pending;
147 147
 		}
148
-		if ( $this->is_on_sale() ) {
149
-			return $display ? EEH_Template::pretty_status( EE_Ticket::onsale, FALSE, 'sentence' ) : EE_Ticket::onsale;
148
+		if ($this->is_on_sale()) {
149
+			return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, FALSE, 'sentence') : EE_Ticket::onsale;
150 150
 		}
151 151
 		return '';
152 152
 	}
@@ -161,12 +161,12 @@  discard block
 block discarded – undo
161 161
      * @return boolean         true = tickets remaining, false not.
162 162
      * @throws \EE_Error
163 163
      */
164
-	public function is_remaining( $DTT_ID = 0 ) {
165
-		$num_remaining = $this->remaining( $DTT_ID );
166
-		if ( $num_remaining === 0 ) {
164
+	public function is_remaining($DTT_ID = 0) {
165
+		$num_remaining = $this->remaining($DTT_ID);
166
+		if ($num_remaining === 0) {
167 167
 			return FALSE;
168 168
 		}
169
-		if ( $num_remaining > 0 && $num_remaining < $this->min() ) {
169
+		if ($num_remaining > 0 && $num_remaining < $this->min()) {
170 170
 			return FALSE;
171 171
 		}
172 172
 		return TRUE;
@@ -182,8 +182,8 @@  discard block
 block discarded – undo
182 182
      * @return int
183 183
      * @throws \EE_Error
184 184
      */
185
-	public function remaining( $DTT_ID = 0 ) {
186
-		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
185
+	public function remaining($DTT_ID = 0) {
186
+		return $this->real_quantity_on_ticket('saleable', $DTT_ID);
187 187
 	}
188 188
 
189 189
 
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
      * @throws \EE_Error
196 196
      */
197 197
 	public function min() {
198
-		return $this->get( 'TKT_min' );
198
+		return $this->get('TKT_min');
199 199
 	}
200 200
 
201 201
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
      * @throws \EE_Error
208 208
      */
209 209
 	public function is_expired() {
210
-		return ( $this->get_raw( 'TKT_end_date' ) < time() );
210
+		return ($this->get_raw('TKT_end_date') < time());
211 211
 	}
212 212
 
213 213
 
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
      * @throws \EE_Error
220 220
      */
221 221
 	public function is_pending() {
222
-		return ( $this->get_raw( 'TKT_start_date' ) > time() );
222
+		return ($this->get_raw('TKT_start_date') > time());
223 223
 	}
224 224
 
225 225
 
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
      * @throws \EE_Error
232 232
      */
233 233
 	public function is_on_sale() {
234
-		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
234
+		return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time());
235 235
 	}
236 236
 
237 237
 
@@ -244,11 +244,11 @@  discard block
 block discarded – undo
244 244
      * @return string
245 245
      * @throws \EE_Error
246 246
      */
247
-	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248
-		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249
-		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
247
+	public function date_range($dt_frmt = '', $conjunction = ' - ') {
248
+		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date($dt_frmt) : '';
249
+		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date($dt_frmt) : '';
250 250
 
251
-		return $first_date && $last_date ? $first_date . $conjunction  . $last_date : '';
251
+		return $first_date && $last_date ? $first_date.$conjunction.$last_date : '';
252 252
 	}
253 253
 
254 254
 
@@ -260,8 +260,8 @@  discard block
 block discarded – undo
260 260
      * @throws \EE_Error
261 261
      */
262 262
 	public function first_datetime() {
263
-		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264
-		return reset( $datetimes );
263
+		$datetimes = $this->datetimes(array('limit' => 1));
264
+		return reset($datetimes);
265 265
 	}
266 266
 
267 267
 
@@ -274,11 +274,11 @@  discard block
 block discarded – undo
274 274
      * @return EE_Datetime[]|EE_Base_Class[]
275 275
      * @throws \EE_Error
276 276
      */
277
-	public function datetimes( $query_params = array() ) {
278
-		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279
-			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
277
+	public function datetimes($query_params = array()) {
278
+		if ( ! isset($query_params['order_by'])) {
279
+			$query_params['order_by']['DTT_order'] = 'ASC';
280 280
 		}
281
-		return $this->get_many_related( 'Datetime', $query_params );
281
+		return $this->get_many_related('Datetime', $query_params);
282 282
 	}
283 283
 
284 284
 
@@ -290,8 +290,8 @@  discard block
 block discarded – undo
290 290
      * @throws \EE_Error
291 291
      */
292 292
 	public function last_datetime() {
293
-		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294
-		return end( $datetimes );
293
+		$datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC')));
294
+		return end($datetimes);
295 295
 	}
296 296
 
297 297
 
@@ -309,22 +309,22 @@  discard block
 block discarded – undo
309 309
      * @return mixed (array|int)          how many tickets have sold
310 310
      * @throws \EE_Error
311 311
      */
312
-	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
312
+	public function tickets_sold($what = 'ticket', $dtt_id = NULL) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
315
-		switch ( $what ) {
315
+		switch ($what) {
316 316
 			case 'ticket' :
317
-				return $tickets_sold[ 'ticket' ];
317
+				return $tickets_sold['ticket'];
318 318
 				break;
319 319
 			case 'datetime' :
320
-				if ( empty( $tickets_sold[ 'datetime' ] ) ) {
320
+				if (empty($tickets_sold['datetime'])) {
321 321
 					return $total;
322 322
 				}
323
-				if ( ! empty( $dtt_id ) && ! isset( $tickets_sold[ 'datetime' ][ $dtt_id ] ) ) {
324
-					EE_Error::add_error( __( '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?', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
323
+				if ( ! empty($dtt_id) && ! isset($tickets_sold['datetime'][$dtt_id])) {
324
+					EE_Error::add_error(__('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?', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
325 325
 					return $total;
326 326
 				}
327
-				return empty( $dtt_id ) ? $tickets_sold[ 'datetime' ] : $tickets_sold[ 'datetime' ][ $dtt_id ];
327
+				return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][$dtt_id];
328 328
 				break;
329 329
 			default:
330 330
 				return $total;
@@ -340,15 +340,15 @@  discard block
 block discarded – undo
340 340
      * @throws \EE_Error
341 341
      */
342 342
 	protected function _all_tickets_sold() {
343
-		$datetimes = $this->get_many_related( 'Datetime' );
343
+		$datetimes = $this->get_many_related('Datetime');
344 344
 		$tickets_sold = array();
345
-		if ( ! empty( $datetimes ) ) {
346
-			foreach ( $datetimes as $datetime ) {
347
-				$tickets_sold[ 'datetime' ][ $datetime->ID() ] = $datetime->get( 'DTT_sold' );
345
+		if ( ! empty($datetimes)) {
346
+			foreach ($datetimes as $datetime) {
347
+				$tickets_sold['datetime'][$datetime->ID()] = $datetime->get('DTT_sold');
348 348
 			}
349 349
 		}
350 350
 		//Tickets sold
351
-		$tickets_sold[ 'ticket' ] = $this->sold();
351
+		$tickets_sold['ticket'] = $this->sold();
352 352
 		return $tickets_sold;
353 353
 	}
354 354
 
@@ -361,11 +361,11 @@  discard block
 block discarded – undo
361 361
      * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362 362
      * @throws \EE_Error
363 363
      */
364
-	public function base_price( $return_array = FALSE ) {
365
-		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
364
+	public function base_price($return_array = FALSE) {
365
+		$_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price);
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+            ? $this->get_many_related('Price', array($_where))
368
+            : $this->get_first_related('Price', array($_where));
369 369
 	}
370 370
 
371 371
 
@@ -378,8 +378,8 @@  discard block
 block discarded – undo
378 378
      * @throws \EE_Error
379 379
      */
380 380
 	public function price_modifiers() {
381
-		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382
-		return $this->prices( $query_params );
381
+		$query_params = array(0 => array('Price_Type.PBT_ID' => array('NOT IN', array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax))));
382
+		return $this->prices($query_params);
383 383
 	}
384 384
 
385 385
 
@@ -391,8 +391,8 @@  discard block
 block discarded – undo
391 391
      * @return EE_Price[]|EE_Base_Class[]
392 392
      * @throws \EE_Error
393 393
      */
394
-	public function prices( $query_params = array() ) {
395
-		return $this->get_many_related( 'Price', $query_params );
394
+	public function prices($query_params = array()) {
395
+		return $this->get_many_related('Price', $query_params);
396 396
 	}
397 397
 
398 398
 
@@ -404,8 +404,8 @@  discard block
 block discarded – undo
404 404
      * @return EE_Datetime_Ticket|EE_Base_Class[]
405 405
      * @throws \EE_Error
406 406
      */
407
-	public function datetime_tickets( $query_params = array() ) {
408
-		return $this->get_many_related( 'Datetime_Ticket', $query_params );
407
+	public function datetime_tickets($query_params = array()) {
408
+		return $this->get_many_related('Datetime_Ticket', $query_params);
409 409
 	}
410 410
 
411 411
 
@@ -418,8 +418,8 @@  discard block
 block discarded – undo
418 418
      * @return EE_Datetime[]
419 419
      * @throws \EE_Error
420 420
      */
421
-	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422
-		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
421
+	public function datetimes_ordered($show_expired = TRUE, $show_deleted = FALSE) {
422
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order($this->ID(), $show_expired, $show_deleted);
423 423
 	}
424 424
 
425 425
 
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
      * @throws \EE_Error
432 432
      */
433 433
 	public function ID() {
434
-		return $this->get( 'TKT_ID' );
434
+		return $this->get('TKT_ID');
435 435
 	}
436 436
 
437 437
 
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      * @throws \EE_Error
457 457
      */
458 458
 	public function template() {
459
-		return $this->get_first_related( 'Ticket_Template' );
459
+		return $this->get_first_related('Ticket_Template');
460 460
 	}
461 461
 
462 462
 
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
      * @throws \EE_Error
479 479
      */
480 480
 	public function ticket_price() {
481
-		return $this->get( 'TKT_price' );
481
+		return $this->get('TKT_price');
482 482
 	}
483 483
 
484 484
 
@@ -488,7 +488,7 @@  discard block
 block discarded – undo
488 488
      * @throws \EE_Error
489 489
      */
490 490
 	public function pretty_price() {
491
-		return $this->get_pretty( 'TKT_price' );
491
+		return $this->get_pretty('TKT_price');
492 492
 	}
493 493
 
494 494
 
@@ -510,8 +510,8 @@  discard block
 block discarded – undo
510 510
      * @return float
511 511
      * @throws \EE_Error
512 512
      */
513
-	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514
-		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
513
+	public function get_ticket_total_with_taxes($no_cache = FALSE) {
514
+		if ($this->_ticket_total_with_taxes === null || $no_cache) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
516 516
 		}
517 517
 		return (float) $this->_ticket_total_with_taxes;
@@ -520,7 +520,7 @@  discard block
 block discarded – undo
520 520
 
521 521
 
522 522
 	public function ensure_TKT_Price_correct() {
523
-		$this->set( 'TKT_price', EE_Taxes::get_subtotal_for_admin( $this ) );
523
+		$this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
524 524
 		$this->save();
525 525
 	}
526 526
 
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
      * @throws \EE_Error
532 532
      */
533 533
 	public function get_ticket_subtotal() {
534
-		return EE_Taxes::get_subtotal_for_admin( $this );
534
+		return EE_Taxes::get_subtotal_for_admin($this);
535 535
 	}
536 536
 
537 537
 
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
      * @throws \EE_Error
544 544
      */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546
-		return EE_Taxes::get_total_taxes_for_admin( $this );
546
+		return EE_Taxes::get_total_taxes_for_admin($this);
547 547
 	}
548 548
 
549 549
 
@@ -554,8 +554,8 @@  discard block
 block discarded – undo
554 554
      * @param string $name
555 555
      * @throws \EE_Error
556 556
      */
557
-	public function set_name( $name ) {
558
-		$this->set( 'TKT_name', $name );
557
+	public function set_name($name) {
558
+		$this->set('TKT_name', $name);
559 559
 	}
560 560
 
561 561
 
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
      * @throws \EE_Error
568 568
      */
569 569
 	public function description() {
570
-		return $this->get( 'TKT_description' );
570
+		return $this->get('TKT_description');
571 571
 	}
572 572
 
573 573
 
@@ -578,8 +578,8 @@  discard block
 block discarded – undo
578 578
      * @param string $description
579 579
      * @throws \EE_Error
580 580
      */
581
-	public function set_description( $description ) {
582
-		$this->set( 'TKT_description', $description );
581
+	public function set_description($description) {
582
+		$this->set('TKT_description', $description);
583 583
 	}
584 584
 
585 585
 
@@ -592,8 +592,8 @@  discard block
 block discarded – undo
592 592
      * @return string
593 593
      * @throws \EE_Error
594 594
      */
595
-	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596
-		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
595
+	public function start_date($dt_frmt = '', $tm_frmt = '') {
596
+		return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt);
597 597
 	}
598 598
 
599 599
 
@@ -605,8 +605,8 @@  discard block
 block discarded – undo
605 605
      * @return void
606 606
      * @throws \EE_Error
607 607
      */
608
-	public function set_start_date( $start_date ) {
609
-		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
608
+	public function set_start_date($start_date) {
609
+		$this->_set_date_time('B', $start_date, 'TKT_start_date');
610 610
 	}
611 611
 
612 612
 
@@ -619,8 +619,8 @@  discard block
 block discarded – undo
619 619
      * @return string
620 620
      * @throws \EE_Error
621 621
      */
622
-	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623
-		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
622
+	public function end_date($dt_frmt = '', $tm_frmt = '') {
623
+		return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt);
624 624
 	}
625 625
 
626 626
 
@@ -632,8 +632,8 @@  discard block
 block discarded – undo
632 632
      * @return void
633 633
      * @throws \EE_Error
634 634
      */
635
-	public function set_end_date( $end_date ) {
636
-		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
635
+	public function set_end_date($end_date) {
636
+		$this->_set_date_time('B', $end_date, 'TKT_end_date');
637 637
 	}
638 638
 
639 639
 
@@ -645,8 +645,8 @@  discard block
 block discarded – undo
645 645
      * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646 646
      * @throws \EE_Error
647 647
      */
648
-	public function set_end_time( $time ) {
649
-		$this->_set_time_for( $time, 'TKT_end_date' );
648
+	public function set_end_time($time) {
649
+		$this->_set_time_for($time, 'TKT_end_date');
650 650
 	}
651 651
 
652 652
 
@@ -658,8 +658,8 @@  discard block
 block discarded – undo
658 658
      * @return void
659 659
      * @throws \EE_Error
660 660
      */
661
-	public function set_min( $min ) {
662
-		$this->set( 'TKT_min', $min );
661
+	public function set_min($min) {
662
+		$this->set('TKT_min', $min);
663 663
 	}
664 664
 
665 665
 
@@ -671,7 +671,7 @@  discard block
 block discarded – undo
671 671
      * @throws \EE_Error
672 672
      */
673 673
 	public function max() {
674
-		return $this->get( 'TKT_max' );
674
+		return $this->get('TKT_max');
675 675
 	}
676 676
 
677 677
 
@@ -683,8 +683,8 @@  discard block
 block discarded – undo
683 683
      * @return void
684 684
      * @throws \EE_Error
685 685
      */
686
-	public function set_max( $max ) {
687
-		$this->set( 'TKT_max', $max );
686
+	public function set_max($max) {
687
+		$this->set('TKT_max', $max);
688 688
 	}
689 689
 
690 690
 
@@ -696,8 +696,8 @@  discard block
 block discarded – undo
696 696
      * @return void
697 697
      * @throws \EE_Error
698 698
      */
699
-	public function set_price( $price ) {
700
-		$this->set( 'TKT_price', $price );
699
+	public function set_price($price) {
700
+		$this->set('TKT_price', $price);
701 701
 	}
702 702
 
703 703
 
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
      * @throws \EE_Error
710 710
      */
711 711
 	public function sold() {
712
-		return $this->get_raw( 'TKT_sold' );
712
+		return $this->get_raw('TKT_sold');
713 713
 	}
714 714
 
715 715
 
@@ -721,10 +721,10 @@  discard block
 block discarded – undo
721 721
      * @return void
722 722
      * @throws \EE_Error
723 723
      */
724
-	public function set_sold( $sold ) {
724
+	public function set_sold($sold) {
725 725
 		// sold can not go below zero
726
-		$sold = max( 0, $sold );
727
-		$this->set( 'TKT_sold', $sold );
726
+		$sold = max(0, $sold);
727
+		$this->set('TKT_sold', $sold);
728 728
 	}
729 729
 
730 730
 
@@ -736,13 +736,13 @@  discard block
 block discarded – undo
736 736
      * @return void
737 737
      * @throws \EE_Error
738 738
      */
739
-	public function increase_sold( $qty = 1 ) {
739
+	public function increase_sold($qty = 1) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
742 742
 		// via \EE_Datetime::increase_sold() when \EE_Ticket::_increase_sold_for_datetimes() is called
743
-		$this->decrease_reserved( $qty, false );
744
-		$this->_increase_sold_for_datetimes( $qty );
745
-		$this->set_sold( $sold );
743
+		$this->decrease_reserved($qty, false);
744
+		$this->_increase_sold_for_datetimes($qty);
745
+		$this->set_sold($sold);
746 746
 	}
747 747
 
748 748
 
@@ -754,12 +754,12 @@  discard block
 block discarded – undo
754 754
      * @return void
755 755
      * @throws \EE_Error
756 756
      */
757
-	protected function _increase_sold_for_datetimes( $qty = 1 ) {
757
+	protected function _increase_sold_for_datetimes($qty = 1) {
758 758
 		$datetimes = $this->datetimes();
759
-		if ( is_array( $datetimes ) ) {
760
-			foreach ( $datetimes as $datetime ) {
761
-				if ( $datetime instanceof EE_Datetime ) {
762
-					$datetime->increase_sold( $qty );
759
+		if (is_array($datetimes)) {
760
+			foreach ($datetimes as $datetime) {
761
+				if ($datetime instanceof EE_Datetime) {
762
+					$datetime->increase_sold($qty);
763 763
 					$datetime->save();
764 764
 				}
765 765
 			}
@@ -775,10 +775,10 @@  discard block
 block discarded – undo
775 775
      * @return void
776 776
      * @throws \EE_Error
777 777
      */
778
-	public function decrease_sold( $qty = 1 ) {
778
+	public function decrease_sold($qty = 1) {
779 779
 		$sold = $this->sold() - $qty;
780
-		$this->_decrease_sold_for_datetimes( $qty );
781
-		$this->set_sold( $sold );
780
+		$this->_decrease_sold_for_datetimes($qty);
781
+		$this->set_sold($sold);
782 782
 	}
783 783
 
784 784
 
@@ -790,12 +790,12 @@  discard block
 block discarded – undo
790 790
      * @return void
791 791
      * @throws \EE_Error
792 792
      */
793
-	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
793
+	protected function _decrease_sold_for_datetimes($qty = 1) {
794 794
 		$datetimes = $this->datetimes();
795
-		if ( is_array( $datetimes ) ) {
796
-			foreach ( $datetimes as $datetime ) {
797
-				if ( $datetime instanceof EE_Datetime ) {
798
-					$datetime->decrease_sold( $qty );
795
+		if (is_array($datetimes)) {
796
+			foreach ($datetimes as $datetime) {
797
+				if ($datetime instanceof EE_Datetime) {
798
+					$datetime->decrease_sold($qty);
799 799
 					$datetime->save();
800 800
 				}
801 801
 			}
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
      * @throws \EE_Error
812 812
      */
813 813
 	public function reserved() {
814
-		return $this->get_raw( 'TKT_reserved' );
814
+		return $this->get_raw('TKT_reserved');
815 815
 	}
816 816
 
817 817
 
@@ -823,10 +823,10 @@  discard block
 block discarded – undo
823 823
      * @return void
824 824
      * @throws \EE_Error
825 825
      */
826
-	public function set_reserved( $reserved ) {
826
+	public function set_reserved($reserved) {
827 827
 		// reserved can not go below zero
828
-		$reserved = max( 0, (int) $reserved );
829
-		$this->set( 'TKT_reserved', $reserved );
828
+		$reserved = max(0, (int) $reserved);
829
+		$this->set('TKT_reserved', $reserved);
830 830
 	}
831 831
 
832 832
 
@@ -838,11 +838,11 @@  discard block
 block discarded – undo
838 838
      * @return void
839 839
      * @throws \EE_Error
840 840
      */
841
-	public function increase_reserved( $qty = 1 ) {
842
-		$qty = absint( $qty );
841
+	public function increase_reserved($qty = 1) {
842
+		$qty = absint($qty);
843 843
 		$reserved = $this->reserved() + $qty;
844
-		$this->_increase_reserved_for_datetimes( $qty );
845
-		$this->set_reserved( $reserved );
844
+		$this->_increase_reserved_for_datetimes($qty);
845
+		$this->set_reserved($reserved);
846 846
 	}
847 847
 
848 848
 
@@ -854,12 +854,12 @@  discard block
 block discarded – undo
854 854
      * @return void
855 855
      * @throws \EE_Error
856 856
      */
857
-	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
857
+	protected function _increase_reserved_for_datetimes($qty = 1) {
858 858
 		$datetimes = $this->datetimes();
859
-		if ( is_array( $datetimes ) ) {
860
-			foreach ( $datetimes as $datetime ) {
861
-				if ( $datetime instanceof EE_Datetime ) {
862
-					$datetime->increase_reserved( $qty );
859
+		if (is_array($datetimes)) {
860
+			foreach ($datetimes as $datetime) {
861
+				if ($datetime instanceof EE_Datetime) {
862
+					$datetime->increase_reserved($qty);
863 863
 					$datetime->save();
864 864
 				}
865 865
 			}
@@ -876,12 +876,12 @@  discard block
 block discarded – undo
876 876
      * @return void
877 877
      * @throws \EE_Error
878 878
      */
879
-	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
880
-		$reserved = $this->reserved() - absint( $qty );
881
-		if ( $adjust_datetimes ) {
882
-			$this->_decrease_reserved_for_datetimes( $qty );
879
+	public function decrease_reserved($qty = 1, $adjust_datetimes = true) {
880
+		$reserved = $this->reserved() - absint($qty);
881
+		if ($adjust_datetimes) {
882
+			$this->_decrease_reserved_for_datetimes($qty);
883 883
 		}
884
-		$this->set_reserved( $reserved );
884
+		$this->set_reserved($reserved);
885 885
 	}
886 886
 
887 887
 
@@ -893,12 +893,12 @@  discard block
 block discarded – undo
893 893
      * @return void
894 894
      * @throws \EE_Error
895 895
      */
896
-	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
896
+	protected function _decrease_reserved_for_datetimes($qty = 1) {
897 897
 		$datetimes = $this->datetimes();
898
-		if ( is_array( $datetimes ) ) {
899
-			foreach ( $datetimes as $datetime ) {
900
-				if ( $datetime instanceof EE_Datetime ) {
901
-					$datetime->decrease_reserved( $qty );
898
+		if (is_array($datetimes)) {
899
+			foreach ($datetimes as $datetime) {
900
+				if ($datetime instanceof EE_Datetime) {
901
+					$datetime->decrease_reserved($qty);
902 902
 					$datetime->save();
903 903
 				}
904 904
 			}
@@ -919,14 +919,14 @@  discard block
 block discarded – undo
919 919
      * @return int
920 920
      * @throws \EE_Error
921 921
      */
922
-	public function qty( $context = '' ) {
923
-		switch ( $context ) {
922
+	public function qty($context = '') {
923
+		switch ($context) {
924 924
 			case 'reg_limit' :
925 925
 				return $this->real_quantity_on_ticket();
926 926
 			case 'saleable' :
927
-				return $this->real_quantity_on_ticket( 'saleable' );
927
+				return $this->real_quantity_on_ticket('saleable');
928 928
 			default:
929
-				return $this->get_raw( 'TKT_qty' );
929
+				return $this->get_raw('TKT_qty');
930 930
 		}
931 931
 	}
932 932
 
@@ -945,16 +945,16 @@  discard block
 block discarded – undo
945 945
      * @return int
946 946
      * @throws \EE_Error
947 947
      */
948
-	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
949
-		$raw = $this->get_raw( 'TKT_qty' );
948
+	public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0) {
949
+		$raw = $this->get_raw('TKT_qty');
950 950
 		// return immediately if it's zero
951
-		if ( $raw === 0 ) {
951
+		if ($raw === 0) {
952 952
 			return $raw;
953 953
 		}
954 954
 		// echo is_admin() && ! did_action('admin_notices') ? '<div style="margin-left:180px;">' : '';
955 955
 		// echo "\n\n<br />" . $this->ID() . ') Ticket: ' . $this->name() . '<br />';
956 956
 		// ensure qty doesn't exceed raw value for THIS ticket
957
-		$qty = min( EE_INF, $raw );
957
+		$qty = min(EE_INF, $raw);
958 958
 		// echo "\n . qty: " . $qty . '<br />';
959 959
 		// calculate this ticket's total sales and reservations
960 960
 		$sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
@@ -963,23 +963,23 @@  discard block
 block discarded – undo
963 963
 		// echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
964 964
 		// first we need to calculate the maximum number of tickets available for the datetime
965 965
 		// do we want data for one datetime or all of them ?
966
-		$query_params = $DTT_ID ? array( array( 'DTT_ID' => $DTT_ID ) ) : array();
967
-		$datetimes = $this->datetimes( $query_params );
968
-		if ( is_array( $datetimes ) && ! empty( $datetimes ) ) {
969
-			foreach ( $datetimes as $datetime ) {
970
-				if ( $datetime instanceof EE_Datetime ) {
966
+		$query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array();
967
+		$datetimes = $this->datetimes($query_params);
968
+		if (is_array($datetimes) && ! empty($datetimes)) {
969
+			foreach ($datetimes as $datetime) {
970
+				if ($datetime instanceof EE_Datetime) {
971 971
 					$datetime->refresh_from_db();
972 972
 					// echo "\n . . datetime name: " . $datetime->name() . '<br />';
973 973
 					// echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
974 974
 					// initialize with no restrictions for each datetime
975 975
 					// but adjust datetime qty based on datetime reg limit
976
-					$datetime_qty = min( EE_INF, $datetime->reg_limit() );
976
+					$datetime_qty = min(EE_INF, $datetime->reg_limit());
977 977
 					// echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
978 978
 					// echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
979 979
 					// if we want the actual saleable amount, then we need to consider OTHER ticket sales
980 980
 					// and reservations for this datetime, that do NOT include sales and reservations
981 981
 					// for this ticket (so we add $this->sold() and $this->reserved() back in)
982
-					if ( $context === 'saleable' ) {
982
+					if ($context === 'saleable') {
983 983
 						$datetime_qty = max(
984 984
 							$datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
985 985
 							0
@@ -991,16 +991,16 @@  discard block
 block discarded – undo
991 991
 						$datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
992 992
 						// echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
993 993
 					}
994
-					$qty = min( $datetime_qty, $qty );
994
+					$qty = min($datetime_qty, $qty);
995 995
 					// echo "\n . . qty: " . $qty . '<br />';
996 996
 				}
997 997
 			}
998 998
 		}
999 999
 		// NOW that we know the  maximum number of tickets available for the datetime
1000 1000
 		// we can finally factor in the details for this specific ticket
1001
-		if ( $qty > 0 && $context === 'saleable' ) {
1001
+		if ($qty > 0 && $context === 'saleable') {
1002 1002
 			// and subtract the sales for THIS ticket
1003
-			$qty = max( $qty - $sold_and_reserved_for_this_ticket, 0 );
1003
+			$qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1004 1004
 			// echo "\n . qty: " . $qty . '<br />';
1005 1005
 		}
1006 1006
         // echo "\nFINAL QTY: " . $qty . "<br /><br />";
@@ -1017,14 +1017,14 @@  discard block
 block discarded – undo
1017 1017
 	 * @return void
1018 1018
 	 * @throws \EE_Error
1019 1019
 	 */
1020
-	public function set_qty( $qty ) {
1020
+	public function set_qty($qty) {
1021 1021
 		$datetimes = $this->datetimes();
1022
-		foreach ( $datetimes as $datetime ) {
1023
-			if ( $datetime instanceof EE_Datetime ) {
1024
-				$qty = min( $qty, $datetime->reg_limit() );
1022
+		foreach ($datetimes as $datetime) {
1023
+			if ($datetime instanceof EE_Datetime) {
1024
+				$qty = min($qty, $datetime->reg_limit());
1025 1025
 			}
1026 1026
 		}
1027
-		$this->set( 'TKT_qty', $qty );
1027
+		$this->set('TKT_qty', $qty);
1028 1028
 	}
1029 1029
 
1030 1030
 
@@ -1036,7 +1036,7 @@  discard block
 block discarded – undo
1036 1036
      * @throws \EE_Error
1037 1037
      */
1038 1038
 	public function uses() {
1039
-		return $this->get( 'TKT_uses' );
1039
+		return $this->get('TKT_uses');
1040 1040
 	}
1041 1041
 
1042 1042
 
@@ -1048,8 +1048,8 @@  discard block
 block discarded – undo
1048 1048
      * @return void
1049 1049
      * @throws \EE_Error
1050 1050
      */
1051
-	public function set_uses( $uses ) {
1052
-		$this->set( 'TKT_uses', $uses );
1051
+	public function set_uses($uses) {
1052
+		$this->set('TKT_uses', $uses);
1053 1053
 	}
1054 1054
 
1055 1055
 
@@ -1061,7 +1061,7 @@  discard block
 block discarded – undo
1061 1061
      * @throws \EE_Error
1062 1062
      */
1063 1063
 	public function required() {
1064
-		return $this->get( 'TKT_required' );
1064
+		return $this->get('TKT_required');
1065 1065
 	}
1066 1066
 
1067 1067
 
@@ -1073,8 +1073,8 @@  discard block
 block discarded – undo
1073 1073
      * @return void
1074 1074
      * @throws \EE_Error
1075 1075
      */
1076
-	public function set_required( $required ) {
1077
-		$this->set( 'TKT_required', $required );
1076
+	public function set_required($required) {
1077
+		$this->set('TKT_required', $required);
1078 1078
 	}
1079 1079
 
1080 1080
 
@@ -1086,7 +1086,7 @@  discard block
 block discarded – undo
1086 1086
      * @throws \EE_Error
1087 1087
      */
1088 1088
 	public function taxable() {
1089
-		return $this->get( 'TKT_taxable' );
1089
+		return $this->get('TKT_taxable');
1090 1090
 	}
1091 1091
 
1092 1092
 
@@ -1098,8 +1098,8 @@  discard block
 block discarded – undo
1098 1098
      * @return void
1099 1099
      * @throws \EE_Error
1100 1100
      */
1101
-	public function set_taxable( $taxable ) {
1102
-		$this->set( 'TKT_taxable', $taxable );
1101
+	public function set_taxable($taxable) {
1102
+		$this->set('TKT_taxable', $taxable);
1103 1103
 	}
1104 1104
 
1105 1105
 
@@ -1111,7 +1111,7 @@  discard block
 block discarded – undo
1111 1111
      * @throws \EE_Error
1112 1112
      */
1113 1113
 	public function is_default() {
1114
-		return $this->get( 'TKT_is_default' );
1114
+		return $this->get('TKT_is_default');
1115 1115
 	}
1116 1116
 
1117 1117
 
@@ -1123,8 +1123,8 @@  discard block
 block discarded – undo
1123 1123
      * @return void
1124 1124
      * @throws \EE_Error
1125 1125
      */
1126
-	public function set_is_default( $is_default ) {
1127
-		$this->set( 'TKT_is_default', $is_default );
1126
+	public function set_is_default($is_default) {
1127
+		$this->set('TKT_is_default', $is_default);
1128 1128
 	}
1129 1129
 
1130 1130
 
@@ -1136,7 +1136,7 @@  discard block
 block discarded – undo
1136 1136
      * @throws \EE_Error
1137 1137
      */
1138 1138
 	public function order() {
1139
-		return $this->get( 'TKT_order' );
1139
+		return $this->get('TKT_order');
1140 1140
 	}
1141 1141
 
1142 1142
 
@@ -1148,8 +1148,8 @@  discard block
 block discarded – undo
1148 1148
      * @return void
1149 1149
      * @throws \EE_Error
1150 1150
      */
1151
-	public function set_order( $order ) {
1152
-		$this->set( 'TKT_order', $order );
1151
+	public function set_order($order) {
1152
+		$this->set('TKT_order', $order);
1153 1153
 	}
1154 1154
 
1155 1155
 
@@ -1161,7 +1161,7 @@  discard block
 block discarded – undo
1161 1161
      * @throws \EE_Error
1162 1162
      */
1163 1163
 	public function row() {
1164
-		return $this->get( 'TKT_row' );
1164
+		return $this->get('TKT_row');
1165 1165
 	}
1166 1166
 
1167 1167
 
@@ -1173,8 +1173,8 @@  discard block
 block discarded – undo
1173 1173
      * @return void
1174 1174
      * @throws \EE_Error
1175 1175
      */
1176
-	public function set_row( $row ) {
1177
-		$this->set( 'TKT_row', $row );
1176
+	public function set_row($row) {
1177
+		$this->set('TKT_row', $row);
1178 1178
 	}
1179 1179
 
1180 1180
 
@@ -1186,7 +1186,7 @@  discard block
 block discarded – undo
1186 1186
      * @throws \EE_Error
1187 1187
      */
1188 1188
 	public function deleted() {
1189
-		return $this->get( 'TKT_deleted' );
1189
+		return $this->get('TKT_deleted');
1190 1190
 	}
1191 1191
 
1192 1192
 
@@ -1198,8 +1198,8 @@  discard block
 block discarded – undo
1198 1198
      * @return void
1199 1199
      * @throws \EE_Error
1200 1200
      */
1201
-	public function set_deleted( $deleted ) {
1202
-		$this->set( 'TKT_deleted', $deleted );
1201
+	public function set_deleted($deleted) {
1202
+		$this->set('TKT_deleted', $deleted);
1203 1203
 	}
1204 1204
 
1205 1205
 
@@ -1211,7 +1211,7 @@  discard block
 block discarded – undo
1211 1211
      * @throws \EE_Error
1212 1212
      */
1213 1213
 	public function parent_ID() {
1214
-		return $this->get( 'TKT_parent' );
1214
+		return $this->get('TKT_parent');
1215 1215
 	}
1216 1216
 
1217 1217
 
@@ -1223,8 +1223,8 @@  discard block
 block discarded – undo
1223 1223
      * @return void
1224 1224
      * @throws \EE_Error
1225 1225
      */
1226
-	public function set_parent_ID( $parent ) {
1227
-		$this->set( 'TKT_parent', $parent );
1226
+	public function set_parent_ID($parent) {
1227
+		$this->set('TKT_parent', $parent);
1228 1228
 	}
1229 1229
 
1230 1230
 
@@ -1237,10 +1237,10 @@  discard block
 block discarded – undo
1237 1237
      */
1238 1238
 	public function name_and_info() {
1239 1239
 		$times = array();
1240
-		foreach ( $this->datetimes() as $datetime ) {
1240
+		foreach ($this->datetimes() as $datetime) {
1241 1241
 			$times[] = $datetime->start_date_and_time();
1242 1242
 		}
1243
-		return $this->name() . ' @ ' . implode( ', ', $times ) . ' for ' . $this->pretty_price();
1243
+		return $this->name().' @ '.implode(', ', $times).' for '.$this->pretty_price();
1244 1244
 	}
1245 1245
 
1246 1246
 
@@ -1252,7 +1252,7 @@  discard block
 block discarded – undo
1252 1252
      * @throws \EE_Error
1253 1253
      */
1254 1254
 	public function name() {
1255
-		return $this->get( 'TKT_name' );
1255
+		return $this->get('TKT_name');
1256 1256
 	}
1257 1257
 
1258 1258
 
@@ -1264,7 +1264,7 @@  discard block
 block discarded – undo
1264 1264
      * @throws \EE_Error
1265 1265
      */
1266 1266
 	public function price() {
1267
-		return $this->get( 'TKT_price' );
1267
+		return $this->get('TKT_price');
1268 1268
 	}
1269 1269
 
1270 1270
 
@@ -1276,8 +1276,8 @@  discard block
 block discarded – undo
1276 1276
      * @return EE_Registration[]|EE_Base_Class[]
1277 1277
      * @throws \EE_Error
1278 1278
      */
1279
-	public function registrations( $query_params = array() ) {
1280
-		return $this->get_many_related( 'Registration', $query_params );
1279
+	public function registrations($query_params = array()) {
1280
+		return $this->get_many_related('Registration', $query_params);
1281 1281
 	}
1282 1282
 
1283 1283
 
@@ -1316,7 +1316,7 @@  discard block
 block discarded – undo
1316 1316
 	 * @param array $query_params like EEM_Base::get_all's
1317 1317
 	 * @return int
1318 1318
 	 */
1319
-	public function count_registrations( $query_params = array() ) {
1319
+	public function count_registrations($query_params = array()) {
1320 1320
 		return $this->count_related('Registration', $query_params);
1321 1321
 	}
1322 1322
 
@@ -1344,23 +1344,23 @@  discard block
 block discarded – undo
1344 1344
 	public function get_related_event() {
1345 1345
 		//get one datetime to use for getting the event
1346 1346
 		$datetime = $this->first_datetime();
1347
-		if ( ! $datetime instanceof \EE_Datetime ) {
1347
+		if ( ! $datetime instanceof \EE_Datetime) {
1348 1348
 			throw new UnexpectedEntityException(
1349 1349
 				$datetime,
1350 1350
                 'EE_Datetime',
1351 1351
 				sprintf(
1352
-					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1352
+					__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1353 1353
 					$this->name()
1354 1354
 				)
1355 1355
 			);
1356 1356
 		}
1357 1357
 		$event = $datetime->event();
1358
-		if ( ! $event instanceof \EE_Event ) {
1358
+		if ( ! $event instanceof \EE_Event) {
1359 1359
 			throw new UnexpectedEntityException(
1360 1360
 				$event,
1361 1361
                 'EE_Event',
1362 1362
 				sprintf(
1363
-					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1363
+					__('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1364 1364
 					$this->name()
1365 1365
 				)
1366 1366
 			);
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/espresso_events_Pricing_Hooks.class.php 1 patch
Indentation   +1533 added lines, -1533 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 /**
@@ -31,1538 +31,1538 @@  discard block
 block discarded – undo
31 31
 class espresso_events_Pricing_Hooks extends EE_Admin_Hooks
32 32
 {
33 33
 
34
-    /**
35
-     * This property is just used to hold the status of whether an event is currently being
36
-     * created (true) or edited (false)
37
-     * @access protected
38
-     * @var bool
39
-     */
40
-    protected $_is_creating_event;
41
-
42
-
43
-    /**
44
-     * Used to contain the format strings for date and time that will be used for php date and
45
-     * time.
46
-     *
47
-     * Is set in the _set_hooks_properties() method.
48
-     *
49
-     * @var array
50
-     */
51
-    protected $_date_format_strings;
52
-
53
-
54
-    protected function _set_hooks_properties()
55
-    {
56
-        $this->_name = 'pricing';
57
-
58
-        //capability check
59
-        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_default_prices',
60
-            'advanced_ticket_datetime_metabox')
61
-        ) {
62
-            return;
63
-        }
64
-
65
-
66
-        //if we were going to add our own metaboxes we'd use the below.
67
-        $this->_metaboxes = array(
68
-            0 => array(
69
-                'page_route' => array('edit', 'create_new'),
70
-                'func'       => 'pricing_metabox',
71
-                'label'      => __('Event Tickets & Datetimes', 'event_espresso'),
72
-                'priority'   => 'high',
73
-                'context'    => 'normal'
74
-            ),
75
-
76
-        );/**/
77
-
78
-        $this->_remove_metaboxes = array(
79
-            0 => array(
80
-                'page_route' => array('edit', 'create_new'),
81
-                'id'         => 'espresso_event_editor_tickets',
82
-                'context'    => 'normal'
83
-            )
84
-        );
85
-
86
-        /**
87
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
88
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
89
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
90
-         *
91
-         * @since 4.6.7
92
-         *
93
-         * @var array  Expected an array returned with 'date' and 'time' keys.
94
-         */
95
-        $this->_date_format_strings = apply_filters('FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
96
-            array(
97
-                'date' => 'Y-m-d',
98
-                'time' => 'h:i a'
99
-            ));
100
-
101
-        //validate
102
-        $this->_date_format_strings['date'] = isset($this->_date_format_strings['date']) ? $this->_date_format_strings['date'] : null;
103
-        $this->_date_format_strings['time'] = isset($this->_date_format_strings['time']) ? $this->_date_format_strings['time'] : null;
104
-
105
-        //validate format strings
106
-        $format_validation = EEH_DTT_Helper::validate_format_string($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
107
-        if (is_array($format_validation)) {
108
-            $msg = '<p>' . sprintf(__('The format "%s" was likely added via a filter and is invalid for the following reasons:',
109
-                    'event_espresso'),
110
-                    $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']) . '</p><ul>';
111
-            foreach ($format_validation as $error) {
112
-                $msg .= '<li>' . $error . '</li>';
113
-            }
114
-            $msg .= '</ul></p><p>' . sprintf(__('%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
115
-                    'event_espresso'), '<span style="color:#D54E21;">', '</span>') . '</p>';
116
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
117
-            $this->_date_format_strings = array(
118
-                'date' => 'Y-m-d',
119
-                'time' => 'h:i a'
120
-            );
121
-        }
122
-
123
-
124
-        $this->_scripts_styles = array(
125
-            'registers'   => array(
126
-                'ee-tickets-datetimes-css' => array(
127
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
128
-                    'type' => 'css'
129
-                ),
130
-                'ee-dtt-ticket-metabox'    => array(
131
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
132
-                    'depends' => array('ee-datepicker', 'ee-dialog', 'underscore')
133
-                )
134
-            ),
135
-            'deregisters' => array(
136
-                'event-editor-css'       => array('type' => 'css'),
137
-                'event-datetime-metabox' => array('type' => 'js')
138
-            ),
139
-            'enqueues'    => array(
140
-                'ee-tickets-datetimes-css' => array('edit', 'create_new'),
141
-                'ee-dtt-ticket-metabox'    => array('edit', 'create_new')
142
-            ),
143
-            'localize'    => array(
144
-                'ee-dtt-ticket-metabox' => array(
145
-                    'DTT_TRASH_BLOCK'       => array(
146
-                        'main_warning'            => __('The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
147
-                            'event_espresso'),
148
-                        'after_warning'           => __('In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
149
-                            'event_espresso'),
150
-                        'cancel_button'           => '<button class="button-secondary ee-modal-cancel">' . __('Cancel',
151
-                                'event_espresso') . '</button>',
152
-                        'close_button'            => '<button class="button-secondary ee-modal-cancel">' . __('Close',
153
-                                'event_espresso') . '</button>',
154
-                        'single_warning_from_tkt' => __('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.',
155
-                            'event_espresso'),
156
-                        'single_warning_from_dtt' => __('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.',
157
-                            'event_espresso'),
158
-                        'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">' . __('Dismiss',
159
-                                'event_espresso') . '</button>'
160
-                    ),
161
-                    'DTT_ERROR_MSG'         => array(
162
-                        'no_ticket_name' => __('General Admission', 'event_espresso'),
163
-                        'dismiss_button' => '<div class="save-cancel-button-container"><button class="button-secondary ee-modal-cancel">' . __('Dismiss',
164
-                                'event_espresso') . '</button></div>'
165
-                    ),
166
-                    'DTT_OVERSELL_WARNING'  => array(
167
-                        'datetime_ticket' => __('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.',
168
-                            'event_espresso'),
169
-                        'ticket_datetime' => __('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.',
170
-                            'event_espresso')
171
-                    ),
172
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats($this->_date_format_strings['date'],
173
-                        $this->_date_format_strings['time']),
174
-                    'DTT_START_OF_WEEK'     => array('dayValue' => (int)get_option('start_of_week'))
175
-                )
176
-            )
177
-        );
178
-
179
-
180
-        add_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
181
-            array($this, 'autosave_handling'), 10);
182
-        add_filter('FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
183
-            array($this, 'caf_updates'), 10);
184
-    }
185
-
186
-
187
-    public function caf_updates($update_callbacks)
188
-    {
189
-        foreach ($update_callbacks as $key => $callback) {
190
-            if ($callback[1] == '_default_tickets_update') {
191
-                unset($update_callbacks[$key]);
192
-            }
193
-        }
194
-
195
-        $update_callbacks[] = array($this, 'dtt_and_tickets_caf_update');
196
-
197
-        return $update_callbacks;
198
-    }
199
-
200
-
201
-    /**
202
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
203
-     *
204
-     * @param  EE_Event $evtobj The Event object we're attaching data to
205
-     * @param  array    $data   The request data from the form
206
-     *
207
-     * @return bool             success or fail
208
-     */
209
-    public function dtt_and_tickets_caf_update($evtobj, $data)
210
-    {
211
-        //first we need to start with datetimes cause they are the "root" items attached to events.
212
-        $saved_dtts = $this->_update_dtts($evtobj, $data);
213
-        //next tackle the tickets (and prices?)
214
-        $this->_update_tkts($evtobj, $saved_dtts, $data);
215
-    }
216
-
217
-
218
-    /**
219
-     * update event_datetimes
220
-     *
221
-     * @param  EE_Event $evt_obj Event being updated
222
-     * @param  array    $data    the request data from the form
223
-     *
224
-     * @return EE_Datetime[]
225
-     */
226
-    protected function _update_dtts($evt_obj, $data)
227
-    {
228
-        $timezone       = isset($data['timezone_string']) ? $data['timezone_string'] : null;
229
-        $saved_dtt_ids  = array();
230
-        $saved_dtt_objs = array();
231
-
232
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
233
-            //trim all values to ensure any excess whitespace is removed.
234
-            $dtt                = array_map(
235
-                function ($datetime_data) {
236
-                    return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
237
-                },
238
-                $dtt
239
-            );
240
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end'] : $dtt['DTT_EVT_start'];
241
-            $datetime_values    = array(
242
-                'DTT_ID'          => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
243
-                'DTT_name'        => ! empty($dtt['DTT_name']) ? $dtt['DTT_name'] : '',
244
-                'DTT_description' => ! empty($dtt['DTT_description']) ? $dtt['DTT_description'] : '',
245
-                'DTT_EVT_start'   => $dtt['DTT_EVT_start'],
246
-                'DTT_EVT_end'     => $dtt['DTT_EVT_end'],
247
-                'DTT_reg_limit'   => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
248
-                'DTT_order'       => ! isset($dtt['DTT_order']) ? $row : $dtt['DTT_order'],
249
-            );
250
-
251
-            //if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
252
-
253
-            if ( ! empty($dtt['DTT_ID'])) {
254
-                $DTM = EE_Registry::instance()->load_model('Datetime', array($timezone))->get_one_by_ID($dtt['DTT_ID']);
255
-
256
-                //set date and time format according to what is set in this class.
257
-                $DTM->set_date_format($this->_date_format_strings['date']);
258
-                $DTM->set_time_format($this->_date_format_strings['time']);
259
-
260
-                foreach ($datetime_values as $field => $value) {
261
-                    $DTM->set($field, $value);
262
-                }
263
-
264
-                // make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.
265
-                // We need to do this so we dont' TRASH the parent DTT.(save the ID for both key and value to avoid duplications)
266
-                $saved_dtt_ids[$DTM->ID()] = $DTM->ID();
267
-
268
-            } else {
269
-                $DTM = EE_Registry::instance()->load_class(
270
-                    'Datetime',
271
-                    array(
272
-                        $datetime_values,
273
-                        $timezone,
274
-                        array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
275
-                    ),
276
-                    false,
277
-                    false
278
-                );
279
-
280
-                foreach ($datetime_values as $field => $value) {
281
-                    $DTM->set($field, $value);
282
-                }
283
-            }
284
-
285
-
286
-            $DTM->save();
287
-            $DTM = $evt_obj->_add_relation_to($DTM, 'Datetime');
288
-            $evt_obj->save();
289
-
290
-            //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
291
-            if ($DTM->get_raw('DTT_EVT_start') > $DTM->get_raw('DTT_EVT_end')) {
292
-                $DTM->set('DTT_EVT_end', $DTM->get('DTT_EVT_start'));
293
-                $DTM = EEH_DTT_Helper::date_time_add($DTM, 'DTT_EVT_end', 'days');
294
-                $DTM->save();
295
-            }
296
-
297
-            //	now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
298
-            // because it is possible there was a new one created for the autosave.
299
-            // (save the ID for both key and value to avoid duplications)
300
-            $saved_dtt_ids[$DTM->ID()] = $DTM->ID();
301
-            $saved_dtt_objs[$row]      = $DTM;
302
-
303
-            //todo if ANY of these updates fail then we want the appropriate global error message.
304
-        }
305
-
306
-        //now we need to REMOVE any dtts that got deleted.  Keep in mind that this process will only kick in for DTT's that don't have any DTT_sold on them. So its safe to permanently delete at this point.
307
-        $old_datetimes = explode(',', $data['datetime_IDs']);
308
-        $old_datetimes = $old_datetimes[0] == '' ? array() : $old_datetimes;
309
-
310
-        if (is_array($old_datetimes)) {
311
-            $dtts_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
312
-            foreach ($dtts_to_delete as $id) {
313
-                $id = absint($id);
314
-                if (empty($id)) {
315
-                    continue;
316
-                }
317
-
318
-                $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
319
-
320
-                //remove tkt relationships.
321
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
322
-                foreach ($related_tickets as $tkt) {
323
-                    $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
324
-                }
325
-
326
-                $evt_obj->_remove_relation_to($id, 'Datetime');
327
-                $dtt_to_remove->refresh_cache_of_related_objects();
328
-
329
-            }
330
-        }
331
-
332
-        return $saved_dtt_objs;
333
-    }
334
-
335
-
336
-    /**
337
-     * update tickets
338
-     *
339
-     * @param  EE_Event      $evtobj     Event object being updated
340
-     * @param  EE_Datetime[] $saved_dtts an array of datetime ids being updated
341
-     * @param  array         $data       incoming request data
342
-     *
343
-     * @return EE_Ticket[]
344
-     */
345
-    protected function _update_tkts($evtobj, $saved_dtts, $data)
346
-    {
347
-
348
-        $new_tkt     = null;
349
-        $new_default = null;
350
-        //stripslashes because WP filtered the $_POST ($data) array to add slashes
351
-        $data          = stripslashes_deep($data);
352
-        $timezone      = isset($data['timezone_string']) ? $data['timezone_string'] : null;
353
-        $saved_tickets = $dtts_on_existing = array();
354
-        $old_tickets   = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
355
-
356
-        //load money helper
357
-
358
-        foreach ($data['edit_tickets'] as $row => $tkt) {
359
-
360
-            $update_prices = $create_new_TKT = false;
361
-
362
-            //figure out what dtts were added to the ticket and what dtts were removed from the ticket in the session.
363
-
364
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
365
-            $tkt_dtt_rows          = explode(',', $data['ticket_datetime_rows'][$row]);
366
-            $dtts_added            = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
367
-            $dtts_removed          = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
368
-
369
-            // trim inputs to ensure any excess whitespace is removed.
370
-            $tkt = array_map(
371
-                function ($ticket_data) {
372
-                    return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
373
-                },
374
-                $tkt
375
-            );
376
-
377
-            //note we are doing conversions to floats here instead of allowing EE_Money_Field to handle because we're doing calcs prior to using the models.
378
-            //note incoming ['TKT_price'] value is already in standard notation (via js).
379
-            $ticket_price = isset($tkt['TKT_price']) ? round((float)$tkt['TKT_price'], 3) : 0;
380
-
381
-            //note incoming base price needs converted from localized value.
382
-            $base_price = isset($tkt['TKT_base_price']) ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price']) : 0;
383
-            //if ticket price == 0 and $base_price != 0 then ticket price == base_price
384
-            $ticket_price  = $ticket_price === 0 && $base_price !== 0 ? $base_price : $ticket_price;
385
-            $base_price_id = isset($tkt['TKT_base_price_ID']) ? $tkt['TKT_base_price_ID'] : 0;
386
-
387
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row]) ? $data['edit_prices'][$row] : array();
388
-
389
-            $now = null;
390
-            if (empty($tkt['TKT_start_date'])) {
391
-                //lets' use now in the set timezone.
392
-                $now                   = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
393
-                $tkt['TKT_start_date'] = $now->format($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
394
-            }
395
-
396
-            if (empty($tkt['TKT_end_date'])) {
397
-                /**
398
-                 * set the TKT_end_date to the first datetime attached to the ticket.
399
-                 */
400
-                $first_dtt           = $saved_dtts[reset($tkt_dtt_rows)];
401
-                $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_format_strings['date'] . ' ' . $this->_date_format_string['time']);
402
-            }
403
-
404
-            $TKT_values = array(
405
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
406
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
407
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
408
-                'TKT_description' => ! empty($tkt['TKT_description']) && $tkt['TKT_description'] != __('You can modify this description',
409
-                    'event_espresso') ? $tkt['TKT_description'] : '',
410
-                'TKT_start_date'  => $tkt['TKT_start_date'],
411
-                'TKT_end_date'    => $tkt['TKT_end_date'],
412
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
413
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
414
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
415
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
416
-                'TKT_row'         => $row,
417
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
418
-                'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
419
-                'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
420
-                'TKT_price'       => $ticket_price
421
-            );
422
-
423
-
424
-            //if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
425
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
426
-                $TKT_values['TKT_ID']         = 0;
427
-                $TKT_values['TKT_is_default'] = 0;
428
-                $update_prices                = true;
429
-            }
430
-
431
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
432
-            // we actually do our saves ahead of doing any add_relations to
433
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
434
-            // but DID have it's items modified.
435
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
436
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
437
-            if (absint($TKT_values['TKT_ID'])) {
438
-                $TKT = EE_Registry::instance()->load_model('Ticket', array($timezone))->get_one_by_ID($tkt['TKT_ID']);
439
-                if ($TKT instanceof EE_Ticket) {
440
-
441
-                    $TKT = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
442
-                    // are there any registrations using this ticket ?
443
-                    $tickets_sold = $TKT->count_related(
444
-                        'Registration',
445
-                        array(
446
-                            array(
447
-                                'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete))
448
-                            )
449
-                        )
450
-                    );
451
-                    //set ticket formats
452
-                    $TKT->set_date_format($this->_date_format_strings['date']);
453
-                    $TKT->set_time_format($this->_date_format_strings['time']);
454
-
455
-                    // let's just check the total price for the existing ticket
456
-                    // and determine if it matches the new total price.
457
-                    // if they are different then we create a new ticket (if tkts sold)
458
-                    // if they aren't different then we go ahead and modify existing ticket.
459
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price != $TKT->price() && ! $TKT->deleted()
460
-                        ? true : false;
461
-
462
-                    //set new values
463
-                    foreach ($TKT_values as $field => $value) {
464
-                        if ($field === 'TKT_qty') {
465
-                            $TKT->set_qty($value);
466
-                        } else {
467
-                            $TKT->set($field, $value);
468
-                        }
469
-                    }
470
-
471
-                    //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
472
-                    if ($create_new_TKT) {
473
-                        $new_tkt = $this->_duplicate_ticket($TKT, $price_rows, $ticket_price, $base_price,
474
-                            $base_price_id);
475
-                    }
476
-                }
477
-
478
-            } else {
479
-                // no TKT_id so a new TKT
480
-                $TKT = EE_Ticket::new_instance(
481
-                    $TKT_values,
482
-                    $timezone,
483
-                    array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
484
-                );
485
-                if ($TKT instanceof EE_Ticket) {
486
-                    // make sure ticket has an ID of setting relations won't work
487
-                    $TKT->save();
488
-                    $TKT           = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
489
-                    $update_prices = true;
490
-                }
491
-            }
492
-            //make sure any current values have been saved.
493
-            //$TKT->save();
494
-
495
-            //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
496
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
497
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
498
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
499
-            }
500
-
501
-            //let's make sure the base price is handled
502
-            $TKT = ! $create_new_TKT ? $this->_add_prices_to_ticket(array(), $TKT, $update_prices, $base_price,
503
-                $base_price_id) : $TKT;
504
-
505
-            //add/update price_modifiers
506
-            $TKT = ! $create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $TKT, $update_prices) : $TKT;
507
-
508
-            //need to make sue that the TKT_price is accurate after saving the prices.
509
-            $TKT->ensure_TKT_Price_correct();
510
-
511
-            //handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
512
-            if ( ! defined('DOING_AUTOSAVE')) {
513
-                if ( ! empty($tkt['TKT_is_default_selector'])) {
514
-                    $update_prices = true;
515
-                    $new_default   = clone $TKT;
516
-                    $new_default->set('TKT_ID', 0);
517
-                    $new_default->set('TKT_is_default', 1);
518
-                    $new_default->set('TKT_row', 1);
519
-                    $new_default->set('TKT_price', $ticket_price);
520
-                    //remove any dtt relations cause we DON'T want dtt relations attached (note this is just removing the cached relations in the object)
521
-                    $new_default->_remove_relations('Datetime');
522
-                    //todo we need to add the current attached prices as new prices to the new default ticket.
523
-                    $new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
524
-                    //don't forget the base price!
525
-                    $new_default = $this->_add_prices_to_ticket(array(), $new_default, $update_prices, $base_price,
526
-                        $base_price_id);
527
-                    $new_default->save();
528
-                    do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket', $new_default,
529
-                        $row, $TKT, $data);
530
-                }
531
-            }
532
-
533
-
534
-            //DO ALL dtt relationships for both current tickets and any archived tickets for the given dtt that are related to the current ticket. TODO... not sure exactly how we're going to do this considering we don't know what current ticket the archived tickets are related to (and TKT_parent is used for autosaves so that's not a field we can reliably use).
535
-
536
-
537
-            //let's assign any tickets that have been setup to the saved_tickets tracker
538
-            //save existing TKT
539
-            $TKT->save();
540
-            if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
541
-                //save new TKT
542
-                $new_tkt->save();
543
-                //add new ticket to array
544
-                $saved_tickets[$new_tkt->ID()] = $new_tkt;
545
-
546
-                do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket', $new_tkt, $row, $tkt, $data);
547
-
548
-            } else {
549
-                //add tkt to saved tkts
550
-                $saved_tickets[$TKT->ID()] = $TKT;
551
-
552
-                do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket', $TKT, $row, $tkt, $data);
553
-            }
554
-
555
-        }
556
-
557
-        // now we need to handle tickets actually "deleted permanently".
558
-        // There are cases where we'd want this to happen
559
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
560
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
561
-        // No sense in keeping all the related data in the db!
562
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
563
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
564
-
565
-        foreach ($tickets_removed as $id) {
566
-            $id = absint($id);
567
-
568
-            //get the ticket for this id
569
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
570
-
571
-            //if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
572
-            if ($tkt_to_remove->get('TKT_is_default')) {
573
-                continue;
574
-            }
575
-
576
-            // if this tkt has any registrations attached so then we just ARCHIVE
577
-            // because we don't actually permanently delete these tickets.
578
-            if ($tkt_to_remove->count_related('Registration') > 0) {
579
-                $tkt_to_remove->delete();
580
-                continue;
581
-            }
582
-
583
-            // need to get all the related datetimes on this ticket and remove from every single one of them
584
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
585
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
586
-
587
-            foreach ($dtts as $dtt) {
588
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
589
-            }
590
-
591
-            // need to do the same for prices (except these prices can also be deleted because again,
592
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
593
-            $tkt_to_remove->delete_related_permanently('Price');
594
-
595
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
596
-
597
-            // finally let's delete this ticket
598
-            // (which should not be blocked at this point b/c we've removed all our relationships)
599
-            $tkt_to_remove->delete_permanently();
600
-        }
601
-
602
-        return $saved_tickets;
603
-    }
604
-
605
-
606
-    /**
607
-     *
608
-     * @access  protected
609
-     *
610
-     * @param \EE_Ticket     $ticket
611
-     * @param \EE_Datetime[] $saved_datetimes
612
-     * @param \EE_Datetime[] $added_datetimes
613
-     * @param \EE_Datetime[] $removed_datetimes
614
-     *
615
-     * @return \EE_Ticket
616
-     * @throws \EE_Error
617
-     */
618
-    protected function _update_ticket_datetimes(
619
-        EE_Ticket $ticket,
620
-        $saved_datetimes = array(),
621
-        $added_datetimes = array(),
622
-        $removed_datetimes = array()
623
-    ) {
624
-
625
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
626
-        // and removing the ticket from datetimes it got removed from.
627
-
628
-        // first let's add datetimes
629
-        if ( ! empty($added_datetimes) && is_array($added_datetimes)) {
630
-            foreach ($added_datetimes as $row_id) {
631
-                $row_id = (int)$row_id;
632
-                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
633
-                    $ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
634
-                    // Is this an existing ticket (has an ID) and does it have any sold?
635
-                    // If so, then we need to add that to the DTT sold because this DTT is getting added.
636
-                    if ($ticket->ID() && $ticket->sold() > 0) {
637
-                        $saved_datetimes[$row_id]->increase_sold($ticket->sold());
638
-                        $saved_datetimes[$row_id]->save();
639
-                    }
640
-                }
641
-            }
642
-        }
643
-        // then remove datetimes
644
-        if ( ! empty($removed_datetimes) && is_array($removed_datetimes)) {
645
-            foreach ($removed_datetimes as $row_id) {
646
-                $row_id = (int)$row_id;
647
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
648
-                // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
649
-                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
650
-                    $ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
651
-                    // Is this an existing ticket (has an ID) and does it have any sold?
652
-                    // If so, then we need to remove it's sold from the DTT_sold.
653
-                    // but NOT if the ticket is being removed because it is getting archived !!!
654
-                    // Because in that scenario, the archived ticket is likely still a valid ticket
655
-                    // and needs to still have it's quantity sold to count in calculations
656
-                    if ($ticket->ID() && $ticket->sold() > 0 && ! $ticket->deleted()) {
657
-                        $saved_datetimes[$row_id]->decrease_sold($ticket->sold());
658
-                        $saved_datetimes[$row_id]->save();
659
-                    }
660
-                }
661
-            }
662
-        }
663
-        // cap ticket qty by datetime reg limits
664
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
665
-
666
-        return $ticket;
667
-    }
668
-
669
-
670
-    /**
671
-     *
672
-     * @access  protected
673
-     *
674
-     * @param \EE_Ticket $ticket
675
-     * @param array      $price_rows
676
-     * @param int        $ticket_price
677
-     * @param int        $base_price
678
-     * @param int        $base_price_id
679
-     *
680
-     * @return \EE_Ticket
681
-     * @throws \EE_Error
682
-     */
683
-    protected function _duplicate_ticket(
684
-        EE_Ticket $ticket,
685
-        $price_rows = array(),
686
-        $ticket_price = 0,
687
-        $base_price = 0,
688
-        $base_price_id = 0
689
-    ) {
690
-
691
-        // create new ticket that's a copy of the existing
692
-        // except a new id of course (and not archived)
693
-        // AND has the new TKT_price associated with it.
694
-        $new_ticket = clone $ticket;
695
-        $new_ticket->set('TKT_ID', 0);
696
-        $new_ticket->set_deleted(0);
697
-        $new_ticket->set_price($ticket_price);
698
-        $new_ticket->set_sold(0);
699
-        // let's get a new ID for this ticket
700
-        $new_ticket->save();
701
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
702
-        $datetimes_on_existing = $ticket->get_many_related('Datetime');
703
-        $new_ticket            = $this->_update_ticket_datetimes(
704
-            $new_ticket,
705
-            $datetimes_on_existing,
706
-            array_keys($datetimes_on_existing)
707
-        );
708
-
709
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
710
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
711
-        // available.
712
-        if ($ticket->sold() > 0) {
713
-            $new_qty = $ticket->qty() - $ticket->sold();
714
-            $new_ticket->set_qty($new_qty);
715
-        }
716
-        //now we update the prices just for this ticket
717
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
718
-        //and we update the base price
719
-        $new_ticket = $this->_add_prices_to_ticket(array(), $new_ticket, true, $base_price, $base_price_id);
720
-
721
-        return $new_ticket;
722
-    }
723
-
724
-
725
-    /**
726
-     * This attaches a list of given prices to a ticket.
727
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
728
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
729
-     * price info and prices are automatically "archived" via the ticket.
730
-     *
731
-     * @access  private
732
-     *
733
-     * @param array     $prices        Array of prices from the form.
734
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
735
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
736
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
737
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
738
-     *
739
-     * @return EE_Ticket
740
-     */
741
-    protected function _add_prices_to_ticket(
742
-        $prices = array(),
743
-        EE_Ticket $ticket,
744
-        $new_prices = false,
745
-        $base_price = false,
746
-        $base_price_id = false
747
-    ) {
748
-
749
-        //let's just get any current prices that may exist on the given ticket so we can remove any prices that got trashed in this session.
750
-        $current_prices_on_ticket = $base_price !== false ? $ticket->base_price(true) : $ticket->price_modifiers();
751
-
752
-        $updated_prices = array();
753
-
754
-        // if $base_price ! FALSE then updating a base price.
755
-        if ($base_price !== false) {
756
-            $prices[1] = array(
757
-                'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
758
-                'PRT_ID'     => 1,
759
-                'PRC_amount' => $base_price,
760
-                'PRC_name'   => $ticket->get('TKT_name'),
761
-                'PRC_desc'   => $ticket->get('TKT_description')
762
-            );
763
-        }
764
-
765
-        //possibly need to save tkt
766
-        if ( ! $ticket->ID()) {
767
-            $ticket->save();
768
-        }
769
-
770
-        foreach ($prices as $row => $prc) {
771
-            $prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
772
-            if (empty($prt_id)) {
773
-                continue;
774
-            } //prices MUST have a price type id.
775
-            $PRC_values = array(
776
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
777
-                'PRT_ID'         => $prt_id,
778
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
779
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
780
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
781
-                'PRC_is_default' => false,
782
-                //make sure we set PRC_is_default to false for all ticket saves from event_editor
783
-                'PRC_order'      => $row
784
-            );
785
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
786
-                $PRC_values['PRC_ID'] = 0;
787
-                $PRC                  = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
788
-            } else {
789
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
790
-                //update this price with new values
791
-                foreach ($PRC_values as $field => $newprc) {
792
-                    $PRC->set($field, $newprc);
793
-                }
794
-            }
795
-            $PRC->save();
796
-            $prcid                  = $PRC->ID();
797
-            $updated_prices[$prcid] = $PRC;
798
-            $ticket->_add_relation_to($PRC, 'Price');
799
-        }
800
-
801
-        //now let's remove any prices that got removed from the ticket
802
-        if ( ! empty ($current_prices_on_ticket)) {
803
-            $current          = array_keys($current_prices_on_ticket);
804
-            $updated          = array_keys($updated_prices);
805
-            $prices_to_remove = array_diff($current, $updated);
806
-            if ( ! empty($prices_to_remove)) {
807
-                foreach ($prices_to_remove as $prc_id) {
808
-                    $p = $current_prices_on_ticket[$prc_id];
809
-                    $ticket->_remove_relation_to($p, 'Price');
810
-
811
-                    //delete permanently the price
812
-                    $p->delete_permanently();
813
-                }
814
-            }
815
-        }
816
-
817
-        return $ticket;
818
-    }
819
-
820
-
821
-    public function autosave_handling($event_admin_obj)
822
-    {
823
-        return $event_admin_obj; //doing nothing for the moment.
824
-        //todo when I get to this remember that I need to set the template args on the $event_admin_obj (use the set_template_args() method)
825
-
826
-        /**
827
-         * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
828
-         *
829
-         * 1. TKT_is_default_selector (visible)
830
-         * 2. TKT_is_default (hidden)
831
-         *
832
-         * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want this ticket to be saved as a default.
833
-         *
834
-         * The tricky part is, on an initial display on create or edit (or after manually updating), the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true if this is a create.  However, after an autosave, users will want some sort of indicator that the TKT HAS been saved as a default.. in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
835
-         * On Autosave:
836
-         * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements, then set the TKT_is_default to false.
837
-         * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
838
-         * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
839
-         */
840
-    }
841
-
842
-
843
-    public function pricing_metabox()
844
-    {
845
-        $existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
846
-
847
-        $evtobj = $this->_adminpage_obj->get_cpt_model_obj();
848
-
849
-        //set is_creating_event property.
850
-        $evtID                    = $evtobj->ID();
851
-        $this->_is_creating_event = absint($evtID) != 0 ? false : true;
852
-
853
-        //default main template args
854
-        $main_template_args = array(
855
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link('event_editor_event_datetimes_help_tab',
856
-                $this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
857
-            //todo need to add a filter to the template for the help text in the Events_Admin_Page core file so we can add further help
858
-            'existing_datetime_ids'    => '',
859
-            'total_dtt_rows'           => 1,
860
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link('add_new_dtt_info',
861
-                $this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
862
-            //todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
863
-            'datetime_rows'            => '',
864
-            'show_tickets_container'   => '',
865
-            //$this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
866
-            'ticket_rows'              => '',
867
-            'existing_ticket_ids'      => '',
868
-            'total_ticket_rows'        => 1,
869
-            'ticket_js_structure'      => '',
870
-            'ee_collapsible_status'    => ' ee-collapsible-open'
871
-            //$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
872
-        );
873
-
874
-        $timezone = $evtobj instanceof EE_Event ? $evtobj->timezone_string() : null;
875
-
876
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
877
-
878
-        /**
879
-         * 1. Start with retrieving Datetimes
880
-         * 2. For each datetime get related tickets
881
-         * 3. For each ticket get related prices
882
-         */
883
-
884
-        $DTM   = EE_Registry::instance()->load_model('Datetime', array($timezone));
885
-        $times = $DTM->get_all_event_dates($evtID);
886
-
887
-
888
-        $main_template_args['total_dtt_rows'] = count($times);
889
-
890
-        /** @see https://events.codebasehq.com/projects/event-espresso/tickets/9486 for why we are counting $dttrow and then setting that on the Datetime object */
891
-        $dttrow = 1;
892
-        foreach ($times as $time) {
893
-            $dttid = $time->get('DTT_ID');
894
-            $time->set('DTT_order', $dttrow);
895
-            $existing_datetime_ids[] = $dttid;
896
-
897
-            //tickets attached
898
-            $related_tickets = $time->ID() > 0 ? $time->get_many_related('Ticket', array(
899
-                array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
900
-                'default_where_conditions' => 'none',
901
-                'order_by'                 => array('TKT_order' => 'ASC')
902
-            )) : array();
903
-
904
-            //if there are no related tickets this is likely a new event OR autodraft
905
-            // event so we need to generate the default tickets because dtts
906
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
907
-            // datetime on the event.
908
-            if (empty ($related_tickets) && count($times) < 2) {
909
-                $related_tickets = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
910
-
911
-                //this should be ordered by TKT_ID, so let's grab the first default ticket (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
912
-                $default_prices = EEM_Price::instance()->get_all_default_prices();
913
-
914
-                $main_default_ticket = reset($related_tickets);
915
-                if ($main_default_ticket instanceof EE_Ticket) {
916
-                    foreach ($default_prices as $default_price) {
917
-                        if ($default_price->is_base_price()) {
918
-                            continue;
919
-                        }
920
-                        $main_default_ticket->cache('Price', $default_price);
921
-                    }
922
-                }
923
-            }
924
-
925
-
926
-            //we can't actually setup rows in this loop yet cause we don't know all the unique tickets for this event yet (tickets are linked through all datetimes). So we're going to temporarily cache some of that information.
927
-
928
-            //loop through and setup the ticket rows and make sure the order is set.
929
-            foreach ($related_tickets as $ticket) {
930
-                $tktid  = $ticket->get('TKT_ID');
931
-                $tktrow = $ticket->get('TKT_row');
932
-                //we only want unique tickets in our final display!!
933
-                if ( ! in_array($tktid, $existing_ticket_ids)) {
934
-                    $existing_ticket_ids[] = $tktid;
935
-                    $all_tickets[]         = $ticket;
936
-                }
937
-
938
-                //temporary cache of this ticket info for this datetime for later processing of datetime rows.
939
-                $datetime_tickets[$dttid][] = $tktrow;
940
-
941
-                //temporary cache of this datetime info for this ticket for later processing of ticket rows.
942
-                if ( ! isset($ticket_datetimes[$tktid]) || ! in_array($dttrow, $ticket_datetimes[$tktid])) {
943
-                    $ticket_datetimes[$tktid][] = $dttrow;
944
-                }
945
-            }
946
-            $dttrow++;
947
-        }
948
-
949
-        $main_template_args['total_ticket_rows']     = count($existing_ticket_ids);
950
-        $main_template_args['existing_ticket_ids']   = implode(',', $existing_ticket_ids);
951
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
952
-
953
-        //sort $all_tickets by order
954
-        usort($all_tickets, function ($a, $b) {
955
-            $a_order = (int)$a->get('TKT_order');
956
-            $b_order = (int)$b->get('TKT_order');
957
-            if ($a_order == $b_order) {
958
-                return 0;
959
-            }
960
-
961
-            return ($a_order < $b_order) ? -1 : 1;
962
-        });
963
-
964
-        //k NOW we have all the data we need for setting up the dtt rows and ticket rows so we start our dtt loop again.
965
-        $dttrow = 1;
966
-        foreach ($times as $time) {
967
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row($dttrow, $time, $datetime_tickets,
968
-                $all_tickets, false, $times);
969
-            $dttrow++;
970
-        }
971
-
972
-        //then loop through all tickets for the ticket rows.
973
-        $tktrow = 1;
974
-        foreach ($all_tickets as $ticket) {
975
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row($tktrow, $ticket, $ticket_datetimes, $times,
976
-                false, $all_tickets);
977
-            $tktrow++;
978
-        }
979
-
980
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($times, $all_tickets);
981
-        $template                                  = PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php';
982
-        EEH_Template::display_template($template, $main_template_args);
983
-
984
-        return;
985
-    }
986
-
987
-
988
-    protected function _get_datetime_row(
989
-        $dttrow,
990
-        EE_Datetime $dtt,
991
-        $datetime_tickets,
992
-        $all_tickets,
993
-        $default = false,
994
-        $all_dtts = array()
995
-    ) {
996
-
997
-        $dtt_display_template_args = array(
998
-            'dtt_edit_row'             => $this->_get_dtt_edit_row($dttrow, $dtt, $default, $all_dtts),
999
-            'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row($dttrow, $dtt, $datetime_tickets,
1000
-                $all_tickets, $default),
1001
-            'dtt_row'                  => $default ? 'DTTNUM' : $dttrow
1002
-        );
1003
-        $template                  = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php';
1004
-
1005
-        return EEH_Template::display_template($template, $dtt_display_template_args, true);
1006
-    }
1007
-
1008
-
1009
-    /**
1010
-     * This method is used to generate a dtt fields  edit row.
1011
-     * The same row is used to generate a row with valid DTT objects and the default row that is used as the
1012
-     * skeleton by the js.
1013
-     *
1014
-     * @param int           $dttrow                         The row number for the row being generated.
1015
-     * @param               mixed                           EE_Datetime|null $dtt      If not default row being
1016
-     *                                                                       generated, this must be a EE_Datetime
1017
-     *                                                                       object.
1018
-     * @param bool          $default                        Whether a default row is being generated or not.
1019
-     * @param EE_Datetime[] $all_dtts                       This is the array of all datetimes used in the editor.
1020
-     *
1021
-     * @return string Generated edit row.
1022
-     */
1023
-    protected function _get_dtt_edit_row($dttrow, $dtt, $default, $all_dtts)
1024
-    {
1025
-
1026
-        // if the incoming $dtt object is NOT an instance of EE_Datetime then force default to true.
1027
-        $default = ! $dtt instanceof EE_Datetime ? true : false;
1028
-
1029
-        $template_args = array(
1030
-            'dtt_row'              => $default ? 'DTTNUM' : $dttrow,
1031
-            'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1032
-            'edit_dtt_expanded'    => '',
1033
-            //$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? '' : ' ee-edit-editing',
1034
-            'DTT_ID'               => $default ? '' : $dtt->ID(),
1035
-            'DTT_name'             => $default ? '' : $dtt->name(),
1036
-            'DTT_description'      => $default ? '' : $dtt->description(),
1037
-            'DTT_EVT_start'        => $default ? '' : $dtt->start_date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1038
-            'DTT_EVT_end'          => $default ? '' : $dtt->end_date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1039
-            'DTT_reg_limit'        => $default ? '' : $dtt->get_pretty('DTT_reg_limit', 'input'),
1040
-            'DTT_order'            => $default ? 'DTTNUM' : $dttrow,
1041
-            'dtt_sold'             => $default ? '0' : $dtt->get('DTT_sold'),
1042
-            'dtt_reserved'         => $default ? '0' : $dtt->reserved(),
1043
-            'clone_icon'           => ! empty($dtt) && $dtt->get('DTT_sold') > 0 ? '' : 'clone-icon ee-icon ee-icon-clone clickable',
1044
-            'trash_icon'           => ! empty($dtt) && $dtt->get('DTT_sold') > 0 ? 'ee-lock-icon' : 'trash-icon dashicons dashicons-post-trash clickable',
1045
-            'reg_list_url'         => $default || ! $dtt->event() instanceof \EE_Event
1046
-                ? ''
1047
-                : EE_Admin_Page::add_query_args_and_nonce(
1048
-                    array('event_id' => $dtt->event()->ID(), 'datetime_id' => $dtt->ID()),
1049
-                    REG_ADMIN_URL
1050
-                )
1051
-        );
1052
-
1053
-        $template_args['show_trash'] = count($all_dtts) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon' ? ' style="display:none"' : '';
1054
-
1055
-        //allow filtering of template args at this point.
1056
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1057
-            $template_args, $dttrow, $dtt, $default, $all_dtts, $this->_is_creating_event);
1058
-
1059
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php';
1060
-
1061
-        return EEH_Template::display_template($template, $template_args, true);
1062
-    }
1063
-
1064
-
1065
-    protected function _get_dtt_attached_tickets_row($dttrow, $dtt, $datetime_tickets, $all_tickets, $default)
1066
-    {
1067
-
1068
-        $template_args = array(
1069
-            'dtt_row'                           => $default ? 'DTTNUM' : $dttrow,
1070
-            'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1071
-            'DTT_description'                   => $default ? '' : $dtt->description(),
1072
-            'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1073
-            'show_tickets_row'                  => ' style="display:none;"',
1074
-            //$default || $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' style="display:none;"' : '',
1075
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link('add_new_ticket_via_datetime',
1076
-                $this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
1077
-            //todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1078
-            'DTT_ID'                            => $default ? '' : $dtt->ID()
1079
-        );
1080
-
1081
-        //need to setup the list items (but only if this isnt' a default skeleton setup)
1082
-        if ( ! $default) {
1083
-            $tktrow = 1;
1084
-            foreach ($all_tickets as $ticket) {
1085
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item($dttrow, $tktrow,
1086
-                    $dtt, $ticket, $datetime_tickets, $default);
1087
-                $tktrow++;
1088
-            }
1089
-        }
1090
-
1091
-        //filter template args at this point
1092
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1093
-            $template_args, $dttrow, $dtt, $datetime_tickets, $all_tickets, $default, $this->_is_creating_event);
1094
-
1095
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php';
1096
-
1097
-        return EEH_Template::display_template($template, $template_args, true);
1098
-    }
1099
-
1100
-
1101
-    protected function _get_datetime_tickets_list_item($dttrow, $tktrow, $dtt, $ticket, $datetime_tickets, $default)
1102
-    {
1103
-        $tktid    = ! empty($ticket) ? $ticket->ID() : 0;
1104
-        $dtt_tkts = $dtt instanceof EE_Datetime && isset($datetime_tickets[$dtt->ID()]) ? $datetime_tickets[$dtt->ID()] : array();
1105
-
1106
-        $displayrow    = ! empty($ticket) ? $ticket->get('TKT_row') : 0;
1107
-        $template_args = array(
1108
-            'dtt_row'                 => $default ? 'DTTNUM' : $dttrow,
1109
-            'tkt_row'                 => $default && empty($ticket) ? 'TICKETNUM' : $tktrow,
1110
-            'datetime_ticket_checked' => in_array($displayrow, $dtt_tkts) ? ' checked="checked"' : '',
1111
-            'ticket_selected'         => in_array($displayrow, $dtt_tkts) ? ' ticket-selected' : '',
1112
-            'TKT_name'                => $default && empty($ticket) ? 'TKTNAME' : $ticket->get('TKT_name'),
1113
-            'tkt_status_class'        => ($default && empty($ticket)) || $this->_is_creating_event ? ' tkt-status-' . EE_Ticket::onsale : ' tkt-status-' . $ticket->ticket_status(),
1114
-        );
1115
-
1116
-        //filter template args
1117
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1118
-            $template_args, $dttrow, $tktrow, $dtt, $ticket, $datetime_tickets, $default, $this->_is_creating_event);
1119
-
1120
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php';
1121
-
1122
-        return EEH_Template::display_template($template, $template_args, true);
1123
-    }
1124
-
1125
-
1126
-    /**
1127
-     * This generates the ticket row for tickets.
1128
-     * This same method is used to generate both the actual rows and the js skeleton row (when default ==
1129
-     * true)
1130
-     *
1131
-     * @param int           $tktrow                          Represents the row number being generated.
1132
-     * @param               mixed                            null|EE_Ticket $ticket           If default then this will
1133
-     *                                                                      be null.
1134
-     * @param EE_Datetime[] $ticket_datetimes                Either an array of all datetimes on all tickets indexed by
1135
-     *                                                       each ticket or empty for  default
1136
-     * @param EE_Datetime[] $all_dtts                        All Datetimes on the event or empty for default.
1137
-     * @param bool          $default                         Whether default row being generated or not.
1138
-     * @param EE_Ticket[]   $all_tickets                     This is an array of all tickets attached to the event (or
1139
-     *                                                       empty in the case of defaults)
1140
-     *
1141
-     * @return [type] [description]
1142
-     */
1143
-    protected function _get_ticket_row(
1144
-        $tktrow,
1145
-        $ticket,
1146
-        $ticket_datetimes,
1147
-        $all_dtts,
1148
-        $default = false,
1149
-        $all_tickets = array()
1150
-    ) {
1151
-
1152
-        //if $ticket is not an instance of EE_Ticket then force default to true.
1153
-        $default = ! $ticket instanceof EE_Ticket ? true : false;
1154
-
1155
-        $prices = ! empty($ticket) && ! $default ? $ticket->get_many_related('Price',
1156
-            array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))) : array();
1157
-
1158
-        //if there is only one price (which would be the base price) or NO prices and this ticket is a default ticket, let's just make sure there are no cached default prices on
1159
-        //the object.  This is done by not including any query_params.
1160
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1161
-            $prices = $ticket->get_many_related('Price');
1162
-        }
1163
-
1164
-        // check if we're dealing with a default ticket in which case we don't want any starting_ticket_datetime_row values set (otherwise there won't be any new relationships created for tickets based off of the default ticket).  This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1165
-        $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->get('TKT_is_default')) ? true : false;
1166
-
1167
-        $tkt_dtts = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()]) ? $ticket_datetimes[$ticket->ID()] : array();
1168
-
1169
-        $ticket_subtotal  = $default ? 0 : $ticket->get_ticket_subtotal();
1170
-        $base_price       = $default ? null : $ticket->base_price();
1171
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1172
-
1173
-        //breaking out complicated condition for ticket_status
1174
-        if ($default) {
1175
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1176
-        } else {
1177
-            $ticket_status_class = $ticket->is_default() ? ' tkt-status-' . EE_Ticket::onsale : ' tkt-status-' . $ticket->ticket_status();
1178
-        }
1179
-
1180
-        //breaking out complicated condition for TKT_taxable
1181
-        if ($default) {
1182
-            $TKT_taxable = '';
1183
-        } else {
1184
-            $TKT_taxable = $ticket->get('TKT_taxable') ? ' checked="checked"' : '';
1185
-        }
1186
-
1187
-
1188
-        $template_args = array(
1189
-            'tkt_row'                       => $default ? 'TICKETNUM' : $tktrow,
1190
-            'TKT_order'                     => $default ? 'TICKETNUM' : $tktrow,
1191
-            //on initial page load this will always be the correct order.
1192
-            'tkt_status_class'              => $ticket_status_class,
1193
-            'display_edit_tkt_row'          => ' style="display:none;"',
1194
-            'edit_tkt_expanded'             => '',
1195
-            'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1196
-            'TKT_name'                      => $default ? '' : $ticket->get('TKT_name'),
1197
-            'TKT_start_date'                => $default ? '' : $ticket->get_date('TKT_start_date',
1198
-                $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1199
-            'TKT_end_date'                  => $default ? '' : $ticket->get_date('TKT_end_date',
1200
-                $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1201
-            'TKT_status'                    => $default ? EEH_Template::pretty_status(EE_Ticket::onsale, false,
1202
-                'sentence') : $ticket->is_default() ? EEH_Template::pretty_status(EE_Ticket::onsale, false,
1203
-                'sentence') : $ticket->ticket_status(true),
1204
-            'TKT_price'                     => $default ? '' : EEH_Template::format_currency($ticket->get_ticket_total_with_taxes(),
1205
-                false, false),
1206
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1207
-            'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1208
-            'TKT_qty'                       => $default ? '' : $ticket->get_pretty('TKT_qty', 'symbol'),
1209
-            'TKT_qty_for_input'             => $default ? '' : $ticket->get_pretty('TKT_qty', 'input'),
1210
-            'TKT_uses'                      => $default ? '' : $ticket->get_pretty('TKT_uses', 'input'),
1211
-            'TKT_min'                       => $default ? '' : ($ticket->get('TKT_min') === -1 || $ticket->get('TKT_min') === 0 ? '' : $ticket->get('TKT_min')),
1212
-            'TKT_max'                       => $default ? '' : $ticket->get_pretty('TKT_max', 'input'),
1213
-            'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1214
-            'TKT_reserved'                      => $default ? 0 : $ticket->reserved(),
1215
-            'TKT_registrations'             => $default ? 0 : $ticket->count_registrations(array(
1216
-                array(
1217
-                    'STS_ID' => array(
1218
-                        '!=',
1219
-                        EEM_Registration::status_id_incomplete
1220
-                    )
1221
-                )
1222
-            )),
1223
-            'TKT_ID'                        => $default ? 0 : $ticket->get('TKT_ID'),
1224
-            'TKT_description'               => $default ? '' : $ticket->get('TKT_description'),
1225
-            'TKT_is_default'                => $default ? 0 : $ticket->get('TKT_is_default'),
1226
-            'TKT_required'                  => $default ? 0 : $ticket->required(),
1227
-            'TKT_is_default_selector'       => '',
1228
-            'ticket_price_rows'             => '',
1229
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price ? '' : $base_price->get_pretty('PRC_amount',
1230
-                'localized_float'),
1231
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1232
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0) ? '' : ' style="display:none;"',
1233
-            'show_price_mod_button'         => count($prices) > 1 || ($default && $count_price_mods > 0) || ( ! $default && $ticket->get('TKT_deleted')) ? ' style="display:none;"' : '',
1234
-            'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1235
-            'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1236
-            'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_dtts),
1237
-            'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_dtts),
1238
-            'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1239
-            'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1240
-            'TKT_taxable'                   => $TKT_taxable,
1241
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->get('TKT_taxable') ? '' : ' style="display:none"',
1242
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1243
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency($ticket_subtotal, false, false),
1244
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1245
-            'tax_rows'                      => $this->_get_tax_rows($tktrow, $ticket),
1246
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? true : false,
1247
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? ' ticket-archived' : '',
1248
-            'trash_icon'                    => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? 'ee-lock-icon ' : 'trash-icon dashicons dashicons-post-trash clickable',
1249
-            'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? '' : 'clone-icon ee-icon ee-icon-clone clickable'
1250
-        );
1251
-
1252
-        $template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] != 'ee-lock-icon' ? ' style="display:none"' : '';
1253
-
1254
-        //handle rows that should NOT be empty
1255
-        if (empty($template_args['TKT_start_date'])) {
1256
-            //if empty then the start date will be now.
1257
-            $template_args['TKT_start_date']   = date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'],
1258
-                current_time('timestamp'));
1259
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1260
-        }
1261
-
1262
-        if (empty($template_args['TKT_end_date'])) {
1263
-
1264
-            //get the earliest datetime (if present);
1265
-            $earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related('Datetime',
1266
-                array('order_by' => array('DTT_EVT_start' => 'ASC'))) : null;
1267
-
1268
-            if ( ! empty($earliest_dtt)) {
1269
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start',
1270
-                    $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
1271
-            } else {
1272
-                //default so let's just use what's been set for the default date-time which is 30 days from now.
1273
-                $template_args['TKT_end_date'] = date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'],
1274
-                    mktime(24, 0, 0, date("m"), date("d") + 29, date("Y")));
1275
-            }
1276
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1277
-        }
1278
-
1279
-        //generate ticket_datetime items
1280
-        if ( ! $default) {
1281
-            $dttrow = 1;
1282
-            foreach ($all_dtts as $dtt) {
1283
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item($dttrow, $tktrow, $dtt,
1284
-                    $ticket, $ticket_datetimes, $default);
1285
-                $dttrow++;
1286
-            }
1287
-        }
1288
-
1289
-        $prcrow = 1;
1290
-        foreach ($prices as $price) {
1291
-            if ($price->is_base_price()) {
1292
-                $prcrow++;
1293
-                continue;
1294
-            }
1295
-            $show_trash  = (count($prices) > 1 && $prcrow === 1) || count($prices) === 1 ? false : true;
1296
-            $show_create = count($prices) > 1 && count($prices) !== $prcrow ? false : true;
1297
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row($tktrow, $prcrow, $price, $default,
1298
-                $ticket, $show_trash, $show_create);
1299
-            $prcrow++;
1300
-        }
1301
-
1302
-        //filter $template_args
1303
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1304
-            $template_args, $tktrow, $ticket, $ticket_datetimes, $all_dtts, $default, $all_tickets,
1305
-            $this->_is_creating_event);
1306
-
1307
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php';
1308
-
1309
-        return EEH_Template::display_template($template, $template_args, true);
1310
-    }
1311
-
1312
-
1313
-    protected function _get_tax_rows($tktrow, $ticket)
1314
-    {
1315
-        $tax_rows      = '';
1316
-        $template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php';
1317
-        $template_args = array();
1318
-        $taxes         = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1319
-        foreach ($taxes as $tax) {
1320
-            $tax_added     = $this->_get_tax_added($tax, $ticket);
1321
-            $template_args = array(
1322
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable') ? '' : ' style="display:none;"',
1323
-                'tax_id'            => $tax->ID(),
1324
-                'tkt_row'           => $tktrow,
1325
-                'tax_label'         => $tax->get('PRC_name'),
1326
-                'tax_added'         => $tax_added,
1327
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1328
-                'tax_amount'        => $tax->get('PRC_amount')
1329
-            );
1330
-            $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1331
-                $template_args, $tktrow, $ticket, $this->_is_creating_event);
1332
-            $tax_rows .= EEH_Template::display_template($template, $template_args, true);
1333
-        }
1334
-
1335
-
1336
-        return $tax_rows;
1337
-    }
1338
-
1339
-
1340
-    protected function _get_tax_added(EE_Price $tax, $ticket)
1341
-    {
1342
-        $subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1343
-
1344
-        return $subtotal * $tax->get('PRC_amount') / 100;
1345
-    }
1346
-
1347
-
1348
-    protected function _get_ticket_price_row(
1349
-        $tktrow,
1350
-        $prcrow,
1351
-        $price,
1352
-        $default,
1353
-        $ticket,
1354
-        $show_trash = true,
1355
-        $show_create = true
1356
-    ) {
1357
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted') ? true : false;
1358
-        $template_args = array(
1359
-            'tkt_row'               => $default && empty($ticket) ? 'TICKETNUM' : $tktrow,
1360
-            'PRC_order'             => $default && empty($price) ? 'PRICENUM' : $prcrow,
1361
-            'edit_prices_name'      => $default && empty($price) ? 'PRICENAMEATTR' : 'edit_prices',
1362
-            'price_type_selector'   => $default && empty($price) ? $this->_get_base_price_template($tktrow, $prcrow,
1363
-                $price, $default) : $this->_get_price_type_selector($tktrow, $prcrow, $price, $default, $send_disabled),
1364
-            'PRC_ID'                => $default && empty($price) ? 0 : $price->ID(),
1365
-            'PRC_is_default'        => $default && empty($price) ? 0 : $price->get('PRC_is_default'),
1366
-            'PRC_name'              => $default && empty($price) ? '' : $price->get('PRC_name'),
1367
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1368
-            'show_plus_or_minus'    => $default && empty($price) ? '' : ' style="display:none;"',
1369
-            'show_plus'             => $default && empty($price) ? ' style="display:none;"' : ($price->is_discount() || $price->is_base_price() ? ' style="display:none;"' : ''),
1370
-            'show_minus'            => $default && empty($price) ? ' style="display:none;"' : ($price->is_discount() ? '' : ' style="display:none;"'),
1371
-            'show_currency_symbol'  => $default && empty($price) ? ' style="display:none"' : ($price->is_percent() ? ' style="display:none"' : ''),
1372
-            'PRC_amount'            => $default && empty($price) ? 0 : $price->get_pretty('PRC_amount',
1373
-                'localized_float'),
1374
-            'show_percentage'       => $default && empty($price) ? ' style="display:none;"' : ($price->is_percent() ? '' : ' style="display:none;"'),
1375
-            'show_trash_icon'       => $show_trash ? '' : ' style="display:none;"',
1376
-            'show_create_button'    => $show_create ? '' : ' style="display:none;"',
1377
-            'PRC_desc'              => $default && empty($price) ? '' : $price->get('PRC_desc'),
1378
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted') ? true : false
1379
-        );
1380
-
1381
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1382
-            $template_args, $tktrow, $prcrow, $price, $default, $ticket, $show_trash, $show_create,
1383
-            $this->_is_creating_event);
1384
-
1385
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php';
1386
-
1387
-        return EEH_Template::display_template($template, $template_args, true);
1388
-    }
1389
-
1390
-
1391
-    protected function _get_price_type_selector($tktrow, $prcrow, $price, $default, $disabled = false)
1392
-    {
1393
-        if ($price->is_base_price()) {
1394
-            return $this->_get_base_price_template($tktrow, $prcrow, $price, $default);
1395
-        } else {
1396
-            return $this->_get_price_modifier_template($tktrow, $prcrow, $price, $default, $disabled);
1397
-        }
1398
-
1399
-    }
1400
-
1401
-
1402
-    protected function _get_base_price_template($tktrow, $prcrow, $price, $default)
1403
-    {
1404
-        $template_args = array(
1405
-            'tkt_row'                   => $default ? 'TICKETNUM' : $tktrow,
1406
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $prcrow,
1407
-            'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1408
-            'PRT_name'                  => __('Price', 'event_espresso'),
1409
-            'price_selected_operator'   => '+',
1410
-            'price_selected_is_percent' => 0
1411
-        );
1412
-        $template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php';
1413
-
1414
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1415
-            $template_args, $tktrow, $prcrow, $price, $default, $this->_is_creating_event);
1416
-
1417
-        return EEH_Template::display_template($template, $template_args, true);
1418
-    }
1419
-
1420
-
1421
-    protected function _get_price_modifier_template($tktrow, $prcrow, $price, $default, $disabled = false)
1422
-    {
1423
-        $select_name                = $default && empty($price) ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]' : 'edit_prices[' . $tktrow . '][' . $prcrow . '][PRT_ID]';
1424
-        $price_types                = EE_Registry::instance()->load_model('Price_Type')->get_all(array(
1425
-            array(
1426
-                'OR' => array(
1427
-                    'PBT_ID'  => '2',
1428
-                    'PBT_ID*' => '3'
1429
-                )
1430
-            )
1431
-        ));
1432
-        $price_option_span_template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php';
1433
-        $all_price_types            = $default && empty($price) ? array(
1434
-            array(
1435
-                'id'   => 0,
1436
-                'text' => __('Select Modifier', 'event_espresso')
1437
-            )
1438
-        ) : array();
1439
-        $selected_price_type_id     = $default && empty($price) ? 0 : $price->type();
1440
-        $price_option_spans         = '';
1441
-        //setup pricetypes for selector
1442
-        foreach ($price_types as $price_type) {
1443
-            $all_price_types[] = array(
1444
-                'id'   => $price_type->ID(),
1445
-                'text' => $price_type->get('PRT_name'),
1446
-            );
1447
-
1448
-            //while we're in the loop let's setup the option spans used by js
1449
-            $spanargs = array(
1450
-                'PRT_ID'         => $price_type->ID(),
1451
-                'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1452
-                'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0
1453
-            );
1454
-            $price_option_spans .= EEH_Template::display_template($price_option_span_template, $spanargs, true);
1455
-        }
1456
-
1457
-        $select_params = $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"';
1458
-        $main_name     = $select_name;
1459
-        $select_name   = $disabled ? 'archive_price[' . $tktrow . '][' . $prcrow . '][PRT_ID]' : $main_name;
1460
-
1461
-        $template_args = array(
1462
-            'tkt_row'                   => $default ? 'TICKETNUM' : $tktrow,
1463
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $prcrow,
1464
-            'price_modifier_selector'   => EEH_Form_Fields::select_input($select_name, $all_price_types,
1465
-                $selected_price_type_id, $select_params, 'edit-price-PRT_ID'),
1466
-            'main_name'                 => $main_name,
1467
-            'selected_price_type_id'    => $selected_price_type_id,
1468
-            'price_option_spans'        => $price_option_spans,
1469
-            'price_selected_operator'   => $default && empty($price) ? '' : ($price->is_discount() ? '-' : '+'),
1470
-            'price_selected_is_percent' => $default && empty($price) ? '' : ($price->is_percent() ? 1 : 0),
1471
-            'disabled'                  => $disabled
1472
-        );
1473
-
1474
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1475
-            $template_args, $tktrow, $prcrow, $price, $default, $disabled, $this->_is_creating_event);
1476
-
1477
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php';
1478
-
1479
-        return EEH_Template::display_template($template, $template_args, true);
1480
-    }
1481
-
1482
-
1483
-    protected function _get_ticket_datetime_list_item($dttrow, $tktrow, $dtt, $ticket, $ticket_datetimes, $default)
1484
-    {
1485
-        $tkt_dtts      = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()]) ? $ticket_datetimes[$ticket->ID()] : array();
1486
-        $template_args = array(
1487
-            'dtt_row'                  => $default && ! $dtt instanceof EE_Datetime ? 'DTTNUM' : $dttrow,
1488
-            'tkt_row'                  => $default ? 'TICKETNUM' : $tktrow,
1489
-            'ticket_datetime_selected' => in_array($dttrow, $tkt_dtts) ? ' ticket-selected' : '',
1490
-            'ticket_datetime_checked'  => in_array($dttrow, $tkt_dtts) ? ' checked="checked"' : '',
1491
-            'DTT_name'                 => $default && empty($dtt) ? 'DTTNAME' : $dtt->get_dtt_display_name(true),
1492
-            'tkt_status_class'         => '',
1493
-        );
1494
-
1495
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
1496
-            $template_args, $dttrow, $tktrow, $dtt, $ticket, $ticket_datetimes, $default, $this->_is_creating_event);
1497
-        $template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php';
1498
-
1499
-        return EEH_Template::display_template($template, $template_args, true);
1500
-    }
1501
-
1502
-
1503
-    protected function _get_ticket_js_structure($all_dtts, $all_tickets)
1504
-    {
1505
-        $template_args = array(
1506
-            'default_datetime_edit_row'                => $this->_get_dtt_edit_row('DTTNUM', null, true, $all_dtts),
1507
-            'default_ticket_row'                       => $this->_get_ticket_row('TICKETNUM', null, array(), array(),
1508
-                true),
1509
-            'default_price_row'                        => $this->_get_ticket_price_row('TICKETNUM', 'PRICENUM', null,
1510
-                true, null),
1511
-            'default_price_rows'                       => '',
1512
-            'default_base_price_amount'                => 0,
1513
-            'default_base_price_name'                  => '',
1514
-            'default_base_price_description'           => '',
1515
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template('TICKETNUM', 'PRICENUM',
1516
-                null, true),
1517
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row('DTTNUM', null, array(),
1518
-                array(), true),
1519
-            'existing_available_datetime_tickets_list' => '',
1520
-            'existing_available_ticket_datetimes_list' => '',
1521
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item('DTTNUM', 'TICKETNUM',
1522
-                null, null, array(), true),
1523
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item('DTTNUM', 'TICKETNUM',
1524
-                null, null, array(), true)
1525
-        );
1526
-
1527
-        $tktrow = 1;
1528
-        foreach ($all_tickets as $ticket) {
1529
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item('DTTNUM',
1530
-                $tktrow, null, $ticket, array(), true);
1531
-            $tktrow++;
1532
-        }
1533
-
1534
-
1535
-        $dttrow = 1;
1536
-        foreach ($all_dtts as $dtt) {
1537
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item($dttrow,
1538
-                'TICKETNUM', $dtt, null, array(), true);
1539
-            $dttrow++;
1540
-        }
1541
-
1542
-        $default_prices = EE_Registry::instance()->load_model('Price')->get_all_default_prices();
1543
-        $prcrow         = 1;
1544
-        foreach ($default_prices as $price) {
1545
-            if ($price->is_base_price()) {
1546
-                $template_args['default_base_price_amount']      = $price->get_pretty('PRC_amount', 'localized_float');
1547
-                $template_args['default_base_price_name']        = $price->get('PRC_name');
1548
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
1549
-                $prcrow++;
1550
-                continue;
1551
-            }
1552
-            $show_trash  = (count($default_prices) > 1 && $prcrow === 1) || count($default_prices) === 1 ? false : true;
1553
-            $show_create = count($default_prices) > 1 && count($default_prices) !== $prcrow ? false : true;
1554
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row('TICKETNUM', $prcrow, $price, true,
1555
-                null, $show_trash, $show_create);
1556
-            $prcrow++;
1557
-        }
1558
-
1559
-        $template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
1560
-            $template_args, $all_dtts, $all_tickets, $this->_is_creating_event);
1561
-
1562
-        $template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php';
1563
-
1564
-        return EEH_Template::display_template($template, $template_args, true);
1565
-    }
34
+	/**
35
+	 * This property is just used to hold the status of whether an event is currently being
36
+	 * created (true) or edited (false)
37
+	 * @access protected
38
+	 * @var bool
39
+	 */
40
+	protected $_is_creating_event;
41
+
42
+
43
+	/**
44
+	 * Used to contain the format strings for date and time that will be used for php date and
45
+	 * time.
46
+	 *
47
+	 * Is set in the _set_hooks_properties() method.
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $_date_format_strings;
52
+
53
+
54
+	protected function _set_hooks_properties()
55
+	{
56
+		$this->_name = 'pricing';
57
+
58
+		//capability check
59
+		if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_default_prices',
60
+			'advanced_ticket_datetime_metabox')
61
+		) {
62
+			return;
63
+		}
64
+
65
+
66
+		//if we were going to add our own metaboxes we'd use the below.
67
+		$this->_metaboxes = array(
68
+			0 => array(
69
+				'page_route' => array('edit', 'create_new'),
70
+				'func'       => 'pricing_metabox',
71
+				'label'      => __('Event Tickets & Datetimes', 'event_espresso'),
72
+				'priority'   => 'high',
73
+				'context'    => 'normal'
74
+			),
75
+
76
+		);/**/
77
+
78
+		$this->_remove_metaboxes = array(
79
+			0 => array(
80
+				'page_route' => array('edit', 'create_new'),
81
+				'id'         => 'espresso_event_editor_tickets',
82
+				'context'    => 'normal'
83
+			)
84
+		);
85
+
86
+		/**
87
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
88
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
89
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
90
+		 *
91
+		 * @since 4.6.7
92
+		 *
93
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
94
+		 */
95
+		$this->_date_format_strings = apply_filters('FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
96
+			array(
97
+				'date' => 'Y-m-d',
98
+				'time' => 'h:i a'
99
+			));
100
+
101
+		//validate
102
+		$this->_date_format_strings['date'] = isset($this->_date_format_strings['date']) ? $this->_date_format_strings['date'] : null;
103
+		$this->_date_format_strings['time'] = isset($this->_date_format_strings['time']) ? $this->_date_format_strings['time'] : null;
104
+
105
+		//validate format strings
106
+		$format_validation = EEH_DTT_Helper::validate_format_string($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
107
+		if (is_array($format_validation)) {
108
+			$msg = '<p>' . sprintf(__('The format "%s" was likely added via a filter and is invalid for the following reasons:',
109
+					'event_espresso'),
110
+					$this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']) . '</p><ul>';
111
+			foreach ($format_validation as $error) {
112
+				$msg .= '<li>' . $error . '</li>';
113
+			}
114
+			$msg .= '</ul></p><p>' . sprintf(__('%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
115
+					'event_espresso'), '<span style="color:#D54E21;">', '</span>') . '</p>';
116
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
117
+			$this->_date_format_strings = array(
118
+				'date' => 'Y-m-d',
119
+				'time' => 'h:i a'
120
+			);
121
+		}
122
+
123
+
124
+		$this->_scripts_styles = array(
125
+			'registers'   => array(
126
+				'ee-tickets-datetimes-css' => array(
127
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
128
+					'type' => 'css'
129
+				),
130
+				'ee-dtt-ticket-metabox'    => array(
131
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
132
+					'depends' => array('ee-datepicker', 'ee-dialog', 'underscore')
133
+				)
134
+			),
135
+			'deregisters' => array(
136
+				'event-editor-css'       => array('type' => 'css'),
137
+				'event-datetime-metabox' => array('type' => 'js')
138
+			),
139
+			'enqueues'    => array(
140
+				'ee-tickets-datetimes-css' => array('edit', 'create_new'),
141
+				'ee-dtt-ticket-metabox'    => array('edit', 'create_new')
142
+			),
143
+			'localize'    => array(
144
+				'ee-dtt-ticket-metabox' => array(
145
+					'DTT_TRASH_BLOCK'       => array(
146
+						'main_warning'            => __('The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
147
+							'event_espresso'),
148
+						'after_warning'           => __('In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
149
+							'event_espresso'),
150
+						'cancel_button'           => '<button class="button-secondary ee-modal-cancel">' . __('Cancel',
151
+								'event_espresso') . '</button>',
152
+						'close_button'            => '<button class="button-secondary ee-modal-cancel">' . __('Close',
153
+								'event_espresso') . '</button>',
154
+						'single_warning_from_tkt' => __('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.',
155
+							'event_espresso'),
156
+						'single_warning_from_dtt' => __('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.',
157
+							'event_espresso'),
158
+						'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">' . __('Dismiss',
159
+								'event_espresso') . '</button>'
160
+					),
161
+					'DTT_ERROR_MSG'         => array(
162
+						'no_ticket_name' => __('General Admission', 'event_espresso'),
163
+						'dismiss_button' => '<div class="save-cancel-button-container"><button class="button-secondary ee-modal-cancel">' . __('Dismiss',
164
+								'event_espresso') . '</button></div>'
165
+					),
166
+					'DTT_OVERSELL_WARNING'  => array(
167
+						'datetime_ticket' => __('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.',
168
+							'event_espresso'),
169
+						'ticket_datetime' => __('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.',
170
+							'event_espresso')
171
+					),
172
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats($this->_date_format_strings['date'],
173
+						$this->_date_format_strings['time']),
174
+					'DTT_START_OF_WEEK'     => array('dayValue' => (int)get_option('start_of_week'))
175
+				)
176
+			)
177
+		);
178
+
179
+
180
+		add_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
181
+			array($this, 'autosave_handling'), 10);
182
+		add_filter('FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
183
+			array($this, 'caf_updates'), 10);
184
+	}
185
+
186
+
187
+	public function caf_updates($update_callbacks)
188
+	{
189
+		foreach ($update_callbacks as $key => $callback) {
190
+			if ($callback[1] == '_default_tickets_update') {
191
+				unset($update_callbacks[$key]);
192
+			}
193
+		}
194
+
195
+		$update_callbacks[] = array($this, 'dtt_and_tickets_caf_update');
196
+
197
+		return $update_callbacks;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
203
+	 *
204
+	 * @param  EE_Event $evtobj The Event object we're attaching data to
205
+	 * @param  array    $data   The request data from the form
206
+	 *
207
+	 * @return bool             success or fail
208
+	 */
209
+	public function dtt_and_tickets_caf_update($evtobj, $data)
210
+	{
211
+		//first we need to start with datetimes cause they are the "root" items attached to events.
212
+		$saved_dtts = $this->_update_dtts($evtobj, $data);
213
+		//next tackle the tickets (and prices?)
214
+		$this->_update_tkts($evtobj, $saved_dtts, $data);
215
+	}
216
+
217
+
218
+	/**
219
+	 * update event_datetimes
220
+	 *
221
+	 * @param  EE_Event $evt_obj Event being updated
222
+	 * @param  array    $data    the request data from the form
223
+	 *
224
+	 * @return EE_Datetime[]
225
+	 */
226
+	protected function _update_dtts($evt_obj, $data)
227
+	{
228
+		$timezone       = isset($data['timezone_string']) ? $data['timezone_string'] : null;
229
+		$saved_dtt_ids  = array();
230
+		$saved_dtt_objs = array();
231
+
232
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
233
+			//trim all values to ensure any excess whitespace is removed.
234
+			$dtt                = array_map(
235
+				function ($datetime_data) {
236
+					return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
237
+				},
238
+				$dtt
239
+			);
240
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end'] : $dtt['DTT_EVT_start'];
241
+			$datetime_values    = array(
242
+				'DTT_ID'          => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
243
+				'DTT_name'        => ! empty($dtt['DTT_name']) ? $dtt['DTT_name'] : '',
244
+				'DTT_description' => ! empty($dtt['DTT_description']) ? $dtt['DTT_description'] : '',
245
+				'DTT_EVT_start'   => $dtt['DTT_EVT_start'],
246
+				'DTT_EVT_end'     => $dtt['DTT_EVT_end'],
247
+				'DTT_reg_limit'   => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
248
+				'DTT_order'       => ! isset($dtt['DTT_order']) ? $row : $dtt['DTT_order'],
249
+			);
250
+
251
+			//if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
252
+
253
+			if ( ! empty($dtt['DTT_ID'])) {
254
+				$DTM = EE_Registry::instance()->load_model('Datetime', array($timezone))->get_one_by_ID($dtt['DTT_ID']);
255
+
256
+				//set date and time format according to what is set in this class.
257
+				$DTM->set_date_format($this->_date_format_strings['date']);
258
+				$DTM->set_time_format($this->_date_format_strings['time']);
259
+
260
+				foreach ($datetime_values as $field => $value) {
261
+					$DTM->set($field, $value);
262
+				}
263
+
264
+				// make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.
265
+				// We need to do this so we dont' TRASH the parent DTT.(save the ID for both key and value to avoid duplications)
266
+				$saved_dtt_ids[$DTM->ID()] = $DTM->ID();
267
+
268
+			} else {
269
+				$DTM = EE_Registry::instance()->load_class(
270
+					'Datetime',
271
+					array(
272
+						$datetime_values,
273
+						$timezone,
274
+						array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
275
+					),
276
+					false,
277
+					false
278
+				);
279
+
280
+				foreach ($datetime_values as $field => $value) {
281
+					$DTM->set($field, $value);
282
+				}
283
+			}
284
+
285
+
286
+			$DTM->save();
287
+			$DTM = $evt_obj->_add_relation_to($DTM, 'Datetime');
288
+			$evt_obj->save();
289
+
290
+			//before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
291
+			if ($DTM->get_raw('DTT_EVT_start') > $DTM->get_raw('DTT_EVT_end')) {
292
+				$DTM->set('DTT_EVT_end', $DTM->get('DTT_EVT_start'));
293
+				$DTM = EEH_DTT_Helper::date_time_add($DTM, 'DTT_EVT_end', 'days');
294
+				$DTM->save();
295
+			}
296
+
297
+			//	now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
298
+			// because it is possible there was a new one created for the autosave.
299
+			// (save the ID for both key and value to avoid duplications)
300
+			$saved_dtt_ids[$DTM->ID()] = $DTM->ID();
301
+			$saved_dtt_objs[$row]      = $DTM;
302
+
303
+			//todo if ANY of these updates fail then we want the appropriate global error message.
304
+		}
305
+
306
+		//now we need to REMOVE any dtts that got deleted.  Keep in mind that this process will only kick in for DTT's that don't have any DTT_sold on them. So its safe to permanently delete at this point.
307
+		$old_datetimes = explode(',', $data['datetime_IDs']);
308
+		$old_datetimes = $old_datetimes[0] == '' ? array() : $old_datetimes;
309
+
310
+		if (is_array($old_datetimes)) {
311
+			$dtts_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
312
+			foreach ($dtts_to_delete as $id) {
313
+				$id = absint($id);
314
+				if (empty($id)) {
315
+					continue;
316
+				}
317
+
318
+				$dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
319
+
320
+				//remove tkt relationships.
321
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
322
+				foreach ($related_tickets as $tkt) {
323
+					$dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
324
+				}
325
+
326
+				$evt_obj->_remove_relation_to($id, 'Datetime');
327
+				$dtt_to_remove->refresh_cache_of_related_objects();
328
+
329
+			}
330
+		}
331
+
332
+		return $saved_dtt_objs;
333
+	}
334
+
335
+
336
+	/**
337
+	 * update tickets
338
+	 *
339
+	 * @param  EE_Event      $evtobj     Event object being updated
340
+	 * @param  EE_Datetime[] $saved_dtts an array of datetime ids being updated
341
+	 * @param  array         $data       incoming request data
342
+	 *
343
+	 * @return EE_Ticket[]
344
+	 */
345
+	protected function _update_tkts($evtobj, $saved_dtts, $data)
346
+	{
347
+
348
+		$new_tkt     = null;
349
+		$new_default = null;
350
+		//stripslashes because WP filtered the $_POST ($data) array to add slashes
351
+		$data          = stripslashes_deep($data);
352
+		$timezone      = isset($data['timezone_string']) ? $data['timezone_string'] : null;
353
+		$saved_tickets = $dtts_on_existing = array();
354
+		$old_tickets   = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
355
+
356
+		//load money helper
357
+
358
+		foreach ($data['edit_tickets'] as $row => $tkt) {
359
+
360
+			$update_prices = $create_new_TKT = false;
361
+
362
+			//figure out what dtts were added to the ticket and what dtts were removed from the ticket in the session.
363
+
364
+			$starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
365
+			$tkt_dtt_rows          = explode(',', $data['ticket_datetime_rows'][$row]);
366
+			$dtts_added            = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
367
+			$dtts_removed          = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
368
+
369
+			// trim inputs to ensure any excess whitespace is removed.
370
+			$tkt = array_map(
371
+				function ($ticket_data) {
372
+					return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
373
+				},
374
+				$tkt
375
+			);
376
+
377
+			//note we are doing conversions to floats here instead of allowing EE_Money_Field to handle because we're doing calcs prior to using the models.
378
+			//note incoming ['TKT_price'] value is already in standard notation (via js).
379
+			$ticket_price = isset($tkt['TKT_price']) ? round((float)$tkt['TKT_price'], 3) : 0;
380
+
381
+			//note incoming base price needs converted from localized value.
382
+			$base_price = isset($tkt['TKT_base_price']) ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price']) : 0;
383
+			//if ticket price == 0 and $base_price != 0 then ticket price == base_price
384
+			$ticket_price  = $ticket_price === 0 && $base_price !== 0 ? $base_price : $ticket_price;
385
+			$base_price_id = isset($tkt['TKT_base_price_ID']) ? $tkt['TKT_base_price_ID'] : 0;
386
+
387
+			$price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row]) ? $data['edit_prices'][$row] : array();
388
+
389
+			$now = null;
390
+			if (empty($tkt['TKT_start_date'])) {
391
+				//lets' use now in the set timezone.
392
+				$now                   = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
393
+				$tkt['TKT_start_date'] = $now->format($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
394
+			}
395
+
396
+			if (empty($tkt['TKT_end_date'])) {
397
+				/**
398
+				 * set the TKT_end_date to the first datetime attached to the ticket.
399
+				 */
400
+				$first_dtt           = $saved_dtts[reset($tkt_dtt_rows)];
401
+				$tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_format_strings['date'] . ' ' . $this->_date_format_string['time']);
402
+			}
403
+
404
+			$TKT_values = array(
405
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
406
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
407
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
408
+				'TKT_description' => ! empty($tkt['TKT_description']) && $tkt['TKT_description'] != __('You can modify this description',
409
+					'event_espresso') ? $tkt['TKT_description'] : '',
410
+				'TKT_start_date'  => $tkt['TKT_start_date'],
411
+				'TKT_end_date'    => $tkt['TKT_end_date'],
412
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
413
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
414
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
415
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
416
+				'TKT_row'         => $row,
417
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
418
+				'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
419
+				'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
420
+				'TKT_price'       => $ticket_price
421
+			);
422
+
423
+
424
+			//if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
425
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
426
+				$TKT_values['TKT_ID']         = 0;
427
+				$TKT_values['TKT_is_default'] = 0;
428
+				$update_prices                = true;
429
+			}
430
+
431
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
432
+			// we actually do our saves ahead of doing any add_relations to
433
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
434
+			// but DID have it's items modified.
435
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
436
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
437
+			if (absint($TKT_values['TKT_ID'])) {
438
+				$TKT = EE_Registry::instance()->load_model('Ticket', array($timezone))->get_one_by_ID($tkt['TKT_ID']);
439
+				if ($TKT instanceof EE_Ticket) {
440
+
441
+					$TKT = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
442
+					// are there any registrations using this ticket ?
443
+					$tickets_sold = $TKT->count_related(
444
+						'Registration',
445
+						array(
446
+							array(
447
+								'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete))
448
+							)
449
+						)
450
+					);
451
+					//set ticket formats
452
+					$TKT->set_date_format($this->_date_format_strings['date']);
453
+					$TKT->set_time_format($this->_date_format_strings['time']);
454
+
455
+					// let's just check the total price for the existing ticket
456
+					// and determine if it matches the new total price.
457
+					// if they are different then we create a new ticket (if tkts sold)
458
+					// if they aren't different then we go ahead and modify existing ticket.
459
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price != $TKT->price() && ! $TKT->deleted()
460
+						? true : false;
461
+
462
+					//set new values
463
+					foreach ($TKT_values as $field => $value) {
464
+						if ($field === 'TKT_qty') {
465
+							$TKT->set_qty($value);
466
+						} else {
467
+							$TKT->set($field, $value);
468
+						}
469
+					}
470
+
471
+					//if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
472
+					if ($create_new_TKT) {
473
+						$new_tkt = $this->_duplicate_ticket($TKT, $price_rows, $ticket_price, $base_price,
474
+							$base_price_id);
475
+					}
476
+				}
477
+
478
+			} else {
479
+				// no TKT_id so a new TKT
480
+				$TKT = EE_Ticket::new_instance(
481
+					$TKT_values,
482
+					$timezone,
483
+					array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
484
+				);
485
+				if ($TKT instanceof EE_Ticket) {
486
+					// make sure ticket has an ID of setting relations won't work
487
+					$TKT->save();
488
+					$TKT           = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
489
+					$update_prices = true;
490
+				}
491
+			}
492
+			//make sure any current values have been saved.
493
+			//$TKT->save();
494
+
495
+			//before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
496
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
497
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
498
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
499
+			}
500
+
501
+			//let's make sure the base price is handled
502
+			$TKT = ! $create_new_TKT ? $this->_add_prices_to_ticket(array(), $TKT, $update_prices, $base_price,
503
+				$base_price_id) : $TKT;
504
+
505
+			//add/update price_modifiers
506
+			$TKT = ! $create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $TKT, $update_prices) : $TKT;
507
+
508
+			//need to make sue that the TKT_price is accurate after saving the prices.
509
+			$TKT->ensure_TKT_Price_correct();
510
+
511
+			//handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
512
+			if ( ! defined('DOING_AUTOSAVE')) {
513
+				if ( ! empty($tkt['TKT_is_default_selector'])) {
514
+					$update_prices = true;
515
+					$new_default   = clone $TKT;
516
+					$new_default->set('TKT_ID', 0);
517
+					$new_default->set('TKT_is_default', 1);
518
+					$new_default->set('TKT_row', 1);
519
+					$new_default->set('TKT_price', $ticket_price);
520
+					//remove any dtt relations cause we DON'T want dtt relations attached (note this is just removing the cached relations in the object)
521
+					$new_default->_remove_relations('Datetime');
522
+					//todo we need to add the current attached prices as new prices to the new default ticket.
523
+					$new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
524
+					//don't forget the base price!
525
+					$new_default = $this->_add_prices_to_ticket(array(), $new_default, $update_prices, $base_price,
526
+						$base_price_id);
527
+					$new_default->save();
528
+					do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket', $new_default,
529
+						$row, $TKT, $data);
530
+				}
531
+			}
532
+
533
+
534
+			//DO ALL dtt relationships for both current tickets and any archived tickets for the given dtt that are related to the current ticket. TODO... not sure exactly how we're going to do this considering we don't know what current ticket the archived tickets are related to (and TKT_parent is used for autosaves so that's not a field we can reliably use).
535
+
536
+
537
+			//let's assign any tickets that have been setup to the saved_tickets tracker
538
+			//save existing TKT
539
+			$TKT->save();
540
+			if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
541
+				//save new TKT
542
+				$new_tkt->save();
543
+				//add new ticket to array
544
+				$saved_tickets[$new_tkt->ID()] = $new_tkt;
545
+
546
+				do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket', $new_tkt, $row, $tkt, $data);
547
+
548
+			} else {
549
+				//add tkt to saved tkts
550
+				$saved_tickets[$TKT->ID()] = $TKT;
551
+
552
+				do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket', $TKT, $row, $tkt, $data);
553
+			}
554
+
555
+		}
556
+
557
+		// now we need to handle tickets actually "deleted permanently".
558
+		// There are cases where we'd want this to happen
559
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
560
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
561
+		// No sense in keeping all the related data in the db!
562
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
563
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
564
+
565
+		foreach ($tickets_removed as $id) {
566
+			$id = absint($id);
567
+
568
+			//get the ticket for this id
569
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
570
+
571
+			//if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
572
+			if ($tkt_to_remove->get('TKT_is_default')) {
573
+				continue;
574
+			}
575
+
576
+			// if this tkt has any registrations attached so then we just ARCHIVE
577
+			// because we don't actually permanently delete these tickets.
578
+			if ($tkt_to_remove->count_related('Registration') > 0) {
579
+				$tkt_to_remove->delete();
580
+				continue;
581
+			}
582
+
583
+			// need to get all the related datetimes on this ticket and remove from every single one of them
584
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
585
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
586
+
587
+			foreach ($dtts as $dtt) {
588
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
589
+			}
590
+
591
+			// need to do the same for prices (except these prices can also be deleted because again,
592
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
593
+			$tkt_to_remove->delete_related_permanently('Price');
594
+
595
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
596
+
597
+			// finally let's delete this ticket
598
+			// (which should not be blocked at this point b/c we've removed all our relationships)
599
+			$tkt_to_remove->delete_permanently();
600
+		}
601
+
602
+		return $saved_tickets;
603
+	}
604
+
605
+
606
+	/**
607
+	 *
608
+	 * @access  protected
609
+	 *
610
+	 * @param \EE_Ticket     $ticket
611
+	 * @param \EE_Datetime[] $saved_datetimes
612
+	 * @param \EE_Datetime[] $added_datetimes
613
+	 * @param \EE_Datetime[] $removed_datetimes
614
+	 *
615
+	 * @return \EE_Ticket
616
+	 * @throws \EE_Error
617
+	 */
618
+	protected function _update_ticket_datetimes(
619
+		EE_Ticket $ticket,
620
+		$saved_datetimes = array(),
621
+		$added_datetimes = array(),
622
+		$removed_datetimes = array()
623
+	) {
624
+
625
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
626
+		// and removing the ticket from datetimes it got removed from.
627
+
628
+		// first let's add datetimes
629
+		if ( ! empty($added_datetimes) && is_array($added_datetimes)) {
630
+			foreach ($added_datetimes as $row_id) {
631
+				$row_id = (int)$row_id;
632
+				if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
633
+					$ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
634
+					// Is this an existing ticket (has an ID) and does it have any sold?
635
+					// If so, then we need to add that to the DTT sold because this DTT is getting added.
636
+					if ($ticket->ID() && $ticket->sold() > 0) {
637
+						$saved_datetimes[$row_id]->increase_sold($ticket->sold());
638
+						$saved_datetimes[$row_id]->save();
639
+					}
640
+				}
641
+			}
642
+		}
643
+		// then remove datetimes
644
+		if ( ! empty($removed_datetimes) && is_array($removed_datetimes)) {
645
+			foreach ($removed_datetimes as $row_id) {
646
+				$row_id = (int)$row_id;
647
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
648
+				// So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
649
+				if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
650
+					$ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
651
+					// Is this an existing ticket (has an ID) and does it have any sold?
652
+					// If so, then we need to remove it's sold from the DTT_sold.
653
+					// but NOT if the ticket is being removed because it is getting archived !!!
654
+					// Because in that scenario, the archived ticket is likely still a valid ticket
655
+					// and needs to still have it's quantity sold to count in calculations
656
+					if ($ticket->ID() && $ticket->sold() > 0 && ! $ticket->deleted()) {
657
+						$saved_datetimes[$row_id]->decrease_sold($ticket->sold());
658
+						$saved_datetimes[$row_id]->save();
659
+					}
660
+				}
661
+			}
662
+		}
663
+		// cap ticket qty by datetime reg limits
664
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
665
+
666
+		return $ticket;
667
+	}
668
+
669
+
670
+	/**
671
+	 *
672
+	 * @access  protected
673
+	 *
674
+	 * @param \EE_Ticket $ticket
675
+	 * @param array      $price_rows
676
+	 * @param int        $ticket_price
677
+	 * @param int        $base_price
678
+	 * @param int        $base_price_id
679
+	 *
680
+	 * @return \EE_Ticket
681
+	 * @throws \EE_Error
682
+	 */
683
+	protected function _duplicate_ticket(
684
+		EE_Ticket $ticket,
685
+		$price_rows = array(),
686
+		$ticket_price = 0,
687
+		$base_price = 0,
688
+		$base_price_id = 0
689
+	) {
690
+
691
+		// create new ticket that's a copy of the existing
692
+		// except a new id of course (and not archived)
693
+		// AND has the new TKT_price associated with it.
694
+		$new_ticket = clone $ticket;
695
+		$new_ticket->set('TKT_ID', 0);
696
+		$new_ticket->set_deleted(0);
697
+		$new_ticket->set_price($ticket_price);
698
+		$new_ticket->set_sold(0);
699
+		// let's get a new ID for this ticket
700
+		$new_ticket->save();
701
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
702
+		$datetimes_on_existing = $ticket->get_many_related('Datetime');
703
+		$new_ticket            = $this->_update_ticket_datetimes(
704
+			$new_ticket,
705
+			$datetimes_on_existing,
706
+			array_keys($datetimes_on_existing)
707
+		);
708
+
709
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
710
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
711
+		// available.
712
+		if ($ticket->sold() > 0) {
713
+			$new_qty = $ticket->qty() - $ticket->sold();
714
+			$new_ticket->set_qty($new_qty);
715
+		}
716
+		//now we update the prices just for this ticket
717
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
718
+		//and we update the base price
719
+		$new_ticket = $this->_add_prices_to_ticket(array(), $new_ticket, true, $base_price, $base_price_id);
720
+
721
+		return $new_ticket;
722
+	}
723
+
724
+
725
+	/**
726
+	 * This attaches a list of given prices to a ticket.
727
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
728
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
729
+	 * price info and prices are automatically "archived" via the ticket.
730
+	 *
731
+	 * @access  private
732
+	 *
733
+	 * @param array     $prices        Array of prices from the form.
734
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
735
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
736
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
737
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
738
+	 *
739
+	 * @return EE_Ticket
740
+	 */
741
+	protected function _add_prices_to_ticket(
742
+		$prices = array(),
743
+		EE_Ticket $ticket,
744
+		$new_prices = false,
745
+		$base_price = false,
746
+		$base_price_id = false
747
+	) {
748
+
749
+		//let's just get any current prices that may exist on the given ticket so we can remove any prices that got trashed in this session.
750
+		$current_prices_on_ticket = $base_price !== false ? $ticket->base_price(true) : $ticket->price_modifiers();
751
+
752
+		$updated_prices = array();
753
+
754
+		// if $base_price ! FALSE then updating a base price.
755
+		if ($base_price !== false) {
756
+			$prices[1] = array(
757
+				'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
758
+				'PRT_ID'     => 1,
759
+				'PRC_amount' => $base_price,
760
+				'PRC_name'   => $ticket->get('TKT_name'),
761
+				'PRC_desc'   => $ticket->get('TKT_description')
762
+			);
763
+		}
764
+
765
+		//possibly need to save tkt
766
+		if ( ! $ticket->ID()) {
767
+			$ticket->save();
768
+		}
769
+
770
+		foreach ($prices as $row => $prc) {
771
+			$prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
772
+			if (empty($prt_id)) {
773
+				continue;
774
+			} //prices MUST have a price type id.
775
+			$PRC_values = array(
776
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
777
+				'PRT_ID'         => $prt_id,
778
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
779
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
780
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
781
+				'PRC_is_default' => false,
782
+				//make sure we set PRC_is_default to false for all ticket saves from event_editor
783
+				'PRC_order'      => $row
784
+			);
785
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
786
+				$PRC_values['PRC_ID'] = 0;
787
+				$PRC                  = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
788
+			} else {
789
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
790
+				//update this price with new values
791
+				foreach ($PRC_values as $field => $newprc) {
792
+					$PRC->set($field, $newprc);
793
+				}
794
+			}
795
+			$PRC->save();
796
+			$prcid                  = $PRC->ID();
797
+			$updated_prices[$prcid] = $PRC;
798
+			$ticket->_add_relation_to($PRC, 'Price');
799
+		}
800
+
801
+		//now let's remove any prices that got removed from the ticket
802
+		if ( ! empty ($current_prices_on_ticket)) {
803
+			$current          = array_keys($current_prices_on_ticket);
804
+			$updated          = array_keys($updated_prices);
805
+			$prices_to_remove = array_diff($current, $updated);
806
+			if ( ! empty($prices_to_remove)) {
807
+				foreach ($prices_to_remove as $prc_id) {
808
+					$p = $current_prices_on_ticket[$prc_id];
809
+					$ticket->_remove_relation_to($p, 'Price');
810
+
811
+					//delete permanently the price
812
+					$p->delete_permanently();
813
+				}
814
+			}
815
+		}
816
+
817
+		return $ticket;
818
+	}
819
+
820
+
821
+	public function autosave_handling($event_admin_obj)
822
+	{
823
+		return $event_admin_obj; //doing nothing for the moment.
824
+		//todo when I get to this remember that I need to set the template args on the $event_admin_obj (use the set_template_args() method)
825
+
826
+		/**
827
+		 * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
828
+		 *
829
+		 * 1. TKT_is_default_selector (visible)
830
+		 * 2. TKT_is_default (hidden)
831
+		 *
832
+		 * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want this ticket to be saved as a default.
833
+		 *
834
+		 * The tricky part is, on an initial display on create or edit (or after manually updating), the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true if this is a create.  However, after an autosave, users will want some sort of indicator that the TKT HAS been saved as a default.. in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
835
+		 * On Autosave:
836
+		 * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements, then set the TKT_is_default to false.
837
+		 * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
838
+		 * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
839
+		 */
840
+	}
841
+
842
+
843
+	public function pricing_metabox()
844
+	{
845
+		$existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
846
+
847
+		$evtobj = $this->_adminpage_obj->get_cpt_model_obj();
848
+
849
+		//set is_creating_event property.
850
+		$evtID                    = $evtobj->ID();
851
+		$this->_is_creating_event = absint($evtID) != 0 ? false : true;
852
+
853
+		//default main template args
854
+		$main_template_args = array(
855
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link('event_editor_event_datetimes_help_tab',
856
+				$this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
857
+			//todo need to add a filter to the template for the help text in the Events_Admin_Page core file so we can add further help
858
+			'existing_datetime_ids'    => '',
859
+			'total_dtt_rows'           => 1,
860
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link('add_new_dtt_info',
861
+				$this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
862
+			//todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
863
+			'datetime_rows'            => '',
864
+			'show_tickets_container'   => '',
865
+			//$this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
866
+			'ticket_rows'              => '',
867
+			'existing_ticket_ids'      => '',
868
+			'total_ticket_rows'        => 1,
869
+			'ticket_js_structure'      => '',
870
+			'ee_collapsible_status'    => ' ee-collapsible-open'
871
+			//$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
872
+		);
873
+
874
+		$timezone = $evtobj instanceof EE_Event ? $evtobj->timezone_string() : null;
875
+
876
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
877
+
878
+		/**
879
+		 * 1. Start with retrieving Datetimes
880
+		 * 2. For each datetime get related tickets
881
+		 * 3. For each ticket get related prices
882
+		 */
883
+
884
+		$DTM   = EE_Registry::instance()->load_model('Datetime', array($timezone));
885
+		$times = $DTM->get_all_event_dates($evtID);
886
+
887
+
888
+		$main_template_args['total_dtt_rows'] = count($times);
889
+
890
+		/** @see https://events.codebasehq.com/projects/event-espresso/tickets/9486 for why we are counting $dttrow and then setting that on the Datetime object */
891
+		$dttrow = 1;
892
+		foreach ($times as $time) {
893
+			$dttid = $time->get('DTT_ID');
894
+			$time->set('DTT_order', $dttrow);
895
+			$existing_datetime_ids[] = $dttid;
896
+
897
+			//tickets attached
898
+			$related_tickets = $time->ID() > 0 ? $time->get_many_related('Ticket', array(
899
+				array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
900
+				'default_where_conditions' => 'none',
901
+				'order_by'                 => array('TKT_order' => 'ASC')
902
+			)) : array();
903
+
904
+			//if there are no related tickets this is likely a new event OR autodraft
905
+			// event so we need to generate the default tickets because dtts
906
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
907
+			// datetime on the event.
908
+			if (empty ($related_tickets) && count($times) < 2) {
909
+				$related_tickets = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
910
+
911
+				//this should be ordered by TKT_ID, so let's grab the first default ticket (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
912
+				$default_prices = EEM_Price::instance()->get_all_default_prices();
913
+
914
+				$main_default_ticket = reset($related_tickets);
915
+				if ($main_default_ticket instanceof EE_Ticket) {
916
+					foreach ($default_prices as $default_price) {
917
+						if ($default_price->is_base_price()) {
918
+							continue;
919
+						}
920
+						$main_default_ticket->cache('Price', $default_price);
921
+					}
922
+				}
923
+			}
924
+
925
+
926
+			//we can't actually setup rows in this loop yet cause we don't know all the unique tickets for this event yet (tickets are linked through all datetimes). So we're going to temporarily cache some of that information.
927
+
928
+			//loop through and setup the ticket rows and make sure the order is set.
929
+			foreach ($related_tickets as $ticket) {
930
+				$tktid  = $ticket->get('TKT_ID');
931
+				$tktrow = $ticket->get('TKT_row');
932
+				//we only want unique tickets in our final display!!
933
+				if ( ! in_array($tktid, $existing_ticket_ids)) {
934
+					$existing_ticket_ids[] = $tktid;
935
+					$all_tickets[]         = $ticket;
936
+				}
937
+
938
+				//temporary cache of this ticket info for this datetime for later processing of datetime rows.
939
+				$datetime_tickets[$dttid][] = $tktrow;
940
+
941
+				//temporary cache of this datetime info for this ticket for later processing of ticket rows.
942
+				if ( ! isset($ticket_datetimes[$tktid]) || ! in_array($dttrow, $ticket_datetimes[$tktid])) {
943
+					$ticket_datetimes[$tktid][] = $dttrow;
944
+				}
945
+			}
946
+			$dttrow++;
947
+		}
948
+
949
+		$main_template_args['total_ticket_rows']     = count($existing_ticket_ids);
950
+		$main_template_args['existing_ticket_ids']   = implode(',', $existing_ticket_ids);
951
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
952
+
953
+		//sort $all_tickets by order
954
+		usort($all_tickets, function ($a, $b) {
955
+			$a_order = (int)$a->get('TKT_order');
956
+			$b_order = (int)$b->get('TKT_order');
957
+			if ($a_order == $b_order) {
958
+				return 0;
959
+			}
960
+
961
+			return ($a_order < $b_order) ? -1 : 1;
962
+		});
963
+
964
+		//k NOW we have all the data we need for setting up the dtt rows and ticket rows so we start our dtt loop again.
965
+		$dttrow = 1;
966
+		foreach ($times as $time) {
967
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row($dttrow, $time, $datetime_tickets,
968
+				$all_tickets, false, $times);
969
+			$dttrow++;
970
+		}
971
+
972
+		//then loop through all tickets for the ticket rows.
973
+		$tktrow = 1;
974
+		foreach ($all_tickets as $ticket) {
975
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row($tktrow, $ticket, $ticket_datetimes, $times,
976
+				false, $all_tickets);
977
+			$tktrow++;
978
+		}
979
+
980
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($times, $all_tickets);
981
+		$template                                  = PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php';
982
+		EEH_Template::display_template($template, $main_template_args);
983
+
984
+		return;
985
+	}
986
+
987
+
988
+	protected function _get_datetime_row(
989
+		$dttrow,
990
+		EE_Datetime $dtt,
991
+		$datetime_tickets,
992
+		$all_tickets,
993
+		$default = false,
994
+		$all_dtts = array()
995
+	) {
996
+
997
+		$dtt_display_template_args = array(
998
+			'dtt_edit_row'             => $this->_get_dtt_edit_row($dttrow, $dtt, $default, $all_dtts),
999
+			'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row($dttrow, $dtt, $datetime_tickets,
1000
+				$all_tickets, $default),
1001
+			'dtt_row'                  => $default ? 'DTTNUM' : $dttrow
1002
+		);
1003
+		$template                  = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php';
1004
+
1005
+		return EEH_Template::display_template($template, $dtt_display_template_args, true);
1006
+	}
1007
+
1008
+
1009
+	/**
1010
+	 * This method is used to generate a dtt fields  edit row.
1011
+	 * The same row is used to generate a row with valid DTT objects and the default row that is used as the
1012
+	 * skeleton by the js.
1013
+	 *
1014
+	 * @param int           $dttrow                         The row number for the row being generated.
1015
+	 * @param               mixed                           EE_Datetime|null $dtt      If not default row being
1016
+	 *                                                                       generated, this must be a EE_Datetime
1017
+	 *                                                                       object.
1018
+	 * @param bool          $default                        Whether a default row is being generated or not.
1019
+	 * @param EE_Datetime[] $all_dtts                       This is the array of all datetimes used in the editor.
1020
+	 *
1021
+	 * @return string Generated edit row.
1022
+	 */
1023
+	protected function _get_dtt_edit_row($dttrow, $dtt, $default, $all_dtts)
1024
+	{
1025
+
1026
+		// if the incoming $dtt object is NOT an instance of EE_Datetime then force default to true.
1027
+		$default = ! $dtt instanceof EE_Datetime ? true : false;
1028
+
1029
+		$template_args = array(
1030
+			'dtt_row'              => $default ? 'DTTNUM' : $dttrow,
1031
+			'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1032
+			'edit_dtt_expanded'    => '',
1033
+			//$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? '' : ' ee-edit-editing',
1034
+			'DTT_ID'               => $default ? '' : $dtt->ID(),
1035
+			'DTT_name'             => $default ? '' : $dtt->name(),
1036
+			'DTT_description'      => $default ? '' : $dtt->description(),
1037
+			'DTT_EVT_start'        => $default ? '' : $dtt->start_date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1038
+			'DTT_EVT_end'          => $default ? '' : $dtt->end_date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1039
+			'DTT_reg_limit'        => $default ? '' : $dtt->get_pretty('DTT_reg_limit', 'input'),
1040
+			'DTT_order'            => $default ? 'DTTNUM' : $dttrow,
1041
+			'dtt_sold'             => $default ? '0' : $dtt->get('DTT_sold'),
1042
+			'dtt_reserved'         => $default ? '0' : $dtt->reserved(),
1043
+			'clone_icon'           => ! empty($dtt) && $dtt->get('DTT_sold') > 0 ? '' : 'clone-icon ee-icon ee-icon-clone clickable',
1044
+			'trash_icon'           => ! empty($dtt) && $dtt->get('DTT_sold') > 0 ? 'ee-lock-icon' : 'trash-icon dashicons dashicons-post-trash clickable',
1045
+			'reg_list_url'         => $default || ! $dtt->event() instanceof \EE_Event
1046
+				? ''
1047
+				: EE_Admin_Page::add_query_args_and_nonce(
1048
+					array('event_id' => $dtt->event()->ID(), 'datetime_id' => $dtt->ID()),
1049
+					REG_ADMIN_URL
1050
+				)
1051
+		);
1052
+
1053
+		$template_args['show_trash'] = count($all_dtts) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon' ? ' style="display:none"' : '';
1054
+
1055
+		//allow filtering of template args at this point.
1056
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1057
+			$template_args, $dttrow, $dtt, $default, $all_dtts, $this->_is_creating_event);
1058
+
1059
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php';
1060
+
1061
+		return EEH_Template::display_template($template, $template_args, true);
1062
+	}
1063
+
1064
+
1065
+	protected function _get_dtt_attached_tickets_row($dttrow, $dtt, $datetime_tickets, $all_tickets, $default)
1066
+	{
1067
+
1068
+		$template_args = array(
1069
+			'dtt_row'                           => $default ? 'DTTNUM' : $dttrow,
1070
+			'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1071
+			'DTT_description'                   => $default ? '' : $dtt->description(),
1072
+			'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1073
+			'show_tickets_row'                  => ' style="display:none;"',
1074
+			//$default || $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' style="display:none;"' : '',
1075
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link('add_new_ticket_via_datetime',
1076
+				$this->_adminpage_obj->page_slug, $this->_adminpage_obj->get_req_action(), false, false),
1077
+			//todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1078
+			'DTT_ID'                            => $default ? '' : $dtt->ID()
1079
+		);
1080
+
1081
+		//need to setup the list items (but only if this isnt' a default skeleton setup)
1082
+		if ( ! $default) {
1083
+			$tktrow = 1;
1084
+			foreach ($all_tickets as $ticket) {
1085
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item($dttrow, $tktrow,
1086
+					$dtt, $ticket, $datetime_tickets, $default);
1087
+				$tktrow++;
1088
+			}
1089
+		}
1090
+
1091
+		//filter template args at this point
1092
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1093
+			$template_args, $dttrow, $dtt, $datetime_tickets, $all_tickets, $default, $this->_is_creating_event);
1094
+
1095
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php';
1096
+
1097
+		return EEH_Template::display_template($template, $template_args, true);
1098
+	}
1099
+
1100
+
1101
+	protected function _get_datetime_tickets_list_item($dttrow, $tktrow, $dtt, $ticket, $datetime_tickets, $default)
1102
+	{
1103
+		$tktid    = ! empty($ticket) ? $ticket->ID() : 0;
1104
+		$dtt_tkts = $dtt instanceof EE_Datetime && isset($datetime_tickets[$dtt->ID()]) ? $datetime_tickets[$dtt->ID()] : array();
1105
+
1106
+		$displayrow    = ! empty($ticket) ? $ticket->get('TKT_row') : 0;
1107
+		$template_args = array(
1108
+			'dtt_row'                 => $default ? 'DTTNUM' : $dttrow,
1109
+			'tkt_row'                 => $default && empty($ticket) ? 'TICKETNUM' : $tktrow,
1110
+			'datetime_ticket_checked' => in_array($displayrow, $dtt_tkts) ? ' checked="checked"' : '',
1111
+			'ticket_selected'         => in_array($displayrow, $dtt_tkts) ? ' ticket-selected' : '',
1112
+			'TKT_name'                => $default && empty($ticket) ? 'TKTNAME' : $ticket->get('TKT_name'),
1113
+			'tkt_status_class'        => ($default && empty($ticket)) || $this->_is_creating_event ? ' tkt-status-' . EE_Ticket::onsale : ' tkt-status-' . $ticket->ticket_status(),
1114
+		);
1115
+
1116
+		//filter template args
1117
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1118
+			$template_args, $dttrow, $tktrow, $dtt, $ticket, $datetime_tickets, $default, $this->_is_creating_event);
1119
+
1120
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php';
1121
+
1122
+		return EEH_Template::display_template($template, $template_args, true);
1123
+	}
1124
+
1125
+
1126
+	/**
1127
+	 * This generates the ticket row for tickets.
1128
+	 * This same method is used to generate both the actual rows and the js skeleton row (when default ==
1129
+	 * true)
1130
+	 *
1131
+	 * @param int           $tktrow                          Represents the row number being generated.
1132
+	 * @param               mixed                            null|EE_Ticket $ticket           If default then this will
1133
+	 *                                                                      be null.
1134
+	 * @param EE_Datetime[] $ticket_datetimes                Either an array of all datetimes on all tickets indexed by
1135
+	 *                                                       each ticket or empty for  default
1136
+	 * @param EE_Datetime[] $all_dtts                        All Datetimes on the event or empty for default.
1137
+	 * @param bool          $default                         Whether default row being generated or not.
1138
+	 * @param EE_Ticket[]   $all_tickets                     This is an array of all tickets attached to the event (or
1139
+	 *                                                       empty in the case of defaults)
1140
+	 *
1141
+	 * @return [type] [description]
1142
+	 */
1143
+	protected function _get_ticket_row(
1144
+		$tktrow,
1145
+		$ticket,
1146
+		$ticket_datetimes,
1147
+		$all_dtts,
1148
+		$default = false,
1149
+		$all_tickets = array()
1150
+	) {
1151
+
1152
+		//if $ticket is not an instance of EE_Ticket then force default to true.
1153
+		$default = ! $ticket instanceof EE_Ticket ? true : false;
1154
+
1155
+		$prices = ! empty($ticket) && ! $default ? $ticket->get_many_related('Price',
1156
+			array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))) : array();
1157
+
1158
+		//if there is only one price (which would be the base price) or NO prices and this ticket is a default ticket, let's just make sure there are no cached default prices on
1159
+		//the object.  This is done by not including any query_params.
1160
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1161
+			$prices = $ticket->get_many_related('Price');
1162
+		}
1163
+
1164
+		// check if we're dealing with a default ticket in which case we don't want any starting_ticket_datetime_row values set (otherwise there won't be any new relationships created for tickets based off of the default ticket).  This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1165
+		$default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->get('TKT_is_default')) ? true : false;
1166
+
1167
+		$tkt_dtts = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()]) ? $ticket_datetimes[$ticket->ID()] : array();
1168
+
1169
+		$ticket_subtotal  = $default ? 0 : $ticket->get_ticket_subtotal();
1170
+		$base_price       = $default ? null : $ticket->base_price();
1171
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1172
+
1173
+		//breaking out complicated condition for ticket_status
1174
+		if ($default) {
1175
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1176
+		} else {
1177
+			$ticket_status_class = $ticket->is_default() ? ' tkt-status-' . EE_Ticket::onsale : ' tkt-status-' . $ticket->ticket_status();
1178
+		}
1179
+
1180
+		//breaking out complicated condition for TKT_taxable
1181
+		if ($default) {
1182
+			$TKT_taxable = '';
1183
+		} else {
1184
+			$TKT_taxable = $ticket->get('TKT_taxable') ? ' checked="checked"' : '';
1185
+		}
1186
+
1187
+
1188
+		$template_args = array(
1189
+			'tkt_row'                       => $default ? 'TICKETNUM' : $tktrow,
1190
+			'TKT_order'                     => $default ? 'TICKETNUM' : $tktrow,
1191
+			//on initial page load this will always be the correct order.
1192
+			'tkt_status_class'              => $ticket_status_class,
1193
+			'display_edit_tkt_row'          => ' style="display:none;"',
1194
+			'edit_tkt_expanded'             => '',
1195
+			'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1196
+			'TKT_name'                      => $default ? '' : $ticket->get('TKT_name'),
1197
+			'TKT_start_date'                => $default ? '' : $ticket->get_date('TKT_start_date',
1198
+				$this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1199
+			'TKT_end_date'                  => $default ? '' : $ticket->get_date('TKT_end_date',
1200
+				$this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']),
1201
+			'TKT_status'                    => $default ? EEH_Template::pretty_status(EE_Ticket::onsale, false,
1202
+				'sentence') : $ticket->is_default() ? EEH_Template::pretty_status(EE_Ticket::onsale, false,
1203
+				'sentence') : $ticket->ticket_status(true),
1204
+			'TKT_price'                     => $default ? '' : EEH_Template::format_currency($ticket->get_ticket_total_with_taxes(),
1205
+				false, false),
1206
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1207
+			'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1208
+			'TKT_qty'                       => $default ? '' : $ticket->get_pretty('TKT_qty', 'symbol'),
1209
+			'TKT_qty_for_input'             => $default ? '' : $ticket->get_pretty('TKT_qty', 'input'),
1210
+			'TKT_uses'                      => $default ? '' : $ticket->get_pretty('TKT_uses', 'input'),
1211
+			'TKT_min'                       => $default ? '' : ($ticket->get('TKT_min') === -1 || $ticket->get('TKT_min') === 0 ? '' : $ticket->get('TKT_min')),
1212
+			'TKT_max'                       => $default ? '' : $ticket->get_pretty('TKT_max', 'input'),
1213
+			'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1214
+			'TKT_reserved'                      => $default ? 0 : $ticket->reserved(),
1215
+			'TKT_registrations'             => $default ? 0 : $ticket->count_registrations(array(
1216
+				array(
1217
+					'STS_ID' => array(
1218
+						'!=',
1219
+						EEM_Registration::status_id_incomplete
1220
+					)
1221
+				)
1222
+			)),
1223
+			'TKT_ID'                        => $default ? 0 : $ticket->get('TKT_ID'),
1224
+			'TKT_description'               => $default ? '' : $ticket->get('TKT_description'),
1225
+			'TKT_is_default'                => $default ? 0 : $ticket->get('TKT_is_default'),
1226
+			'TKT_required'                  => $default ? 0 : $ticket->required(),
1227
+			'TKT_is_default_selector'       => '',
1228
+			'ticket_price_rows'             => '',
1229
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price ? '' : $base_price->get_pretty('PRC_amount',
1230
+				'localized_float'),
1231
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1232
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0) ? '' : ' style="display:none;"',
1233
+			'show_price_mod_button'         => count($prices) > 1 || ($default && $count_price_mods > 0) || ( ! $default && $ticket->get('TKT_deleted')) ? ' style="display:none;"' : '',
1234
+			'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1235
+			'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1236
+			'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_dtts),
1237
+			'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_dtts),
1238
+			'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1239
+			'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1240
+			'TKT_taxable'                   => $TKT_taxable,
1241
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->get('TKT_taxable') ? '' : ' style="display:none"',
1242
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1243
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency($ticket_subtotal, false, false),
1244
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1245
+			'tax_rows'                      => $this->_get_tax_rows($tktrow, $ticket),
1246
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? true : false,
1247
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? ' ticket-archived' : '',
1248
+			'trash_icon'                    => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? 'ee-lock-icon ' : 'trash-icon dashicons dashicons-post-trash clickable',
1249
+			'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->get('TKT_deleted') ? '' : 'clone-icon ee-icon ee-icon-clone clickable'
1250
+		);
1251
+
1252
+		$template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] != 'ee-lock-icon' ? ' style="display:none"' : '';
1253
+
1254
+		//handle rows that should NOT be empty
1255
+		if (empty($template_args['TKT_start_date'])) {
1256
+			//if empty then the start date will be now.
1257
+			$template_args['TKT_start_date']   = date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'],
1258
+				current_time('timestamp'));
1259
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1260
+		}
1261
+
1262
+		if (empty($template_args['TKT_end_date'])) {
1263
+
1264
+			//get the earliest datetime (if present);
1265
+			$earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related('Datetime',
1266
+				array('order_by' => array('DTT_EVT_start' => 'ASC'))) : null;
1267
+
1268
+			if ( ! empty($earliest_dtt)) {
1269
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start',
1270
+					$this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
1271
+			} else {
1272
+				//default so let's just use what's been set for the default date-time which is 30 days from now.
1273
+				$template_args['TKT_end_date'] = date($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'],
1274
+					mktime(24, 0, 0, date("m"), date("d") + 29, date("Y")));
1275
+			}
1276
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1277
+		}
1278
+
1279
+		//generate ticket_datetime items
1280
+		if ( ! $default) {
1281
+			$dttrow = 1;
1282
+			foreach ($all_dtts as $dtt) {
1283
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item($dttrow, $tktrow, $dtt,
1284
+					$ticket, $ticket_datetimes, $default);
1285
+				$dttrow++;
1286
+			}
1287
+		}
1288
+
1289
+		$prcrow = 1;
1290
+		foreach ($prices as $price) {
1291
+			if ($price->is_base_price()) {
1292
+				$prcrow++;
1293
+				continue;
1294
+			}
1295
+			$show_trash  = (count($prices) > 1 && $prcrow === 1) || count($prices) === 1 ? false : true;
1296
+			$show_create = count($prices) > 1 && count($prices) !== $prcrow ? false : true;
1297
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row($tktrow, $prcrow, $price, $default,
1298
+				$ticket, $show_trash, $show_create);
1299
+			$prcrow++;
1300
+		}
1301
+
1302
+		//filter $template_args
1303
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1304
+			$template_args, $tktrow, $ticket, $ticket_datetimes, $all_dtts, $default, $all_tickets,
1305
+			$this->_is_creating_event);
1306
+
1307
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php';
1308
+
1309
+		return EEH_Template::display_template($template, $template_args, true);
1310
+	}
1311
+
1312
+
1313
+	protected function _get_tax_rows($tktrow, $ticket)
1314
+	{
1315
+		$tax_rows      = '';
1316
+		$template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php';
1317
+		$template_args = array();
1318
+		$taxes         = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1319
+		foreach ($taxes as $tax) {
1320
+			$tax_added     = $this->_get_tax_added($tax, $ticket);
1321
+			$template_args = array(
1322
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable') ? '' : ' style="display:none;"',
1323
+				'tax_id'            => $tax->ID(),
1324
+				'tkt_row'           => $tktrow,
1325
+				'tax_label'         => $tax->get('PRC_name'),
1326
+				'tax_added'         => $tax_added,
1327
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1328
+				'tax_amount'        => $tax->get('PRC_amount')
1329
+			);
1330
+			$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1331
+				$template_args, $tktrow, $ticket, $this->_is_creating_event);
1332
+			$tax_rows .= EEH_Template::display_template($template, $template_args, true);
1333
+		}
1334
+
1335
+
1336
+		return $tax_rows;
1337
+	}
1338
+
1339
+
1340
+	protected function _get_tax_added(EE_Price $tax, $ticket)
1341
+	{
1342
+		$subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1343
+
1344
+		return $subtotal * $tax->get('PRC_amount') / 100;
1345
+	}
1346
+
1347
+
1348
+	protected function _get_ticket_price_row(
1349
+		$tktrow,
1350
+		$prcrow,
1351
+		$price,
1352
+		$default,
1353
+		$ticket,
1354
+		$show_trash = true,
1355
+		$show_create = true
1356
+	) {
1357
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted') ? true : false;
1358
+		$template_args = array(
1359
+			'tkt_row'               => $default && empty($ticket) ? 'TICKETNUM' : $tktrow,
1360
+			'PRC_order'             => $default && empty($price) ? 'PRICENUM' : $prcrow,
1361
+			'edit_prices_name'      => $default && empty($price) ? 'PRICENAMEATTR' : 'edit_prices',
1362
+			'price_type_selector'   => $default && empty($price) ? $this->_get_base_price_template($tktrow, $prcrow,
1363
+				$price, $default) : $this->_get_price_type_selector($tktrow, $prcrow, $price, $default, $send_disabled),
1364
+			'PRC_ID'                => $default && empty($price) ? 0 : $price->ID(),
1365
+			'PRC_is_default'        => $default && empty($price) ? 0 : $price->get('PRC_is_default'),
1366
+			'PRC_name'              => $default && empty($price) ? '' : $price->get('PRC_name'),
1367
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1368
+			'show_plus_or_minus'    => $default && empty($price) ? '' : ' style="display:none;"',
1369
+			'show_plus'             => $default && empty($price) ? ' style="display:none;"' : ($price->is_discount() || $price->is_base_price() ? ' style="display:none;"' : ''),
1370
+			'show_minus'            => $default && empty($price) ? ' style="display:none;"' : ($price->is_discount() ? '' : ' style="display:none;"'),
1371
+			'show_currency_symbol'  => $default && empty($price) ? ' style="display:none"' : ($price->is_percent() ? ' style="display:none"' : ''),
1372
+			'PRC_amount'            => $default && empty($price) ? 0 : $price->get_pretty('PRC_amount',
1373
+				'localized_float'),
1374
+			'show_percentage'       => $default && empty($price) ? ' style="display:none;"' : ($price->is_percent() ? '' : ' style="display:none;"'),
1375
+			'show_trash_icon'       => $show_trash ? '' : ' style="display:none;"',
1376
+			'show_create_button'    => $show_create ? '' : ' style="display:none;"',
1377
+			'PRC_desc'              => $default && empty($price) ? '' : $price->get('PRC_desc'),
1378
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted') ? true : false
1379
+		);
1380
+
1381
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1382
+			$template_args, $tktrow, $prcrow, $price, $default, $ticket, $show_trash, $show_create,
1383
+			$this->_is_creating_event);
1384
+
1385
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php';
1386
+
1387
+		return EEH_Template::display_template($template, $template_args, true);
1388
+	}
1389
+
1390
+
1391
+	protected function _get_price_type_selector($tktrow, $prcrow, $price, $default, $disabled = false)
1392
+	{
1393
+		if ($price->is_base_price()) {
1394
+			return $this->_get_base_price_template($tktrow, $prcrow, $price, $default);
1395
+		} else {
1396
+			return $this->_get_price_modifier_template($tktrow, $prcrow, $price, $default, $disabled);
1397
+		}
1398
+
1399
+	}
1400
+
1401
+
1402
+	protected function _get_base_price_template($tktrow, $prcrow, $price, $default)
1403
+	{
1404
+		$template_args = array(
1405
+			'tkt_row'                   => $default ? 'TICKETNUM' : $tktrow,
1406
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $prcrow,
1407
+			'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1408
+			'PRT_name'                  => __('Price', 'event_espresso'),
1409
+			'price_selected_operator'   => '+',
1410
+			'price_selected_is_percent' => 0
1411
+		);
1412
+		$template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php';
1413
+
1414
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1415
+			$template_args, $tktrow, $prcrow, $price, $default, $this->_is_creating_event);
1416
+
1417
+		return EEH_Template::display_template($template, $template_args, true);
1418
+	}
1419
+
1420
+
1421
+	protected function _get_price_modifier_template($tktrow, $prcrow, $price, $default, $disabled = false)
1422
+	{
1423
+		$select_name                = $default && empty($price) ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]' : 'edit_prices[' . $tktrow . '][' . $prcrow . '][PRT_ID]';
1424
+		$price_types                = EE_Registry::instance()->load_model('Price_Type')->get_all(array(
1425
+			array(
1426
+				'OR' => array(
1427
+					'PBT_ID'  => '2',
1428
+					'PBT_ID*' => '3'
1429
+				)
1430
+			)
1431
+		));
1432
+		$price_option_span_template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php';
1433
+		$all_price_types            = $default && empty($price) ? array(
1434
+			array(
1435
+				'id'   => 0,
1436
+				'text' => __('Select Modifier', 'event_espresso')
1437
+			)
1438
+		) : array();
1439
+		$selected_price_type_id     = $default && empty($price) ? 0 : $price->type();
1440
+		$price_option_spans         = '';
1441
+		//setup pricetypes for selector
1442
+		foreach ($price_types as $price_type) {
1443
+			$all_price_types[] = array(
1444
+				'id'   => $price_type->ID(),
1445
+				'text' => $price_type->get('PRT_name'),
1446
+			);
1447
+
1448
+			//while we're in the loop let's setup the option spans used by js
1449
+			$spanargs = array(
1450
+				'PRT_ID'         => $price_type->ID(),
1451
+				'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1452
+				'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0
1453
+			);
1454
+			$price_option_spans .= EEH_Template::display_template($price_option_span_template, $spanargs, true);
1455
+		}
1456
+
1457
+		$select_params = $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"';
1458
+		$main_name     = $select_name;
1459
+		$select_name   = $disabled ? 'archive_price[' . $tktrow . '][' . $prcrow . '][PRT_ID]' : $main_name;
1460
+
1461
+		$template_args = array(
1462
+			'tkt_row'                   => $default ? 'TICKETNUM' : $tktrow,
1463
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $prcrow,
1464
+			'price_modifier_selector'   => EEH_Form_Fields::select_input($select_name, $all_price_types,
1465
+				$selected_price_type_id, $select_params, 'edit-price-PRT_ID'),
1466
+			'main_name'                 => $main_name,
1467
+			'selected_price_type_id'    => $selected_price_type_id,
1468
+			'price_option_spans'        => $price_option_spans,
1469
+			'price_selected_operator'   => $default && empty($price) ? '' : ($price->is_discount() ? '-' : '+'),
1470
+			'price_selected_is_percent' => $default && empty($price) ? '' : ($price->is_percent() ? 1 : 0),
1471
+			'disabled'                  => $disabled
1472
+		);
1473
+
1474
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1475
+			$template_args, $tktrow, $prcrow, $price, $default, $disabled, $this->_is_creating_event);
1476
+
1477
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php';
1478
+
1479
+		return EEH_Template::display_template($template, $template_args, true);
1480
+	}
1481
+
1482
+
1483
+	protected function _get_ticket_datetime_list_item($dttrow, $tktrow, $dtt, $ticket, $ticket_datetimes, $default)
1484
+	{
1485
+		$tkt_dtts      = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()]) ? $ticket_datetimes[$ticket->ID()] : array();
1486
+		$template_args = array(
1487
+			'dtt_row'                  => $default && ! $dtt instanceof EE_Datetime ? 'DTTNUM' : $dttrow,
1488
+			'tkt_row'                  => $default ? 'TICKETNUM' : $tktrow,
1489
+			'ticket_datetime_selected' => in_array($dttrow, $tkt_dtts) ? ' ticket-selected' : '',
1490
+			'ticket_datetime_checked'  => in_array($dttrow, $tkt_dtts) ? ' checked="checked"' : '',
1491
+			'DTT_name'                 => $default && empty($dtt) ? 'DTTNAME' : $dtt->get_dtt_display_name(true),
1492
+			'tkt_status_class'         => '',
1493
+		);
1494
+
1495
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
1496
+			$template_args, $dttrow, $tktrow, $dtt, $ticket, $ticket_datetimes, $default, $this->_is_creating_event);
1497
+		$template      = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php';
1498
+
1499
+		return EEH_Template::display_template($template, $template_args, true);
1500
+	}
1501
+
1502
+
1503
+	protected function _get_ticket_js_structure($all_dtts, $all_tickets)
1504
+	{
1505
+		$template_args = array(
1506
+			'default_datetime_edit_row'                => $this->_get_dtt_edit_row('DTTNUM', null, true, $all_dtts),
1507
+			'default_ticket_row'                       => $this->_get_ticket_row('TICKETNUM', null, array(), array(),
1508
+				true),
1509
+			'default_price_row'                        => $this->_get_ticket_price_row('TICKETNUM', 'PRICENUM', null,
1510
+				true, null),
1511
+			'default_price_rows'                       => '',
1512
+			'default_base_price_amount'                => 0,
1513
+			'default_base_price_name'                  => '',
1514
+			'default_base_price_description'           => '',
1515
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template('TICKETNUM', 'PRICENUM',
1516
+				null, true),
1517
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row('DTTNUM', null, array(),
1518
+				array(), true),
1519
+			'existing_available_datetime_tickets_list' => '',
1520
+			'existing_available_ticket_datetimes_list' => '',
1521
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item('DTTNUM', 'TICKETNUM',
1522
+				null, null, array(), true),
1523
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item('DTTNUM', 'TICKETNUM',
1524
+				null, null, array(), true)
1525
+		);
1526
+
1527
+		$tktrow = 1;
1528
+		foreach ($all_tickets as $ticket) {
1529
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item('DTTNUM',
1530
+				$tktrow, null, $ticket, array(), true);
1531
+			$tktrow++;
1532
+		}
1533
+
1534
+
1535
+		$dttrow = 1;
1536
+		foreach ($all_dtts as $dtt) {
1537
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item($dttrow,
1538
+				'TICKETNUM', $dtt, null, array(), true);
1539
+			$dttrow++;
1540
+		}
1541
+
1542
+		$default_prices = EE_Registry::instance()->load_model('Price')->get_all_default_prices();
1543
+		$prcrow         = 1;
1544
+		foreach ($default_prices as $price) {
1545
+			if ($price->is_base_price()) {
1546
+				$template_args['default_base_price_amount']      = $price->get_pretty('PRC_amount', 'localized_float');
1547
+				$template_args['default_base_price_name']        = $price->get('PRC_name');
1548
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
1549
+				$prcrow++;
1550
+				continue;
1551
+			}
1552
+			$show_trash  = (count($default_prices) > 1 && $prcrow === 1) || count($default_prices) === 1 ? false : true;
1553
+			$show_create = count($default_prices) > 1 && count($default_prices) !== $prcrow ? false : true;
1554
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row('TICKETNUM', $prcrow, $price, true,
1555
+				null, $show_trash, $show_create);
1556
+			$prcrow++;
1557
+		}
1558
+
1559
+		$template_args = apply_filters('FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
1560
+			$template_args, $all_dtts, $all_tickets, $this->_is_creating_event);
1561
+
1562
+		$template = PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php';
1563
+
1564
+		return EEH_Template::display_template($template, $template_args, true);
1565
+	}
1566 1566
 
1567 1567
 
1568 1568
 } //end class espresso_events_Pricing_Hooks
Please login to merge, or discard this patch.