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