Completed
Branch FET/reg-form-builder/main (3adc71)
by
unknown
15:54 queued 13:23
created
core/db_classes/EE_Event.class.php 2 patches
Indentation   +1437 added lines, -1437 removed lines patch added patch discarded remove patch
@@ -15,1441 +15,1441 @@
 block discarded – undo
15 15
 class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event
16 16
 {
17 17
 
18
-    /**
19
-     * cached value for the the logical active status for the event
20
-     *
21
-     * @see get_active_status()
22
-     * @var string
23
-     */
24
-    protected $_active_status = '';
25
-
26
-    /**
27
-     * This is just used for caching the Primary Datetime for the Event on initial retrieval
28
-     *
29
-     * @var EE_Datetime
30
-     */
31
-    protected $_Primary_Datetime;
32
-
33
-    /**
34
-     * @var EventSpacesCalculator $available_spaces_calculator
35
-     */
36
-    protected $available_spaces_calculator;
37
-
38
-
39
-    /**
40
-     * @param array  $props_n_values          incoming values
41
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
42
-     *                                        used.)
43
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
44
-     *                                        date_format and the second value is the time format
45
-     * @return EE_Event
46
-     * @throws EE_Error
47
-     */
48
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
49
-    {
50
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
51
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
52
-    }
53
-
54
-
55
-    /**
56
-     * @param array  $props_n_values  incoming values from the database
57
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
58
-     *                                the website will be used.
59
-     * @return EE_Event
60
-     * @throws EE_Error
61
-     */
62
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
63
-    {
64
-        return new self($props_n_values, true, $timezone);
65
-    }
66
-
67
-
68
-    /**
69
-     * @return EventSpacesCalculator
70
-     * @throws \EE_Error
71
-     */
72
-    public function getAvailableSpacesCalculator()
73
-    {
74
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
75
-            $this->available_spaces_calculator = new EventSpacesCalculator($this);
76
-        }
77
-        return $this->available_spaces_calculator;
78
-    }
79
-
80
-
81
-    /**
82
-     * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
83
-     *
84
-     * @param string $field_name
85
-     * @param mixed  $field_value
86
-     * @param bool   $use_default
87
-     * @throws EE_Error
88
-     */
89
-    public function set($field_name, $field_value, $use_default = false)
90
-    {
91
-        switch ($field_name) {
92
-            case 'status':
93
-                $this->set_status($field_value, $use_default);
94
-                break;
95
-            default:
96
-                parent::set($field_name, $field_value, $use_default);
97
-        }
98
-    }
99
-
100
-
101
-    /**
102
-     *    set_status
103
-     * Checks if event status is being changed to SOLD OUT
104
-     * and updates event meta data with previous event status
105
-     * so that we can revert things if/when the event is no longer sold out
106
-     *
107
-     * @access public
108
-     * @param string $new_status
109
-     * @param bool   $use_default
110
-     * @return void
111
-     * @throws EE_Error
112
-     */
113
-    public function set_status($new_status = null, $use_default = false)
114
-    {
115
-        // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
116
-        if (empty($new_status) && ! $use_default) {
117
-            return;
118
-        }
119
-        // get current Event status
120
-        $old_status = $this->status();
121
-        // if status has changed
122
-        if ($old_status !== $new_status) {
123
-            // TO sold_out
124
-            if ($new_status === EEM_Event::sold_out) {
125
-                // save the previous event status so that we can revert if the event is no longer sold out
126
-                $this->add_post_meta('_previous_event_status', $old_status);
127
-                do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
128
-            // OR FROM  sold_out
129
-            } elseif ($old_status === EEM_Event::sold_out) {
130
-                $this->delete_post_meta('_previous_event_status');
131
-                do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
132
-            }
133
-            // clear out the active status so that it gets reset the next time it is requested
134
-            $this->_active_status = null;
135
-            // update status
136
-            parent::set('status', $new_status, $use_default);
137
-            do_action('AHEE__EE_Event__set_status__after_update', $this);
138
-            return;
139
-        }
140
-        // even though the old value matches the new value, it's still good to
141
-        // allow the parent set method to have a say
142
-        parent::set('status', $new_status, $use_default);
143
-    }
144
-
145
-
146
-    /**
147
-     * Gets all the datetimes for this event
148
-     *
149
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
150
-     * @return EE_Base_Class[]|EE_Datetime[]
151
-     * @throws EE_Error
152
-     */
153
-    public function datetimes($query_params = array())
154
-    {
155
-        return $this->get_many_related('Datetime', $query_params);
156
-    }
157
-
158
-
159
-    /**
160
-     * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
161
-     *
162
-     * @return EE_Base_Class[]|EE_Datetime[]
163
-     * @throws EE_Error
164
-     */
165
-    public function datetimes_in_chronological_order()
166
-    {
167
-        return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
168
-    }
169
-
170
-
171
-    /**
172
-     * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
173
-     * @darren, we should probably UNSET timezone on the EEM_Datetime model
174
-     * after running our query, so that this timezone isn't set for EVERY query
175
-     * on EEM_Datetime for the rest of the request, no?
176
-     *
177
-     * @param boolean $show_expired whether or not to include expired events
178
-     * @param boolean $show_deleted whether or not to include deleted events
179
-     * @param null    $limit
180
-     * @return EE_Datetime[]
181
-     * @throws EE_Error
182
-     */
183
-    public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
184
-    {
185
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
186
-            $this->ID(),
187
-            $show_expired,
188
-            $show_deleted,
189
-            $limit
190
-        );
191
-    }
192
-
193
-
194
-    /**
195
-     * Returns one related datetime. Mostly only used by some legacy code.
196
-     *
197
-     * @return EE_Base_Class|EE_Datetime
198
-     * @throws EE_Error
199
-     */
200
-    public function first_datetime()
201
-    {
202
-        return $this->get_first_related('Datetime');
203
-    }
204
-
205
-
206
-    /**
207
-     * Returns the 'primary' datetime for the event
208
-     *
209
-     * @param bool $try_to_exclude_expired
210
-     * @param bool $try_to_exclude_deleted
211
-     * @return EE_Datetime
212
-     * @throws EE_Error
213
-     */
214
-    public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
215
-    {
216
-        if (! empty($this->_Primary_Datetime)) {
217
-            return $this->_Primary_Datetime;
218
-        }
219
-        $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
220
-            $this->ID(),
221
-            $try_to_exclude_expired,
222
-            $try_to_exclude_deleted
223
-        );
224
-        return $this->_Primary_Datetime;
225
-    }
226
-
227
-
228
-    /**
229
-     * Gets all the tickets available for purchase of this event
230
-     *
231
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
232
-     * @return EE_Base_Class[]|EE_Ticket[]
233
-     * @throws EE_Error
234
-     */
235
-    public function tickets($query_params = array())
236
-    {
237
-        // first get all datetimes
238
-        $datetimes = $this->datetimes_ordered();
239
-        if (! $datetimes) {
240
-            return array();
241
-        }
242
-        $datetime_ids = array();
243
-        foreach ($datetimes as $datetime) {
244
-            $datetime_ids[] = $datetime->ID();
245
-        }
246
-        $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
247
-        // if incoming $query_params has where conditions let's merge but not override existing.
248
-        if (is_array($query_params) && isset($query_params[0])) {
249
-            $where_params = array_merge($query_params[0], $where_params);
250
-            unset($query_params[0]);
251
-        }
252
-        // now add $where_params to $query_params
253
-        $query_params[0] = $where_params;
254
-        return EEM_Ticket::instance()->get_all($query_params);
255
-    }
256
-
257
-
258
-    /**
259
-     * get all unexpired untrashed tickets
260
-     *
261
-     * @return EE_Ticket[]
262
-     * @throws EE_Error
263
-     */
264
-    public function active_tickets()
265
-    {
266
-        return $this->tickets(
267
-            array(
268
-                array(
269
-                    'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
270
-                    'TKT_deleted'  => false,
271
-                ),
272
-            )
273
-        );
274
-    }
275
-
276
-
277
-    /**
278
-     * @return bool
279
-     * @throws EE_Error
280
-     */
281
-    public function additional_limit()
282
-    {
283
-        return $this->get('EVT_additional_limit');
284
-    }
285
-
286
-
287
-    /**
288
-     * @return bool
289
-     * @throws EE_Error
290
-     */
291
-    public function allow_overflow()
292
-    {
293
-        return $this->get('EVT_allow_overflow');
294
-    }
295
-
296
-
297
-    /**
298
-     * @return bool
299
-     * @throws EE_Error
300
-     */
301
-    public function created()
302
-    {
303
-        return $this->get('EVT_created');
304
-    }
305
-
306
-
307
-    /**
308
-     * @return bool
309
-     * @throws EE_Error
310
-     */
311
-    public function description()
312
-    {
313
-        return $this->get('EVT_desc');
314
-    }
315
-
316
-
317
-    /**
318
-     * Runs do_shortcode and wpautop on the description
319
-     *
320
-     * @return string of html
321
-     * @throws EE_Error
322
-     */
323
-    public function description_filtered()
324
-    {
325
-        return $this->get_pretty('EVT_desc');
326
-    }
327
-
328
-
329
-    /**
330
-     * @return bool
331
-     * @throws EE_Error
332
-     */
333
-    public function display_description()
334
-    {
335
-        return $this->get('EVT_display_desc');
336
-    }
337
-
338
-
339
-    /**
340
-     * @return bool
341
-     * @throws EE_Error
342
-     */
343
-    public function display_ticket_selector()
344
-    {
345
-        return (bool) $this->get('EVT_display_ticket_selector');
346
-    }
347
-
348
-
349
-    /**
350
-     * @return bool
351
-     * @throws EE_Error
352
-     */
353
-    public function external_url()
354
-    {
355
-        return $this->get('EVT_external_URL');
356
-    }
357
-
358
-
359
-    /**
360
-     * @return bool
361
-     * @throws EE_Error
362
-     */
363
-    public function member_only()
364
-    {
365
-        return $this->get('EVT_member_only');
366
-    }
367
-
368
-
369
-    /**
370
-     * @return bool
371
-     * @throws EE_Error
372
-     */
373
-    public function phone()
374
-    {
375
-        return $this->get('EVT_phone');
376
-    }
377
-
378
-
379
-    /**
380
-     * @return bool
381
-     * @throws EE_Error
382
-     */
383
-    public function modified()
384
-    {
385
-        return $this->get('EVT_modified');
386
-    }
387
-
388
-
389
-    /**
390
-     * @return bool
391
-     * @throws EE_Error
392
-     */
393
-    public function name()
394
-    {
395
-        return $this->get('EVT_name');
396
-    }
397
-
398
-
399
-    /**
400
-     * @return bool
401
-     * @throws EE_Error
402
-     */
403
-    public function order()
404
-    {
405
-        return $this->get('EVT_order');
406
-    }
407
-
408
-
409
-    /**
410
-     * @return bool|string
411
-     * @throws EE_Error
412
-     */
413
-    public function default_registration_status()
414
-    {
415
-        $event_default_registration_status = $this->get('EVT_default_registration_status');
416
-        return ! empty($event_default_registration_status)
417
-            ? $event_default_registration_status
418
-            : EE_Registry::instance()->CFG->registration->default_STS_ID;
419
-    }
420
-
421
-
422
-    /**
423
-     * @param int  $num_words
424
-     * @param null $more
425
-     * @param bool $not_full_desc
426
-     * @return bool|string
427
-     * @throws EE_Error
428
-     */
429
-    public function short_description($num_words = 55, $more = null, $not_full_desc = false)
430
-    {
431
-        $short_desc = $this->get('EVT_short_desc');
432
-        if (! empty($short_desc) || $not_full_desc) {
433
-            return $short_desc;
434
-        }
435
-        $full_desc = $this->get('EVT_desc');
436
-        return wp_trim_words($full_desc, $num_words, $more);
437
-    }
438
-
439
-
440
-    /**
441
-     * @return bool
442
-     * @throws EE_Error
443
-     */
444
-    public function slug()
445
-    {
446
-        return $this->get('EVT_slug');
447
-    }
448
-
449
-
450
-    /**
451
-     * @return bool
452
-     * @throws EE_Error
453
-     */
454
-    public function timezone_string()
455
-    {
456
-        return $this->get('EVT_timezone_string');
457
-    }
458
-
459
-
460
-    /**
461
-     * @return bool
462
-     * @throws EE_Error
463
-     */
464
-    public function visible_on()
465
-    {
466
-        return $this->get('EVT_visible_on');
467
-    }
468
-
469
-
470
-    /**
471
-     * @return int
472
-     * @throws EE_Error
473
-     */
474
-    public function wp_user()
475
-    {
476
-        return $this->get('EVT_wp_user');
477
-    }
478
-
479
-
480
-    /**
481
-     * @return bool
482
-     * @throws EE_Error
483
-     */
484
-    public function donations()
485
-    {
486
-        return $this->get('EVT_donations');
487
-    }
488
-
489
-
490
-    /**
491
-     * @param $limit
492
-     * @throws EE_Error
493
-     */
494
-    public function set_additional_limit($limit)
495
-    {
496
-        $this->set('EVT_additional_limit', $limit);
497
-    }
498
-
499
-
500
-    /**
501
-     * @param $created
502
-     * @throws EE_Error
503
-     */
504
-    public function set_created($created)
505
-    {
506
-        $this->set('EVT_created', $created);
507
-    }
508
-
509
-
510
-    /**
511
-     * @param $desc
512
-     * @throws EE_Error
513
-     */
514
-    public function set_description($desc)
515
-    {
516
-        $this->set('EVT_desc', $desc);
517
-    }
518
-
519
-
520
-    /**
521
-     * @param $display_desc
522
-     * @throws EE_Error
523
-     */
524
-    public function set_display_description($display_desc)
525
-    {
526
-        $this->set('EVT_display_desc', $display_desc);
527
-    }
528
-
529
-
530
-    /**
531
-     * @param $display_ticket_selector
532
-     * @throws EE_Error
533
-     */
534
-    public function set_display_ticket_selector($display_ticket_selector)
535
-    {
536
-        $this->set('EVT_display_ticket_selector', $display_ticket_selector);
537
-    }
538
-
539
-
540
-    /**
541
-     * @param $external_url
542
-     * @throws EE_Error
543
-     */
544
-    public function set_external_url($external_url)
545
-    {
546
-        $this->set('EVT_external_URL', $external_url);
547
-    }
548
-
549
-
550
-    /**
551
-     * @param $member_only
552
-     * @throws EE_Error
553
-     */
554
-    public function set_member_only($member_only)
555
-    {
556
-        $this->set('EVT_member_only', $member_only);
557
-    }
558
-
559
-
560
-    /**
561
-     * @param $event_phone
562
-     * @throws EE_Error
563
-     */
564
-    public function set_event_phone($event_phone)
565
-    {
566
-        $this->set('EVT_phone', $event_phone);
567
-    }
568
-
569
-
570
-    /**
571
-     * @param $modified
572
-     * @throws EE_Error
573
-     */
574
-    public function set_modified($modified)
575
-    {
576
-        $this->set('EVT_modified', $modified);
577
-    }
578
-
579
-
580
-    /**
581
-     * @param $name
582
-     * @throws EE_Error
583
-     */
584
-    public function set_name($name)
585
-    {
586
-        $this->set('EVT_name', $name);
587
-    }
588
-
589
-
590
-    /**
591
-     * @param $order
592
-     * @throws EE_Error
593
-     */
594
-    public function set_order($order)
595
-    {
596
-        $this->set('EVT_order', $order);
597
-    }
598
-
599
-
600
-    /**
601
-     * @param $short_desc
602
-     * @throws EE_Error
603
-     */
604
-    public function set_short_description($short_desc)
605
-    {
606
-        $this->set('EVT_short_desc', $short_desc);
607
-    }
608
-
609
-
610
-    /**
611
-     * @param $slug
612
-     * @throws EE_Error
613
-     */
614
-    public function set_slug($slug)
615
-    {
616
-        $this->set('EVT_slug', $slug);
617
-    }
618
-
619
-
620
-    /**
621
-     * @param $timezone_string
622
-     * @throws EE_Error
623
-     */
624
-    public function set_timezone_string($timezone_string)
625
-    {
626
-        $this->set('EVT_timezone_string', $timezone_string);
627
-    }
628
-
629
-
630
-    /**
631
-     * @param $visible_on
632
-     * @throws EE_Error
633
-     */
634
-    public function set_visible_on($visible_on)
635
-    {
636
-        $this->set('EVT_visible_on', $visible_on);
637
-    }
638
-
639
-
640
-    /**
641
-     * @param $wp_user
642
-     * @throws EE_Error
643
-     */
644
-    public function set_wp_user($wp_user)
645
-    {
646
-        $this->set('EVT_wp_user', $wp_user);
647
-    }
648
-
649
-
650
-    /**
651
-     * @param $default_registration_status
652
-     * @throws EE_Error
653
-     */
654
-    public function set_default_registration_status($default_registration_status)
655
-    {
656
-        $this->set('EVT_default_registration_status', $default_registration_status);
657
-    }
658
-
659
-
660
-    /**
661
-     * @param $donations
662
-     * @throws EE_Error
663
-     */
664
-    public function set_donations($donations)
665
-    {
666
-        $this->set('EVT_donations', $donations);
667
-    }
668
-
669
-
670
-    /**
671
-     * Adds a venue to this event
672
-     *
673
-     * @param EE_Venue /int $venue_id_or_obj
674
-     * @return EE_Base_Class|EE_Venue
675
-     * @throws EE_Error
676
-     */
677
-    public function add_venue($venue_id_or_obj)
678
-    {
679
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
680
-    }
681
-
682
-
683
-    /**
684
-     * Removes a venue from the event
685
-     *
686
-     * @param EE_Venue /int $venue_id_or_obj
687
-     * @return EE_Base_Class|EE_Venue
688
-     * @throws EE_Error
689
-     */
690
-    public function remove_venue($venue_id_or_obj)
691
-    {
692
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
693
-    }
694
-
695
-
696
-    /**
697
-     * Gets all the venues related ot the event. May provide additional $query_params if desired
698
-     *
699
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
700
-     * @return EE_Base_Class[]|EE_Venue[]
701
-     * @throws EE_Error
702
-     */
703
-    public function venues($query_params = array())
704
-    {
705
-        return $this->get_many_related('Venue', $query_params);
706
-    }
707
-
708
-
709
-    /**
710
-     * check if event id is present and if event is published
711
-     *
712
-     * @access public
713
-     * @return boolean true yes, false no
714
-     * @throws EE_Error
715
-     */
716
-    private function _has_ID_and_is_published()
717
-    {
718
-        // first check if event id is present and not NULL,
719
-        // then check if this event is published (or any of the equivalent "published" statuses)
720
-        return
721
-            $this->ID() && $this->ID() !== null
722
-            && (
723
-                $this->status() === 'publish'
724
-                || $this->status() === EEM_Event::sold_out
725
-                || $this->status() === EEM_Event::postponed
726
-                || $this->status() === EEM_Event::cancelled
727
-            );
728
-    }
729
-
730
-
731
-    /**
732
-     * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
733
-     *
734
-     * @access public
735
-     * @return boolean true yes, false no
736
-     * @throws EE_Error
737
-     */
738
-    public function is_upcoming()
739
-    {
740
-        // check if event id is present and if this event is published
741
-        if ($this->is_inactive()) {
742
-            return false;
743
-        }
744
-        // set initial value
745
-        $upcoming = false;
746
-        // next let's get all datetimes and loop through them
747
-        $datetimes = $this->datetimes_in_chronological_order();
748
-        foreach ($datetimes as $datetime) {
749
-            if ($datetime instanceof EE_Datetime) {
750
-                // if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
751
-                if ($datetime->is_expired()) {
752
-                    continue;
753
-                }
754
-                // if this dtt is active then we return false.
755
-                if ($datetime->is_active()) {
756
-                    return false;
757
-                }
758
-                // otherwise let's check upcoming status
759
-                $upcoming = $datetime->is_upcoming();
760
-            }
761
-        }
762
-        return $upcoming;
763
-    }
764
-
765
-
766
-    /**
767
-     * @return bool
768
-     * @throws EE_Error
769
-     */
770
-    public function is_active()
771
-    {
772
-        // check if event id is present and if this event is published
773
-        if ($this->is_inactive()) {
774
-            return false;
775
-        }
776
-        // set initial value
777
-        $active = false;
778
-        // next let's get all datetimes and loop through them
779
-        $datetimes = $this->datetimes_in_chronological_order();
780
-        foreach ($datetimes as $datetime) {
781
-            if ($datetime instanceof EE_Datetime) {
782
-                // if this dtt is expired then we continue cause one of the other datetimes might be active.
783
-                if ($datetime->is_expired()) {
784
-                    continue;
785
-                }
786
-                // if this dtt is upcoming then we return false.
787
-                if ($datetime->is_upcoming()) {
788
-                    return false;
789
-                }
790
-                // otherwise let's check active status
791
-                $active = $datetime->is_active();
792
-            }
793
-        }
794
-        return $active;
795
-    }
796
-
797
-
798
-    /**
799
-     * @return bool
800
-     * @throws EE_Error
801
-     */
802
-    public function is_expired()
803
-    {
804
-        // check if event id is present and if this event is published
805
-        if ($this->is_inactive()) {
806
-            return false;
807
-        }
808
-        // set initial value
809
-        $expired = false;
810
-        // first let's get all datetimes and loop through them
811
-        $datetimes = $this->datetimes_in_chronological_order();
812
-        foreach ($datetimes as $datetime) {
813
-            if ($datetime instanceof EE_Datetime) {
814
-                // if this dtt is upcoming or active then we return false.
815
-                if ($datetime->is_upcoming() || $datetime->is_active()) {
816
-                    return false;
817
-                }
818
-                // otherwise let's check active status
819
-                $expired = $datetime->is_expired();
820
-            }
821
-        }
822
-        return $expired;
823
-    }
824
-
825
-
826
-    /**
827
-     * @return bool
828
-     * @throws EE_Error
829
-     */
830
-    public function is_inactive()
831
-    {
832
-        // check if event id is present and if this event is published
833
-        if ($this->_has_ID_and_is_published()) {
834
-            return false;
835
-        }
836
-        return true;
837
-    }
838
-
839
-
840
-    /**
841
-     * calculate spaces remaining based on "saleable" tickets
842
-     *
843
-     * @param array $tickets
844
-     * @param bool  $filtered
845
-     * @return int|float
846
-     * @throws EE_Error
847
-     * @throws DomainException
848
-     * @throws UnexpectedEntityException
849
-     */
850
-    public function spaces_remaining($tickets = array(), $filtered = true)
851
-    {
852
-        $this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
853
-        $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
854
-        return $filtered
855
-            ? apply_filters(
856
-                'FHEE_EE_Event__spaces_remaining',
857
-                $spaces_remaining,
858
-                $this,
859
-                $tickets
860
-            )
861
-            : $spaces_remaining;
862
-    }
863
-
864
-
865
-    /**
866
-     *    perform_sold_out_status_check
867
-     *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
868
-     *    available... if NOT, then the event status will get toggled to 'sold_out'
869
-     *
870
-     * @return bool    return the ACTUAL sold out state.
871
-     * @throws EE_Error
872
-     * @throws DomainException
873
-     * @throws UnexpectedEntityException
874
-     */
875
-    public function perform_sold_out_status_check()
876
-    {
877
-        // get all tickets
878
-        $tickets = $this->tickets(
879
-            array(
880
-                'default_where_conditions' => 'none',
881
-                'order_by' => array('TKT_qty' => 'ASC'),
882
-            )
883
-        );
884
-        $all_expired = true;
885
-        foreach ($tickets as $ticket) {
886
-            if (! $ticket->is_expired()) {
887
-                $all_expired = false;
888
-                break;
889
-            }
890
-        }
891
-        // if all the tickets are just expired, then don't update the event status to sold out
892
-        if ($all_expired) {
893
-            return true;
894
-        }
895
-        $spaces_remaining = $this->spaces_remaining($tickets);
896
-        if ($spaces_remaining < 1) {
897
-            if ($this->status() !== EEM_Event::post_status_private) {
898
-                $this->set_status(EEM_Event::sold_out);
899
-                $this->save();
900
-            }
901
-            $sold_out = true;
902
-        } else {
903
-            $sold_out = false;
904
-            // was event previously marked as sold out ?
905
-            if ($this->status() === EEM_Event::sold_out) {
906
-                // revert status to previous value, if it was set
907
-                $previous_event_status = $this->get_post_meta('_previous_event_status', true);
908
-                if ($previous_event_status) {
909
-                    $this->set_status($previous_event_status);
910
-                    $this->save();
911
-                }
912
-            }
913
-        }
914
-        do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
915
-        return $sold_out;
916
-    }
917
-
918
-
919
-    /**
920
-     * This returns the total remaining spaces for sale on this event.
921
-     *
922
-     * @uses EE_Event::total_available_spaces()
923
-     * @return float|int
924
-     * @throws EE_Error
925
-     * @throws DomainException
926
-     * @throws UnexpectedEntityException
927
-     */
928
-    public function spaces_remaining_for_sale()
929
-    {
930
-        return $this->total_available_spaces(true);
931
-    }
932
-
933
-
934
-    /**
935
-     * This returns the total spaces available for an event
936
-     * while considering all the qtys on the tickets and the reg limits
937
-     * on the datetimes attached to this event.
938
-     *
939
-     * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
940
-     *                              If this is false, then we return the most tickets that could ever be sold
941
-     *                              for this event with the datetime and tickets setup on the event under optimal
942
-     *                              selling conditions.  Otherwise we return a live calculation of spaces available
943
-     *                              based on tickets sold.  Depending on setup and stage of sales, this
944
-     *                              may appear to equal remaining tickets.  However, the more tickets are
945
-     *                              sold out, the more accurate the "live" total is.
946
-     * @return float|int
947
-     * @throws EE_Error
948
-     * @throws DomainException
949
-     * @throws UnexpectedEntityException
950
-     */
951
-    public function total_available_spaces($consider_sold = false)
952
-    {
953
-        $spaces_available = $consider_sold
954
-            ? $this->getAvailableSpacesCalculator()->spacesRemaining()
955
-            : $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
956
-        return apply_filters(
957
-            'FHEE_EE_Event__total_available_spaces__spaces_available',
958
-            $spaces_available,
959
-            $this,
960
-            $this->getAvailableSpacesCalculator()->getDatetimes(),
961
-            $this->getAvailableSpacesCalculator()->getActiveTickets()
962
-        );
963
-    }
964
-
965
-
966
-    /**
967
-     * Checks if the event is set to sold out
968
-     *
969
-     * @param  bool $actual whether or not to perform calculations to not only figure the
970
-     *                      actual status but also to flip the status if necessary to sold
971
-     *                      out If false, we just check the existing status of the event
972
-     * @return boolean
973
-     * @throws EE_Error
974
-     */
975
-    public function is_sold_out($actual = false)
976
-    {
977
-        if (! $actual) {
978
-            return $this->status() === EEM_Event::sold_out;
979
-        }
980
-        return $this->perform_sold_out_status_check();
981
-    }
982
-
983
-
984
-    /**
985
-     * Checks if the event is marked as postponed
986
-     *
987
-     * @return boolean
988
-     */
989
-    public function is_postponed()
990
-    {
991
-        return $this->status() === EEM_Event::postponed;
992
-    }
993
-
994
-
995
-    /**
996
-     * Checks if the event is marked as cancelled
997
-     *
998
-     * @return boolean
999
-     */
1000
-    public function is_cancelled()
1001
-    {
1002
-        return $this->status() === EEM_Event::cancelled;
1003
-    }
1004
-
1005
-
1006
-    /**
1007
-     * Get the logical active status in a hierarchical order for all the datetimes.  Note
1008
-     * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1009
-     * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1010
-     * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1011
-     * the event is considered expired.
1012
-     * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1013
-     * status set on the EVENT when it is not published and thus is done
1014
-     *
1015
-     * @param bool $reset
1016
-     * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1017
-     * @throws EE_Error
1018
-     */
1019
-    public function get_active_status($reset = false)
1020
-    {
1021
-        // if the active status has already been set, then just use that value (unless we are resetting it)
1022
-        if (! empty($this->_active_status) && ! $reset) {
1023
-            return $this->_active_status;
1024
-        }
1025
-        // first check if event id is present on this object
1026
-        if (! $this->ID()) {
1027
-            return false;
1028
-        }
1029
-        $where_params_for_event = array(array('EVT_ID' => $this->ID()));
1030
-        // if event is published:
1031
-        if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1032
-            // active?
1033
-            if (
1034
-                EEM_Datetime::instance()->get_datetime_count_for_status(
1035
-                    EE_Datetime::active,
1036
-                    $where_params_for_event
1037
-                ) > 0
1038
-            ) {
1039
-                $this->_active_status = EE_Datetime::active;
1040
-            } else {
1041
-                // upcoming?
1042
-                if (
1043
-                    EEM_Datetime::instance()->get_datetime_count_for_status(
1044
-                        EE_Datetime::upcoming,
1045
-                        $where_params_for_event
1046
-                    ) > 0
1047
-                ) {
1048
-                    $this->_active_status = EE_Datetime::upcoming;
1049
-                } else {
1050
-                    // expired?
1051
-                    if (
1052
-                        EEM_Datetime::instance()->get_datetime_count_for_status(
1053
-                            EE_Datetime::expired,
1054
-                            $where_params_for_event
1055
-                        ) > 0
1056
-                    ) {
1057
-                        $this->_active_status = EE_Datetime::expired;
1058
-                    } else {
1059
-                        // it would be odd if things make it this far because it basically means there are no datetime's
1060
-                        // attached to the event.  So in this case it will just be considered inactive.
1061
-                        $this->_active_status = EE_Datetime::inactive;
1062
-                    }
1063
-                }
1064
-            }
1065
-        } else {
1066
-            // the event is not published, so let's just set it's active status according to its' post status
1067
-            switch ($this->status()) {
1068
-                case EEM_Event::sold_out:
1069
-                    $this->_active_status = EE_Datetime::sold_out;
1070
-                    break;
1071
-                case EEM_Event::cancelled:
1072
-                    $this->_active_status = EE_Datetime::cancelled;
1073
-                    break;
1074
-                case EEM_Event::postponed:
1075
-                    $this->_active_status = EE_Datetime::postponed;
1076
-                    break;
1077
-                default:
1078
-                    $this->_active_status = EE_Datetime::inactive;
1079
-            }
1080
-        }
1081
-        return $this->_active_status;
1082
-    }
1083
-
1084
-
1085
-    /**
1086
-     *    pretty_active_status
1087
-     *
1088
-     * @access public
1089
-     * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1090
-     * @return mixed void|string
1091
-     * @throws EE_Error
1092
-     */
1093
-    public function pretty_active_status($echo = true)
1094
-    {
1095
-        $active_status = $this->get_active_status();
1096
-        $status = '<span class="ee-status event-active-status-'
1097
-                  . $active_status
1098
-                  . '">'
1099
-                  . EEH_Template::pretty_status($active_status, false, 'sentence')
1100
-                  . '</span>';
1101
-        if ($echo) {
1102
-            echo $status;
1103
-            return '';
1104
-        }
1105
-        return $status;
1106
-    }
1107
-
1108
-
1109
-    /**
1110
-     * @return bool|int
1111
-     * @throws EE_Error
1112
-     */
1113
-    public function get_number_of_tickets_sold()
1114
-    {
1115
-        $tkt_sold = 0;
1116
-        if (! $this->ID()) {
1117
-            return 0;
1118
-        }
1119
-        $datetimes = $this->datetimes();
1120
-        foreach ($datetimes as $datetime) {
1121
-            if ($datetime instanceof EE_Datetime) {
1122
-                $tkt_sold += $datetime->sold();
1123
-            }
1124
-        }
1125
-        return $tkt_sold;
1126
-    }
1127
-
1128
-
1129
-    /**
1130
-     * This just returns a count of all the registrations for this event
1131
-     *
1132
-     * @access  public
1133
-     * @return int
1134
-     * @throws EE_Error
1135
-     */
1136
-    public function get_count_of_all_registrations()
1137
-    {
1138
-        return EEM_Event::instance()->count_related($this, 'Registration');
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * This returns the ticket with the earliest start time that is
1144
-     * available for this event (across all datetimes attached to the event)
1145
-     *
1146
-     * @return EE_Base_Class|EE_Ticket|null
1147
-     * @throws EE_Error
1148
-     */
1149
-    public function get_ticket_with_earliest_start_time()
1150
-    {
1151
-        $where['Datetime.EVT_ID'] = $this->ID();
1152
-        $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1153
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1154
-    }
1155
-
1156
-
1157
-    /**
1158
-     * This returns the ticket with the latest end time that is available
1159
-     * for this event (across all datetimes attached to the event)
1160
-     *
1161
-     * @return EE_Base_Class|EE_Ticket|null
1162
-     * @throws EE_Error
1163
-     */
1164
-    public function get_ticket_with_latest_end_time()
1165
-    {
1166
-        $where['Datetime.EVT_ID'] = $this->ID();
1167
-        $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1168
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1169
-    }
1170
-
1171
-
1172
-    /**
1173
-     * This returns the number of different ticket types currently on sale for this event.
1174
-     *
1175
-     * @return int
1176
-     * @throws EE_Error
1177
-     */
1178
-    public function countTicketsOnSale()
1179
-    {
1180
-        $where = array(
1181
-            'Datetime.EVT_ID' => $this->ID(),
1182
-            'TKT_start_date'  => array('<', time()),
1183
-            'TKT_end_date'    => array('>', time()),
1184
-        );
1185
-        return EEM_Ticket::instance()->count(array($where));
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * This returns whether there are any tickets on sale for this event.
1191
-     *
1192
-     * @return bool true = YES tickets on sale.
1193
-     * @throws EE_Error
1194
-     */
1195
-    public function tickets_on_sale()
1196
-    {
1197
-        return $this->countTicketsOnSale() > 0;
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     * Gets the URL for viewing this event on the front-end. Overrides parent
1203
-     * to check for an external URL first
1204
-     *
1205
-     * @return string
1206
-     * @throws EE_Error
1207
-     */
1208
-    public function get_permalink()
1209
-    {
1210
-        if ($this->external_url()) {
1211
-            return $this->external_url();
1212
-        }
1213
-        return parent::get_permalink();
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * Gets the first term for 'espresso_event_categories' we can find
1219
-     *
1220
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1221
-     * @return EE_Base_Class|EE_Term|null
1222
-     * @throws EE_Error
1223
-     */
1224
-    public function first_event_category($query_params = array())
1225
-    {
1226
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1227
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1228
-        return EEM_Term::instance()->get_one($query_params);
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * Gets all terms for 'espresso_event_categories' we can find
1234
-     *
1235
-     * @param array $query_params
1236
-     * @return EE_Base_Class[]|EE_Term[]
1237
-     * @throws EE_Error
1238
-     */
1239
-    public function get_all_event_categories($query_params = array())
1240
-    {
1241
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1242
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1243
-        return EEM_Term::instance()->get_all($query_params);
1244
-    }
1245
-
1246
-
1247
-    /**
1248
-     * Adds a question group to this event
1249
-     *
1250
-     * @param EE_Question_Group|int $question_group_id_or_obj
1251
-     * @param bool $for_primary if true, the question group will be added for the primary
1252
-     *                                           registrant, if false will be added for others. default: false
1253
-     * @return EE_Base_Class|EE_Question_Group
1254
-     * @throws EE_Error
1255
-     * @throws InvalidArgumentException
1256
-     * @throws InvalidDataTypeException
1257
-     * @throws InvalidInterfaceException
1258
-     * @throws ReflectionException
1259
-     */
1260
-    public function add_question_group($question_group_id_or_obj, $for_primary = false)
1261
-    {
1262
-        // If the row already exists, it will be updated. If it doesn't, it will be inserted.
1263
-        // That's in EE_HABTM_Relation::add_relation_to().
1264
-        return $this->_add_relation_to(
1265
-            $question_group_id_or_obj,
1266
-            'Question_Group',
1267
-            [
1268
-                EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1269
-            ]
1270
-        );
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * Removes a question group from the event
1276
-     *
1277
-     * @param EE_Question_Group|int $question_group_id_or_obj
1278
-     * @param bool $for_primary if true, the question group will be removed from the primary
1279
-     *                                           registrant, if false will be removed from others. default: false
1280
-     * @return EE_Base_Class|EE_Question_Group
1281
-     * @throws EE_Error
1282
-     * @throws InvalidArgumentException
1283
-     * @throws ReflectionException
1284
-     * @throws InvalidDataTypeException
1285
-     * @throws InvalidInterfaceException
1286
-     */
1287
-    public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1288
-    {
1289
-        // If the question group is used for the other type (primary or additional)
1290
-        // then just update it. If not, delete it outright.
1291
-        $existing_relation = $this->get_first_related(
1292
-            'Event_Question_Group',
1293
-            [
1294
-                [
1295
-                    'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1296
-                ]
1297
-            ]
1298
-        );
1299
-        $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1300
-        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1301
-        if ($existing_relation->get($other_field) === false) {
1302
-            // Delete it. It's now no longer for primary or additional question groups.
1303
-            return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1304
-        }
1305
-        // Just update it. They'll still use this question group for the other category
1306
-        $existing_relation->save(
1307
-            [
1308
-                $field_to_update => false
1309
-            ]
1310
-        );
1311
-    }
1312
-
1313
-
1314
-    /**
1315
-     * Gets all the question groups, ordering them by QSG_order ascending
1316
-     *
1317
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1318
-     * @return EE_Base_Class[]|EE_Question_Group[]
1319
-     * @throws EE_Error
1320
-     */
1321
-    public function question_groups($query_params = array())
1322
-    {
1323
-        $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1324
-        return $this->get_many_related('Question_Group', $query_params);
1325
-    }
1326
-
1327
-
1328
-    /**
1329
-     * Implementation for EEI_Has_Icon interface method.
1330
-     *
1331
-     * @see EEI_Visual_Representation for comments
1332
-     * @return string
1333
-     */
1334
-    public function get_icon()
1335
-    {
1336
-        return '<span class="dashicons dashicons-flag"></span>';
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * Implementation for EEI_Admin_Links interface method.
1342
-     *
1343
-     * @see EEI_Admin_Links for comments
1344
-     * @return string
1345
-     * @throws EE_Error
1346
-     */
1347
-    public function get_admin_details_link()
1348
-    {
1349
-        return $this->get_admin_edit_link();
1350
-    }
1351
-
1352
-
1353
-    /**
1354
-     * Implementation for EEI_Admin_Links interface method.
1355
-     *
1356
-     * @see EEI_Admin_Links for comments
1357
-     * @return string
1358
-     * @throws EE_Error
1359
-     */
1360
-    public function get_admin_edit_link()
1361
-    {
1362
-        return EEH_URL::add_query_args_and_nonce(
1363
-            array(
1364
-                'page'   => 'espresso_events',
1365
-                'action' => 'edit',
1366
-                'post'   => $this->ID(),
1367
-            ),
1368
-            admin_url('admin.php')
1369
-        );
1370
-    }
1371
-
1372
-
1373
-    /**
1374
-     * Implementation for EEI_Admin_Links interface method.
1375
-     *
1376
-     * @see EEI_Admin_Links for comments
1377
-     * @return string
1378
-     */
1379
-    public function get_admin_settings_link()
1380
-    {
1381
-        return EEH_URL::add_query_args_and_nonce(
1382
-            array(
1383
-                'page'   => 'espresso_events',
1384
-                'action' => 'default_event_settings',
1385
-            ),
1386
-            admin_url('admin.php')
1387
-        );
1388
-    }
1389
-
1390
-
1391
-    /**
1392
-     * Implementation for EEI_Admin_Links interface method.
1393
-     *
1394
-     * @see EEI_Admin_Links for comments
1395
-     * @return string
1396
-     */
1397
-    public function get_admin_overview_link()
1398
-    {
1399
-        return EEH_URL::add_query_args_and_nonce(
1400
-            array(
1401
-                'page'   => 'espresso_events',
1402
-                'action' => 'default',
1403
-            ),
1404
-            admin_url('admin.php')
1405
-        );
1406
-    }
1407
-
1408
-
1409
-    /**
1410
-     * @return string|null
1411
-     * @throws EE_Error
1412
-     * @throws ReflectionException
1413
-     */
1414
-    public function registrationFormUuid():? string
1415
-    {
1416
-        return $this->get('FSC_UUID');
1417
-    }
1418
-
1419
-
1420
-    /**
1421
-     * Gets all the form sections for this event
1422
-     *
1423
-     * @return EE_Base_Class[]|EE_Form_Section[]
1424
-     * @throws EE_Error
1425
-     * @throws ReflectionException
1426
-     */
1427
-    public function registrationForm()
1428
-    {
1429
-        $FSC_UUID = $this->registrationFormUuid();
1430
-        return !empty($FSC_UUID)
1431
-            ? $this->get_many_related(
1432
-                'Form_Section',
1433
-                [
1434
-                    [
1435
-                        'OR' => [
1436
-                            'Form_Section.FSC_UUID'      => $FSC_UUID, // top level form
1437
-                            'Form_Section.FSC_belongsTo' => $FSC_UUID, // child form sections
1438
-                        ]
1439
-                    ],
1440
-                    'order_by' => ['FSC_order' => 'ASC'],
1441
-                ]
1442
-            )
1443
-            : [];
1444
-    }
1445
-
1446
-
1447
-    /**
1448
-     * @param string $UUID
1449
-     * @throws EE_Error
1450
-     */
1451
-    public function setRegistrationFormUuid(string $UUID): void
1452
-    {
1453
-        $this->set('FSC_UUID', $UUID);
1454
-    }
18
+	/**
19
+	 * cached value for the the logical active status for the event
20
+	 *
21
+	 * @see get_active_status()
22
+	 * @var string
23
+	 */
24
+	protected $_active_status = '';
25
+
26
+	/**
27
+	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
28
+	 *
29
+	 * @var EE_Datetime
30
+	 */
31
+	protected $_Primary_Datetime;
32
+
33
+	/**
34
+	 * @var EventSpacesCalculator $available_spaces_calculator
35
+	 */
36
+	protected $available_spaces_calculator;
37
+
38
+
39
+	/**
40
+	 * @param array  $props_n_values          incoming values
41
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
42
+	 *                                        used.)
43
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
44
+	 *                                        date_format and the second value is the time format
45
+	 * @return EE_Event
46
+	 * @throws EE_Error
47
+	 */
48
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
49
+	{
50
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
51
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
52
+	}
53
+
54
+
55
+	/**
56
+	 * @param array  $props_n_values  incoming values from the database
57
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
58
+	 *                                the website will be used.
59
+	 * @return EE_Event
60
+	 * @throws EE_Error
61
+	 */
62
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
63
+	{
64
+		return new self($props_n_values, true, $timezone);
65
+	}
66
+
67
+
68
+	/**
69
+	 * @return EventSpacesCalculator
70
+	 * @throws \EE_Error
71
+	 */
72
+	public function getAvailableSpacesCalculator()
73
+	{
74
+		if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
75
+			$this->available_spaces_calculator = new EventSpacesCalculator($this);
76
+		}
77
+		return $this->available_spaces_calculator;
78
+	}
79
+
80
+
81
+	/**
82
+	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
83
+	 *
84
+	 * @param string $field_name
85
+	 * @param mixed  $field_value
86
+	 * @param bool   $use_default
87
+	 * @throws EE_Error
88
+	 */
89
+	public function set($field_name, $field_value, $use_default = false)
90
+	{
91
+		switch ($field_name) {
92
+			case 'status':
93
+				$this->set_status($field_value, $use_default);
94
+				break;
95
+			default:
96
+				parent::set($field_name, $field_value, $use_default);
97
+		}
98
+	}
99
+
100
+
101
+	/**
102
+	 *    set_status
103
+	 * Checks if event status is being changed to SOLD OUT
104
+	 * and updates event meta data with previous event status
105
+	 * so that we can revert things if/when the event is no longer sold out
106
+	 *
107
+	 * @access public
108
+	 * @param string $new_status
109
+	 * @param bool   $use_default
110
+	 * @return void
111
+	 * @throws EE_Error
112
+	 */
113
+	public function set_status($new_status = null, $use_default = false)
114
+	{
115
+		// if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
116
+		if (empty($new_status) && ! $use_default) {
117
+			return;
118
+		}
119
+		// get current Event status
120
+		$old_status = $this->status();
121
+		// if status has changed
122
+		if ($old_status !== $new_status) {
123
+			// TO sold_out
124
+			if ($new_status === EEM_Event::sold_out) {
125
+				// save the previous event status so that we can revert if the event is no longer sold out
126
+				$this->add_post_meta('_previous_event_status', $old_status);
127
+				do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
128
+			// OR FROM  sold_out
129
+			} elseif ($old_status === EEM_Event::sold_out) {
130
+				$this->delete_post_meta('_previous_event_status');
131
+				do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
132
+			}
133
+			// clear out the active status so that it gets reset the next time it is requested
134
+			$this->_active_status = null;
135
+			// update status
136
+			parent::set('status', $new_status, $use_default);
137
+			do_action('AHEE__EE_Event__set_status__after_update', $this);
138
+			return;
139
+		}
140
+		// even though the old value matches the new value, it's still good to
141
+		// allow the parent set method to have a say
142
+		parent::set('status', $new_status, $use_default);
143
+	}
144
+
145
+
146
+	/**
147
+	 * Gets all the datetimes for this event
148
+	 *
149
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
150
+	 * @return EE_Base_Class[]|EE_Datetime[]
151
+	 * @throws EE_Error
152
+	 */
153
+	public function datetimes($query_params = array())
154
+	{
155
+		return $this->get_many_related('Datetime', $query_params);
156
+	}
157
+
158
+
159
+	/**
160
+	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
161
+	 *
162
+	 * @return EE_Base_Class[]|EE_Datetime[]
163
+	 * @throws EE_Error
164
+	 */
165
+	public function datetimes_in_chronological_order()
166
+	{
167
+		return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
168
+	}
169
+
170
+
171
+	/**
172
+	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
173
+	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
174
+	 * after running our query, so that this timezone isn't set for EVERY query
175
+	 * on EEM_Datetime for the rest of the request, no?
176
+	 *
177
+	 * @param boolean $show_expired whether or not to include expired events
178
+	 * @param boolean $show_deleted whether or not to include deleted events
179
+	 * @param null    $limit
180
+	 * @return EE_Datetime[]
181
+	 * @throws EE_Error
182
+	 */
183
+	public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
184
+	{
185
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
186
+			$this->ID(),
187
+			$show_expired,
188
+			$show_deleted,
189
+			$limit
190
+		);
191
+	}
192
+
193
+
194
+	/**
195
+	 * Returns one related datetime. Mostly only used by some legacy code.
196
+	 *
197
+	 * @return EE_Base_Class|EE_Datetime
198
+	 * @throws EE_Error
199
+	 */
200
+	public function first_datetime()
201
+	{
202
+		return $this->get_first_related('Datetime');
203
+	}
204
+
205
+
206
+	/**
207
+	 * Returns the 'primary' datetime for the event
208
+	 *
209
+	 * @param bool $try_to_exclude_expired
210
+	 * @param bool $try_to_exclude_deleted
211
+	 * @return EE_Datetime
212
+	 * @throws EE_Error
213
+	 */
214
+	public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
215
+	{
216
+		if (! empty($this->_Primary_Datetime)) {
217
+			return $this->_Primary_Datetime;
218
+		}
219
+		$this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
220
+			$this->ID(),
221
+			$try_to_exclude_expired,
222
+			$try_to_exclude_deleted
223
+		);
224
+		return $this->_Primary_Datetime;
225
+	}
226
+
227
+
228
+	/**
229
+	 * Gets all the tickets available for purchase of this event
230
+	 *
231
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
232
+	 * @return EE_Base_Class[]|EE_Ticket[]
233
+	 * @throws EE_Error
234
+	 */
235
+	public function tickets($query_params = array())
236
+	{
237
+		// first get all datetimes
238
+		$datetimes = $this->datetimes_ordered();
239
+		if (! $datetimes) {
240
+			return array();
241
+		}
242
+		$datetime_ids = array();
243
+		foreach ($datetimes as $datetime) {
244
+			$datetime_ids[] = $datetime->ID();
245
+		}
246
+		$where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
247
+		// if incoming $query_params has where conditions let's merge but not override existing.
248
+		if (is_array($query_params) && isset($query_params[0])) {
249
+			$where_params = array_merge($query_params[0], $where_params);
250
+			unset($query_params[0]);
251
+		}
252
+		// now add $where_params to $query_params
253
+		$query_params[0] = $where_params;
254
+		return EEM_Ticket::instance()->get_all($query_params);
255
+	}
256
+
257
+
258
+	/**
259
+	 * get all unexpired untrashed tickets
260
+	 *
261
+	 * @return EE_Ticket[]
262
+	 * @throws EE_Error
263
+	 */
264
+	public function active_tickets()
265
+	{
266
+		return $this->tickets(
267
+			array(
268
+				array(
269
+					'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
270
+					'TKT_deleted'  => false,
271
+				),
272
+			)
273
+		);
274
+	}
275
+
276
+
277
+	/**
278
+	 * @return bool
279
+	 * @throws EE_Error
280
+	 */
281
+	public function additional_limit()
282
+	{
283
+		return $this->get('EVT_additional_limit');
284
+	}
285
+
286
+
287
+	/**
288
+	 * @return bool
289
+	 * @throws EE_Error
290
+	 */
291
+	public function allow_overflow()
292
+	{
293
+		return $this->get('EVT_allow_overflow');
294
+	}
295
+
296
+
297
+	/**
298
+	 * @return bool
299
+	 * @throws EE_Error
300
+	 */
301
+	public function created()
302
+	{
303
+		return $this->get('EVT_created');
304
+	}
305
+
306
+
307
+	/**
308
+	 * @return bool
309
+	 * @throws EE_Error
310
+	 */
311
+	public function description()
312
+	{
313
+		return $this->get('EVT_desc');
314
+	}
315
+
316
+
317
+	/**
318
+	 * Runs do_shortcode and wpautop on the description
319
+	 *
320
+	 * @return string of html
321
+	 * @throws EE_Error
322
+	 */
323
+	public function description_filtered()
324
+	{
325
+		return $this->get_pretty('EVT_desc');
326
+	}
327
+
328
+
329
+	/**
330
+	 * @return bool
331
+	 * @throws EE_Error
332
+	 */
333
+	public function display_description()
334
+	{
335
+		return $this->get('EVT_display_desc');
336
+	}
337
+
338
+
339
+	/**
340
+	 * @return bool
341
+	 * @throws EE_Error
342
+	 */
343
+	public function display_ticket_selector()
344
+	{
345
+		return (bool) $this->get('EVT_display_ticket_selector');
346
+	}
347
+
348
+
349
+	/**
350
+	 * @return bool
351
+	 * @throws EE_Error
352
+	 */
353
+	public function external_url()
354
+	{
355
+		return $this->get('EVT_external_URL');
356
+	}
357
+
358
+
359
+	/**
360
+	 * @return bool
361
+	 * @throws EE_Error
362
+	 */
363
+	public function member_only()
364
+	{
365
+		return $this->get('EVT_member_only');
366
+	}
367
+
368
+
369
+	/**
370
+	 * @return bool
371
+	 * @throws EE_Error
372
+	 */
373
+	public function phone()
374
+	{
375
+		return $this->get('EVT_phone');
376
+	}
377
+
378
+
379
+	/**
380
+	 * @return bool
381
+	 * @throws EE_Error
382
+	 */
383
+	public function modified()
384
+	{
385
+		return $this->get('EVT_modified');
386
+	}
387
+
388
+
389
+	/**
390
+	 * @return bool
391
+	 * @throws EE_Error
392
+	 */
393
+	public function name()
394
+	{
395
+		return $this->get('EVT_name');
396
+	}
397
+
398
+
399
+	/**
400
+	 * @return bool
401
+	 * @throws EE_Error
402
+	 */
403
+	public function order()
404
+	{
405
+		return $this->get('EVT_order');
406
+	}
407
+
408
+
409
+	/**
410
+	 * @return bool|string
411
+	 * @throws EE_Error
412
+	 */
413
+	public function default_registration_status()
414
+	{
415
+		$event_default_registration_status = $this->get('EVT_default_registration_status');
416
+		return ! empty($event_default_registration_status)
417
+			? $event_default_registration_status
418
+			: EE_Registry::instance()->CFG->registration->default_STS_ID;
419
+	}
420
+
421
+
422
+	/**
423
+	 * @param int  $num_words
424
+	 * @param null $more
425
+	 * @param bool $not_full_desc
426
+	 * @return bool|string
427
+	 * @throws EE_Error
428
+	 */
429
+	public function short_description($num_words = 55, $more = null, $not_full_desc = false)
430
+	{
431
+		$short_desc = $this->get('EVT_short_desc');
432
+		if (! empty($short_desc) || $not_full_desc) {
433
+			return $short_desc;
434
+		}
435
+		$full_desc = $this->get('EVT_desc');
436
+		return wp_trim_words($full_desc, $num_words, $more);
437
+	}
438
+
439
+
440
+	/**
441
+	 * @return bool
442
+	 * @throws EE_Error
443
+	 */
444
+	public function slug()
445
+	{
446
+		return $this->get('EVT_slug');
447
+	}
448
+
449
+
450
+	/**
451
+	 * @return bool
452
+	 * @throws EE_Error
453
+	 */
454
+	public function timezone_string()
455
+	{
456
+		return $this->get('EVT_timezone_string');
457
+	}
458
+
459
+
460
+	/**
461
+	 * @return bool
462
+	 * @throws EE_Error
463
+	 */
464
+	public function visible_on()
465
+	{
466
+		return $this->get('EVT_visible_on');
467
+	}
468
+
469
+
470
+	/**
471
+	 * @return int
472
+	 * @throws EE_Error
473
+	 */
474
+	public function wp_user()
475
+	{
476
+		return $this->get('EVT_wp_user');
477
+	}
478
+
479
+
480
+	/**
481
+	 * @return bool
482
+	 * @throws EE_Error
483
+	 */
484
+	public function donations()
485
+	{
486
+		return $this->get('EVT_donations');
487
+	}
488
+
489
+
490
+	/**
491
+	 * @param $limit
492
+	 * @throws EE_Error
493
+	 */
494
+	public function set_additional_limit($limit)
495
+	{
496
+		$this->set('EVT_additional_limit', $limit);
497
+	}
498
+
499
+
500
+	/**
501
+	 * @param $created
502
+	 * @throws EE_Error
503
+	 */
504
+	public function set_created($created)
505
+	{
506
+		$this->set('EVT_created', $created);
507
+	}
508
+
509
+
510
+	/**
511
+	 * @param $desc
512
+	 * @throws EE_Error
513
+	 */
514
+	public function set_description($desc)
515
+	{
516
+		$this->set('EVT_desc', $desc);
517
+	}
518
+
519
+
520
+	/**
521
+	 * @param $display_desc
522
+	 * @throws EE_Error
523
+	 */
524
+	public function set_display_description($display_desc)
525
+	{
526
+		$this->set('EVT_display_desc', $display_desc);
527
+	}
528
+
529
+
530
+	/**
531
+	 * @param $display_ticket_selector
532
+	 * @throws EE_Error
533
+	 */
534
+	public function set_display_ticket_selector($display_ticket_selector)
535
+	{
536
+		$this->set('EVT_display_ticket_selector', $display_ticket_selector);
537
+	}
538
+
539
+
540
+	/**
541
+	 * @param $external_url
542
+	 * @throws EE_Error
543
+	 */
544
+	public function set_external_url($external_url)
545
+	{
546
+		$this->set('EVT_external_URL', $external_url);
547
+	}
548
+
549
+
550
+	/**
551
+	 * @param $member_only
552
+	 * @throws EE_Error
553
+	 */
554
+	public function set_member_only($member_only)
555
+	{
556
+		$this->set('EVT_member_only', $member_only);
557
+	}
558
+
559
+
560
+	/**
561
+	 * @param $event_phone
562
+	 * @throws EE_Error
563
+	 */
564
+	public function set_event_phone($event_phone)
565
+	{
566
+		$this->set('EVT_phone', $event_phone);
567
+	}
568
+
569
+
570
+	/**
571
+	 * @param $modified
572
+	 * @throws EE_Error
573
+	 */
574
+	public function set_modified($modified)
575
+	{
576
+		$this->set('EVT_modified', $modified);
577
+	}
578
+
579
+
580
+	/**
581
+	 * @param $name
582
+	 * @throws EE_Error
583
+	 */
584
+	public function set_name($name)
585
+	{
586
+		$this->set('EVT_name', $name);
587
+	}
588
+
589
+
590
+	/**
591
+	 * @param $order
592
+	 * @throws EE_Error
593
+	 */
594
+	public function set_order($order)
595
+	{
596
+		$this->set('EVT_order', $order);
597
+	}
598
+
599
+
600
+	/**
601
+	 * @param $short_desc
602
+	 * @throws EE_Error
603
+	 */
604
+	public function set_short_description($short_desc)
605
+	{
606
+		$this->set('EVT_short_desc', $short_desc);
607
+	}
608
+
609
+
610
+	/**
611
+	 * @param $slug
612
+	 * @throws EE_Error
613
+	 */
614
+	public function set_slug($slug)
615
+	{
616
+		$this->set('EVT_slug', $slug);
617
+	}
618
+
619
+
620
+	/**
621
+	 * @param $timezone_string
622
+	 * @throws EE_Error
623
+	 */
624
+	public function set_timezone_string($timezone_string)
625
+	{
626
+		$this->set('EVT_timezone_string', $timezone_string);
627
+	}
628
+
629
+
630
+	/**
631
+	 * @param $visible_on
632
+	 * @throws EE_Error
633
+	 */
634
+	public function set_visible_on($visible_on)
635
+	{
636
+		$this->set('EVT_visible_on', $visible_on);
637
+	}
638
+
639
+
640
+	/**
641
+	 * @param $wp_user
642
+	 * @throws EE_Error
643
+	 */
644
+	public function set_wp_user($wp_user)
645
+	{
646
+		$this->set('EVT_wp_user', $wp_user);
647
+	}
648
+
649
+
650
+	/**
651
+	 * @param $default_registration_status
652
+	 * @throws EE_Error
653
+	 */
654
+	public function set_default_registration_status($default_registration_status)
655
+	{
656
+		$this->set('EVT_default_registration_status', $default_registration_status);
657
+	}
658
+
659
+
660
+	/**
661
+	 * @param $donations
662
+	 * @throws EE_Error
663
+	 */
664
+	public function set_donations($donations)
665
+	{
666
+		$this->set('EVT_donations', $donations);
667
+	}
668
+
669
+
670
+	/**
671
+	 * Adds a venue to this event
672
+	 *
673
+	 * @param EE_Venue /int $venue_id_or_obj
674
+	 * @return EE_Base_Class|EE_Venue
675
+	 * @throws EE_Error
676
+	 */
677
+	public function add_venue($venue_id_or_obj)
678
+	{
679
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
680
+	}
681
+
682
+
683
+	/**
684
+	 * Removes a venue from the event
685
+	 *
686
+	 * @param EE_Venue /int $venue_id_or_obj
687
+	 * @return EE_Base_Class|EE_Venue
688
+	 * @throws EE_Error
689
+	 */
690
+	public function remove_venue($venue_id_or_obj)
691
+	{
692
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
693
+	}
694
+
695
+
696
+	/**
697
+	 * Gets all the venues related ot the event. May provide additional $query_params if desired
698
+	 *
699
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
700
+	 * @return EE_Base_Class[]|EE_Venue[]
701
+	 * @throws EE_Error
702
+	 */
703
+	public function venues($query_params = array())
704
+	{
705
+		return $this->get_many_related('Venue', $query_params);
706
+	}
707
+
708
+
709
+	/**
710
+	 * check if event id is present and if event is published
711
+	 *
712
+	 * @access public
713
+	 * @return boolean true yes, false no
714
+	 * @throws EE_Error
715
+	 */
716
+	private function _has_ID_and_is_published()
717
+	{
718
+		// first check if event id is present and not NULL,
719
+		// then check if this event is published (or any of the equivalent "published" statuses)
720
+		return
721
+			$this->ID() && $this->ID() !== null
722
+			&& (
723
+				$this->status() === 'publish'
724
+				|| $this->status() === EEM_Event::sold_out
725
+				|| $this->status() === EEM_Event::postponed
726
+				|| $this->status() === EEM_Event::cancelled
727
+			);
728
+	}
729
+
730
+
731
+	/**
732
+	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
733
+	 *
734
+	 * @access public
735
+	 * @return boolean true yes, false no
736
+	 * @throws EE_Error
737
+	 */
738
+	public function is_upcoming()
739
+	{
740
+		// check if event id is present and if this event is published
741
+		if ($this->is_inactive()) {
742
+			return false;
743
+		}
744
+		// set initial value
745
+		$upcoming = false;
746
+		// next let's get all datetimes and loop through them
747
+		$datetimes = $this->datetimes_in_chronological_order();
748
+		foreach ($datetimes as $datetime) {
749
+			if ($datetime instanceof EE_Datetime) {
750
+				// if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
751
+				if ($datetime->is_expired()) {
752
+					continue;
753
+				}
754
+				// if this dtt is active then we return false.
755
+				if ($datetime->is_active()) {
756
+					return false;
757
+				}
758
+				// otherwise let's check upcoming status
759
+				$upcoming = $datetime->is_upcoming();
760
+			}
761
+		}
762
+		return $upcoming;
763
+	}
764
+
765
+
766
+	/**
767
+	 * @return bool
768
+	 * @throws EE_Error
769
+	 */
770
+	public function is_active()
771
+	{
772
+		// check if event id is present and if this event is published
773
+		if ($this->is_inactive()) {
774
+			return false;
775
+		}
776
+		// set initial value
777
+		$active = false;
778
+		// next let's get all datetimes and loop through them
779
+		$datetimes = $this->datetimes_in_chronological_order();
780
+		foreach ($datetimes as $datetime) {
781
+			if ($datetime instanceof EE_Datetime) {
782
+				// if this dtt is expired then we continue cause one of the other datetimes might be active.
783
+				if ($datetime->is_expired()) {
784
+					continue;
785
+				}
786
+				// if this dtt is upcoming then we return false.
787
+				if ($datetime->is_upcoming()) {
788
+					return false;
789
+				}
790
+				// otherwise let's check active status
791
+				$active = $datetime->is_active();
792
+			}
793
+		}
794
+		return $active;
795
+	}
796
+
797
+
798
+	/**
799
+	 * @return bool
800
+	 * @throws EE_Error
801
+	 */
802
+	public function is_expired()
803
+	{
804
+		// check if event id is present and if this event is published
805
+		if ($this->is_inactive()) {
806
+			return false;
807
+		}
808
+		// set initial value
809
+		$expired = false;
810
+		// first let's get all datetimes and loop through them
811
+		$datetimes = $this->datetimes_in_chronological_order();
812
+		foreach ($datetimes as $datetime) {
813
+			if ($datetime instanceof EE_Datetime) {
814
+				// if this dtt is upcoming or active then we return false.
815
+				if ($datetime->is_upcoming() || $datetime->is_active()) {
816
+					return false;
817
+				}
818
+				// otherwise let's check active status
819
+				$expired = $datetime->is_expired();
820
+			}
821
+		}
822
+		return $expired;
823
+	}
824
+
825
+
826
+	/**
827
+	 * @return bool
828
+	 * @throws EE_Error
829
+	 */
830
+	public function is_inactive()
831
+	{
832
+		// check if event id is present and if this event is published
833
+		if ($this->_has_ID_and_is_published()) {
834
+			return false;
835
+		}
836
+		return true;
837
+	}
838
+
839
+
840
+	/**
841
+	 * calculate spaces remaining based on "saleable" tickets
842
+	 *
843
+	 * @param array $tickets
844
+	 * @param bool  $filtered
845
+	 * @return int|float
846
+	 * @throws EE_Error
847
+	 * @throws DomainException
848
+	 * @throws UnexpectedEntityException
849
+	 */
850
+	public function spaces_remaining($tickets = array(), $filtered = true)
851
+	{
852
+		$this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
853
+		$spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
854
+		return $filtered
855
+			? apply_filters(
856
+				'FHEE_EE_Event__spaces_remaining',
857
+				$spaces_remaining,
858
+				$this,
859
+				$tickets
860
+			)
861
+			: $spaces_remaining;
862
+	}
863
+
864
+
865
+	/**
866
+	 *    perform_sold_out_status_check
867
+	 *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
868
+	 *    available... if NOT, then the event status will get toggled to 'sold_out'
869
+	 *
870
+	 * @return bool    return the ACTUAL sold out state.
871
+	 * @throws EE_Error
872
+	 * @throws DomainException
873
+	 * @throws UnexpectedEntityException
874
+	 */
875
+	public function perform_sold_out_status_check()
876
+	{
877
+		// get all tickets
878
+		$tickets = $this->tickets(
879
+			array(
880
+				'default_where_conditions' => 'none',
881
+				'order_by' => array('TKT_qty' => 'ASC'),
882
+			)
883
+		);
884
+		$all_expired = true;
885
+		foreach ($tickets as $ticket) {
886
+			if (! $ticket->is_expired()) {
887
+				$all_expired = false;
888
+				break;
889
+			}
890
+		}
891
+		// if all the tickets are just expired, then don't update the event status to sold out
892
+		if ($all_expired) {
893
+			return true;
894
+		}
895
+		$spaces_remaining = $this->spaces_remaining($tickets);
896
+		if ($spaces_remaining < 1) {
897
+			if ($this->status() !== EEM_Event::post_status_private) {
898
+				$this->set_status(EEM_Event::sold_out);
899
+				$this->save();
900
+			}
901
+			$sold_out = true;
902
+		} else {
903
+			$sold_out = false;
904
+			// was event previously marked as sold out ?
905
+			if ($this->status() === EEM_Event::sold_out) {
906
+				// revert status to previous value, if it was set
907
+				$previous_event_status = $this->get_post_meta('_previous_event_status', true);
908
+				if ($previous_event_status) {
909
+					$this->set_status($previous_event_status);
910
+					$this->save();
911
+				}
912
+			}
913
+		}
914
+		do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
915
+		return $sold_out;
916
+	}
917
+
918
+
919
+	/**
920
+	 * This returns the total remaining spaces for sale on this event.
921
+	 *
922
+	 * @uses EE_Event::total_available_spaces()
923
+	 * @return float|int
924
+	 * @throws EE_Error
925
+	 * @throws DomainException
926
+	 * @throws UnexpectedEntityException
927
+	 */
928
+	public function spaces_remaining_for_sale()
929
+	{
930
+		return $this->total_available_spaces(true);
931
+	}
932
+
933
+
934
+	/**
935
+	 * This returns the total spaces available for an event
936
+	 * while considering all the qtys on the tickets and the reg limits
937
+	 * on the datetimes attached to this event.
938
+	 *
939
+	 * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
940
+	 *                              If this is false, then we return the most tickets that could ever be sold
941
+	 *                              for this event with the datetime and tickets setup on the event under optimal
942
+	 *                              selling conditions.  Otherwise we return a live calculation of spaces available
943
+	 *                              based on tickets sold.  Depending on setup and stage of sales, this
944
+	 *                              may appear to equal remaining tickets.  However, the more tickets are
945
+	 *                              sold out, the more accurate the "live" total is.
946
+	 * @return float|int
947
+	 * @throws EE_Error
948
+	 * @throws DomainException
949
+	 * @throws UnexpectedEntityException
950
+	 */
951
+	public function total_available_spaces($consider_sold = false)
952
+	{
953
+		$spaces_available = $consider_sold
954
+			? $this->getAvailableSpacesCalculator()->spacesRemaining()
955
+			: $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
956
+		return apply_filters(
957
+			'FHEE_EE_Event__total_available_spaces__spaces_available',
958
+			$spaces_available,
959
+			$this,
960
+			$this->getAvailableSpacesCalculator()->getDatetimes(),
961
+			$this->getAvailableSpacesCalculator()->getActiveTickets()
962
+		);
963
+	}
964
+
965
+
966
+	/**
967
+	 * Checks if the event is set to sold out
968
+	 *
969
+	 * @param  bool $actual whether or not to perform calculations to not only figure the
970
+	 *                      actual status but also to flip the status if necessary to sold
971
+	 *                      out If false, we just check the existing status of the event
972
+	 * @return boolean
973
+	 * @throws EE_Error
974
+	 */
975
+	public function is_sold_out($actual = false)
976
+	{
977
+		if (! $actual) {
978
+			return $this->status() === EEM_Event::sold_out;
979
+		}
980
+		return $this->perform_sold_out_status_check();
981
+	}
982
+
983
+
984
+	/**
985
+	 * Checks if the event is marked as postponed
986
+	 *
987
+	 * @return boolean
988
+	 */
989
+	public function is_postponed()
990
+	{
991
+		return $this->status() === EEM_Event::postponed;
992
+	}
993
+
994
+
995
+	/**
996
+	 * Checks if the event is marked as cancelled
997
+	 *
998
+	 * @return boolean
999
+	 */
1000
+	public function is_cancelled()
1001
+	{
1002
+		return $this->status() === EEM_Event::cancelled;
1003
+	}
1004
+
1005
+
1006
+	/**
1007
+	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
1008
+	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1009
+	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1010
+	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1011
+	 * the event is considered expired.
1012
+	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1013
+	 * status set on the EVENT when it is not published and thus is done
1014
+	 *
1015
+	 * @param bool $reset
1016
+	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1017
+	 * @throws EE_Error
1018
+	 */
1019
+	public function get_active_status($reset = false)
1020
+	{
1021
+		// if the active status has already been set, then just use that value (unless we are resetting it)
1022
+		if (! empty($this->_active_status) && ! $reset) {
1023
+			return $this->_active_status;
1024
+		}
1025
+		// first check if event id is present on this object
1026
+		if (! $this->ID()) {
1027
+			return false;
1028
+		}
1029
+		$where_params_for_event = array(array('EVT_ID' => $this->ID()));
1030
+		// if event is published:
1031
+		if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1032
+			// active?
1033
+			if (
1034
+				EEM_Datetime::instance()->get_datetime_count_for_status(
1035
+					EE_Datetime::active,
1036
+					$where_params_for_event
1037
+				) > 0
1038
+			) {
1039
+				$this->_active_status = EE_Datetime::active;
1040
+			} else {
1041
+				// upcoming?
1042
+				if (
1043
+					EEM_Datetime::instance()->get_datetime_count_for_status(
1044
+						EE_Datetime::upcoming,
1045
+						$where_params_for_event
1046
+					) > 0
1047
+				) {
1048
+					$this->_active_status = EE_Datetime::upcoming;
1049
+				} else {
1050
+					// expired?
1051
+					if (
1052
+						EEM_Datetime::instance()->get_datetime_count_for_status(
1053
+							EE_Datetime::expired,
1054
+							$where_params_for_event
1055
+						) > 0
1056
+					) {
1057
+						$this->_active_status = EE_Datetime::expired;
1058
+					} else {
1059
+						// it would be odd if things make it this far because it basically means there are no datetime's
1060
+						// attached to the event.  So in this case it will just be considered inactive.
1061
+						$this->_active_status = EE_Datetime::inactive;
1062
+					}
1063
+				}
1064
+			}
1065
+		} else {
1066
+			// the event is not published, so let's just set it's active status according to its' post status
1067
+			switch ($this->status()) {
1068
+				case EEM_Event::sold_out:
1069
+					$this->_active_status = EE_Datetime::sold_out;
1070
+					break;
1071
+				case EEM_Event::cancelled:
1072
+					$this->_active_status = EE_Datetime::cancelled;
1073
+					break;
1074
+				case EEM_Event::postponed:
1075
+					$this->_active_status = EE_Datetime::postponed;
1076
+					break;
1077
+				default:
1078
+					$this->_active_status = EE_Datetime::inactive;
1079
+			}
1080
+		}
1081
+		return $this->_active_status;
1082
+	}
1083
+
1084
+
1085
+	/**
1086
+	 *    pretty_active_status
1087
+	 *
1088
+	 * @access public
1089
+	 * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1090
+	 * @return mixed void|string
1091
+	 * @throws EE_Error
1092
+	 */
1093
+	public function pretty_active_status($echo = true)
1094
+	{
1095
+		$active_status = $this->get_active_status();
1096
+		$status = '<span class="ee-status event-active-status-'
1097
+				  . $active_status
1098
+				  . '">'
1099
+				  . EEH_Template::pretty_status($active_status, false, 'sentence')
1100
+				  . '</span>';
1101
+		if ($echo) {
1102
+			echo $status;
1103
+			return '';
1104
+		}
1105
+		return $status;
1106
+	}
1107
+
1108
+
1109
+	/**
1110
+	 * @return bool|int
1111
+	 * @throws EE_Error
1112
+	 */
1113
+	public function get_number_of_tickets_sold()
1114
+	{
1115
+		$tkt_sold = 0;
1116
+		if (! $this->ID()) {
1117
+			return 0;
1118
+		}
1119
+		$datetimes = $this->datetimes();
1120
+		foreach ($datetimes as $datetime) {
1121
+			if ($datetime instanceof EE_Datetime) {
1122
+				$tkt_sold += $datetime->sold();
1123
+			}
1124
+		}
1125
+		return $tkt_sold;
1126
+	}
1127
+
1128
+
1129
+	/**
1130
+	 * This just returns a count of all the registrations for this event
1131
+	 *
1132
+	 * @access  public
1133
+	 * @return int
1134
+	 * @throws EE_Error
1135
+	 */
1136
+	public function get_count_of_all_registrations()
1137
+	{
1138
+		return EEM_Event::instance()->count_related($this, 'Registration');
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * This returns the ticket with the earliest start time that is
1144
+	 * available for this event (across all datetimes attached to the event)
1145
+	 *
1146
+	 * @return EE_Base_Class|EE_Ticket|null
1147
+	 * @throws EE_Error
1148
+	 */
1149
+	public function get_ticket_with_earliest_start_time()
1150
+	{
1151
+		$where['Datetime.EVT_ID'] = $this->ID();
1152
+		$query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1153
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1154
+	}
1155
+
1156
+
1157
+	/**
1158
+	 * This returns the ticket with the latest end time that is available
1159
+	 * for this event (across all datetimes attached to the event)
1160
+	 *
1161
+	 * @return EE_Base_Class|EE_Ticket|null
1162
+	 * @throws EE_Error
1163
+	 */
1164
+	public function get_ticket_with_latest_end_time()
1165
+	{
1166
+		$where['Datetime.EVT_ID'] = $this->ID();
1167
+		$query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1168
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1169
+	}
1170
+
1171
+
1172
+	/**
1173
+	 * This returns the number of different ticket types currently on sale for this event.
1174
+	 *
1175
+	 * @return int
1176
+	 * @throws EE_Error
1177
+	 */
1178
+	public function countTicketsOnSale()
1179
+	{
1180
+		$where = array(
1181
+			'Datetime.EVT_ID' => $this->ID(),
1182
+			'TKT_start_date'  => array('<', time()),
1183
+			'TKT_end_date'    => array('>', time()),
1184
+		);
1185
+		return EEM_Ticket::instance()->count(array($where));
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * This returns whether there are any tickets on sale for this event.
1191
+	 *
1192
+	 * @return bool true = YES tickets on sale.
1193
+	 * @throws EE_Error
1194
+	 */
1195
+	public function tickets_on_sale()
1196
+	{
1197
+		return $this->countTicketsOnSale() > 0;
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 * Gets the URL for viewing this event on the front-end. Overrides parent
1203
+	 * to check for an external URL first
1204
+	 *
1205
+	 * @return string
1206
+	 * @throws EE_Error
1207
+	 */
1208
+	public function get_permalink()
1209
+	{
1210
+		if ($this->external_url()) {
1211
+			return $this->external_url();
1212
+		}
1213
+		return parent::get_permalink();
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * Gets the first term for 'espresso_event_categories' we can find
1219
+	 *
1220
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1221
+	 * @return EE_Base_Class|EE_Term|null
1222
+	 * @throws EE_Error
1223
+	 */
1224
+	public function first_event_category($query_params = array())
1225
+	{
1226
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1227
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1228
+		return EEM_Term::instance()->get_one($query_params);
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * Gets all terms for 'espresso_event_categories' we can find
1234
+	 *
1235
+	 * @param array $query_params
1236
+	 * @return EE_Base_Class[]|EE_Term[]
1237
+	 * @throws EE_Error
1238
+	 */
1239
+	public function get_all_event_categories($query_params = array())
1240
+	{
1241
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1242
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1243
+		return EEM_Term::instance()->get_all($query_params);
1244
+	}
1245
+
1246
+
1247
+	/**
1248
+	 * Adds a question group to this event
1249
+	 *
1250
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1251
+	 * @param bool $for_primary if true, the question group will be added for the primary
1252
+	 *                                           registrant, if false will be added for others. default: false
1253
+	 * @return EE_Base_Class|EE_Question_Group
1254
+	 * @throws EE_Error
1255
+	 * @throws InvalidArgumentException
1256
+	 * @throws InvalidDataTypeException
1257
+	 * @throws InvalidInterfaceException
1258
+	 * @throws ReflectionException
1259
+	 */
1260
+	public function add_question_group($question_group_id_or_obj, $for_primary = false)
1261
+	{
1262
+		// If the row already exists, it will be updated. If it doesn't, it will be inserted.
1263
+		// That's in EE_HABTM_Relation::add_relation_to().
1264
+		return $this->_add_relation_to(
1265
+			$question_group_id_or_obj,
1266
+			'Question_Group',
1267
+			[
1268
+				EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1269
+			]
1270
+		);
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * Removes a question group from the event
1276
+	 *
1277
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1278
+	 * @param bool $for_primary if true, the question group will be removed from the primary
1279
+	 *                                           registrant, if false will be removed from others. default: false
1280
+	 * @return EE_Base_Class|EE_Question_Group
1281
+	 * @throws EE_Error
1282
+	 * @throws InvalidArgumentException
1283
+	 * @throws ReflectionException
1284
+	 * @throws InvalidDataTypeException
1285
+	 * @throws InvalidInterfaceException
1286
+	 */
1287
+	public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1288
+	{
1289
+		// If the question group is used for the other type (primary or additional)
1290
+		// then just update it. If not, delete it outright.
1291
+		$existing_relation = $this->get_first_related(
1292
+			'Event_Question_Group',
1293
+			[
1294
+				[
1295
+					'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1296
+				]
1297
+			]
1298
+		);
1299
+		$field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1300
+		$other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1301
+		if ($existing_relation->get($other_field) === false) {
1302
+			// Delete it. It's now no longer for primary or additional question groups.
1303
+			return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1304
+		}
1305
+		// Just update it. They'll still use this question group for the other category
1306
+		$existing_relation->save(
1307
+			[
1308
+				$field_to_update => false
1309
+			]
1310
+		);
1311
+	}
1312
+
1313
+
1314
+	/**
1315
+	 * Gets all the question groups, ordering them by QSG_order ascending
1316
+	 *
1317
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1318
+	 * @return EE_Base_Class[]|EE_Question_Group[]
1319
+	 * @throws EE_Error
1320
+	 */
1321
+	public function question_groups($query_params = array())
1322
+	{
1323
+		$query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1324
+		return $this->get_many_related('Question_Group', $query_params);
1325
+	}
1326
+
1327
+
1328
+	/**
1329
+	 * Implementation for EEI_Has_Icon interface method.
1330
+	 *
1331
+	 * @see EEI_Visual_Representation for comments
1332
+	 * @return string
1333
+	 */
1334
+	public function get_icon()
1335
+	{
1336
+		return '<span class="dashicons dashicons-flag"></span>';
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * Implementation for EEI_Admin_Links interface method.
1342
+	 *
1343
+	 * @see EEI_Admin_Links for comments
1344
+	 * @return string
1345
+	 * @throws EE_Error
1346
+	 */
1347
+	public function get_admin_details_link()
1348
+	{
1349
+		return $this->get_admin_edit_link();
1350
+	}
1351
+
1352
+
1353
+	/**
1354
+	 * Implementation for EEI_Admin_Links interface method.
1355
+	 *
1356
+	 * @see EEI_Admin_Links for comments
1357
+	 * @return string
1358
+	 * @throws EE_Error
1359
+	 */
1360
+	public function get_admin_edit_link()
1361
+	{
1362
+		return EEH_URL::add_query_args_and_nonce(
1363
+			array(
1364
+				'page'   => 'espresso_events',
1365
+				'action' => 'edit',
1366
+				'post'   => $this->ID(),
1367
+			),
1368
+			admin_url('admin.php')
1369
+		);
1370
+	}
1371
+
1372
+
1373
+	/**
1374
+	 * Implementation for EEI_Admin_Links interface method.
1375
+	 *
1376
+	 * @see EEI_Admin_Links for comments
1377
+	 * @return string
1378
+	 */
1379
+	public function get_admin_settings_link()
1380
+	{
1381
+		return EEH_URL::add_query_args_and_nonce(
1382
+			array(
1383
+				'page'   => 'espresso_events',
1384
+				'action' => 'default_event_settings',
1385
+			),
1386
+			admin_url('admin.php')
1387
+		);
1388
+	}
1389
+
1390
+
1391
+	/**
1392
+	 * Implementation for EEI_Admin_Links interface method.
1393
+	 *
1394
+	 * @see EEI_Admin_Links for comments
1395
+	 * @return string
1396
+	 */
1397
+	public function get_admin_overview_link()
1398
+	{
1399
+		return EEH_URL::add_query_args_and_nonce(
1400
+			array(
1401
+				'page'   => 'espresso_events',
1402
+				'action' => 'default',
1403
+			),
1404
+			admin_url('admin.php')
1405
+		);
1406
+	}
1407
+
1408
+
1409
+	/**
1410
+	 * @return string|null
1411
+	 * @throws EE_Error
1412
+	 * @throws ReflectionException
1413
+	 */
1414
+	public function registrationFormUuid():? string
1415
+	{
1416
+		return $this->get('FSC_UUID');
1417
+	}
1418
+
1419
+
1420
+	/**
1421
+	 * Gets all the form sections for this event
1422
+	 *
1423
+	 * @return EE_Base_Class[]|EE_Form_Section[]
1424
+	 * @throws EE_Error
1425
+	 * @throws ReflectionException
1426
+	 */
1427
+	public function registrationForm()
1428
+	{
1429
+		$FSC_UUID = $this->registrationFormUuid();
1430
+		return !empty($FSC_UUID)
1431
+			? $this->get_many_related(
1432
+				'Form_Section',
1433
+				[
1434
+					[
1435
+						'OR' => [
1436
+							'Form_Section.FSC_UUID'      => $FSC_UUID, // top level form
1437
+							'Form_Section.FSC_belongsTo' => $FSC_UUID, // child form sections
1438
+						]
1439
+					],
1440
+					'order_by' => ['FSC_order' => 'ASC'],
1441
+				]
1442
+			)
1443
+			: [];
1444
+	}
1445
+
1446
+
1447
+	/**
1448
+	 * @param string $UUID
1449
+	 * @throws EE_Error
1450
+	 */
1451
+	public function setRegistrationFormUuid(string $UUID): void
1452
+	{
1453
+		$this->set('FSC_UUID', $UUID);
1454
+	}
1455 1455
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
      */
72 72
     public function getAvailableSpacesCalculator()
73 73
     {
74
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
74
+        if ( ! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
75 75
             $this->available_spaces_calculator = new EventSpacesCalculator($this);
76 76
         }
77 77
         return $this->available_spaces_calculator;
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
      */
214 214
     public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
215 215
     {
216
-        if (! empty($this->_Primary_Datetime)) {
216
+        if ( ! empty($this->_Primary_Datetime)) {
217 217
             return $this->_Primary_Datetime;
218 218
         }
219 219
         $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
     {
237 237
         // first get all datetimes
238 238
         $datetimes = $this->datetimes_ordered();
239
-        if (! $datetimes) {
239
+        if ( ! $datetimes) {
240 240
             return array();
241 241
         }
242 242
         $datetime_ids = array();
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
     public function short_description($num_words = 55, $more = null, $not_full_desc = false)
430 430
     {
431 431
         $short_desc = $this->get('EVT_short_desc');
432
-        if (! empty($short_desc) || $not_full_desc) {
432
+        if ( ! empty($short_desc) || $not_full_desc) {
433 433
             return $short_desc;
434 434
         }
435 435
         $full_desc = $this->get('EVT_desc');
@@ -883,7 +883,7 @@  discard block
 block discarded – undo
883 883
         );
884 884
         $all_expired = true;
885 885
         foreach ($tickets as $ticket) {
886
-            if (! $ticket->is_expired()) {
886
+            if ( ! $ticket->is_expired()) {
887 887
                 $all_expired = false;
888 888
                 break;
889 889
             }
@@ -974,7 +974,7 @@  discard block
 block discarded – undo
974 974
      */
975 975
     public function is_sold_out($actual = false)
976 976
     {
977
-        if (! $actual) {
977
+        if ( ! $actual) {
978 978
             return $this->status() === EEM_Event::sold_out;
979 979
         }
980 980
         return $this->perform_sold_out_status_check();
@@ -1019,11 +1019,11 @@  discard block
 block discarded – undo
1019 1019
     public function get_active_status($reset = false)
1020 1020
     {
1021 1021
         // if the active status has already been set, then just use that value (unless we are resetting it)
1022
-        if (! empty($this->_active_status) && ! $reset) {
1022
+        if ( ! empty($this->_active_status) && ! $reset) {
1023 1023
             return $this->_active_status;
1024 1024
         }
1025 1025
         // first check if event id is present on this object
1026
-        if (! $this->ID()) {
1026
+        if ( ! $this->ID()) {
1027 1027
             return false;
1028 1028
         }
1029 1029
         $where_params_for_event = array(array('EVT_ID' => $this->ID()));
@@ -1113,7 +1113,7 @@  discard block
 block discarded – undo
1113 1113
     public function get_number_of_tickets_sold()
1114 1114
     {
1115 1115
         $tkt_sold = 0;
1116
-        if (! $this->ID()) {
1116
+        if ( ! $this->ID()) {
1117 1117
             return 0;
1118 1118
         }
1119 1119
         $datetimes = $this->datetimes();
@@ -1297,7 +1297,7 @@  discard block
 block discarded – undo
1297 1297
             ]
1298 1298
         );
1299 1299
         $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1300
-        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1300
+        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext( ! $for_primary);
1301 1301
         if ($existing_relation->get($other_field) === false) {
1302 1302
             // Delete it. It's now no longer for primary or additional question groups.
1303 1303
             return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
@@ -1411,7 +1411,7 @@  discard block
 block discarded – undo
1411 1411
      * @throws EE_Error
1412 1412
      * @throws ReflectionException
1413 1413
      */
1414
-    public function registrationFormUuid():? string
1414
+    public function registrationFormUuid(): ? string
1415 1415
     {
1416 1416
         return $this->get('FSC_UUID');
1417 1417
     }
@@ -1427,7 +1427,7 @@  discard block
 block discarded – undo
1427 1427
     public function registrationForm()
1428 1428
     {
1429 1429
         $FSC_UUID = $this->registrationFormUuid();
1430
-        return !empty($FSC_UUID)
1430
+        return ! empty($FSC_UUID)
1431 1431
             ? $this->get_many_related(
1432 1432
                 'Form_Section',
1433 1433
                 [
Please login to merge, or discard this patch.