Completed
Branch BUG-10738-inconsistency-in-ses... (cda363)
by
unknown
13:38 queued 12s
created

EventSpacesCalculator   D

Complexity

Total Complexity 83

Size/Duplication

Total Lines 619
Duplicated Lines 8.89 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 55
loc 619
rs 4.7957
c 0
b 0
f 0
wmc 83
lcom 1
cbo 6

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getActiveTickets() 0 15 2
B setActiveTickets() 0 21 5
A validateTicket() 12 23 3
A getDatetimes() 0 4 1
A setDatetime() 12 16 2
A spacesRemaining() 0 5 1
A totalSpacesAvailable() 0 5 1
B initialize() 0 60 6
B calculate() 5 21 5
D adjustTicketQuantitiesDueToSales() 13 28 10
C trackAvailableSpacesForDatetimes() 9 48 10
B calculateAvailableSpacesForTicket() 0 54 9
C adjustDatetimes() 0 71 21
B adjustDatetimeSpaces() 4 28 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EventSpacesCalculator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EventSpacesCalculator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace EventEspresso\core\domain\services\event;
4
5
use DomainException;
6
use EE_Datetime;
7
use EE_Error;
8
use EE_Event;
9
use EE_Ticket;
10
use EEM_Ticket;
11
use EventEspresso\core\exceptions\InvalidDataTypeException;
12
use EventEspresso\core\exceptions\InvalidInterfaceException;
13
use EventEspresso\core\exceptions\UnexpectedEntityException;
14
use InvalidArgumentException;
15
16
defined('EVENT_ESPRESSO_VERSION') || exit;
17
18
19
20
/**
21
 * Class EventSpacesCalculator
22
 * Calculates total available spaces for an event with no regard for sold tickets,
23
 * or spaces remaining based on "saleable" tickets.
24
 * This is done by looping through all of the tickets and datetimes for the event
25
 * and simulating the sale of available tickets until each datetime reaches its maximum capacity.
26
 *
27
 * @package EventEspresso\core\domain\services\event
28
 * @author  Brent Christensen
29
 * @since   4.9.45
30
 */
31
class EventSpacesCalculator
32
{
33
34
    /**
35
     * @var EE_Event $event
36
     */
37
    private $event;
38
39
    /**
40
     * @var array $datetime_query_params
41
     */
42
    private $datetime_query_params;
43
44
    /**
45
     * @var EE_Ticket[] $active_tickets
46
     */
47
    private $active_tickets = array();
48
49
    /**
50
     * @var EE_Datetime[] $datetimes
51
     */
52
    private $datetimes = array();
53
54
    /**
55
     * Array of Ticket IDs grouped by Datetime
56
     *
57
     * @var array $datetimes
58
     */
59
    private $datetime_tickets = array();
60
61
    /**
62
     * Max spaces for each Datetime (reg limit - previous sold)
63
     *
64
     * @var array $datetime_spaces
65
     */
66
    private $datetime_spaces = array();
67
68
    /**
69
     * Array of Datetime IDs grouped by Ticket
70
     *
71
     * @var array $ticket_datetimes
72
     */
73
    private $ticket_datetimes = array();
74
75
    /**
76
     * maximum ticket quantities for each ticket (adjusted for reg limit)
77
     *
78
     * @var array $ticket_quantities
79
     */
80
    private $ticket_quantities = array();
81
82
    /**
83
     * total quantity of sold and reserved for each ticket
84
     *
85
     * @var array $tickets_sold
86
     */
87
    private $tickets_sold = array();
88
89
    /**
90
     * total spaces available across all datetimes
91
     *
92
     * @var array $total_spaces
93
     */
94
    private $total_spaces = array();
95
96
    /**
97
     * @var boolean $debug
98
     */
99
    private $debug = false;
100
101
102
103
    /**
104
     * EventSpacesCalculator constructor.
105
     *
106
     * @param EE_Event $event
107
     * @param array    $datetime_query_params
108
     * @throws EE_Error
109
     */
110
    public function __construct(EE_Event $event, array $datetime_query_params = array())
111
    {
112
        $this->event                 = $event;
113
        $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
114
    }
115
116
117
118
    /**
119
     * @return EE_Ticket[]
120
     * @throws EE_Error
121
     * @throws InvalidDataTypeException
122
     * @throws InvalidInterfaceException
123
     * @throws InvalidArgumentException
124
     */
125
    public function getActiveTickets()
126
    {
127
        if (empty($this->active_tickets)) {
128
            $this->active_tickets = $this->event->tickets(
129
                array(
130
                    array(
131
                        'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
132
                        'TKT_deleted'  => false,
133
                    ),
134
                    'order_by' => array('TKT_qty' => 'ASC'),
135
                )
136
            );
137
        }
138
        return $this->active_tickets;
139
    }
140
141
142
143
    /**
144
     * @param EE_Ticket[] $active_tickets
145
     * @throws EE_Error
146
     * @throws DomainException
147
     * @throws UnexpectedEntityException
148
     */
149
    public function setActiveTickets(array $active_tickets = array())
150
    {
151
        if ( ! empty($active_tickets)) {
152
            foreach ($active_tickets as $active_ticket) {
153
                $this->validateTicket($active_ticket);
154
            }
155
            // sort incoming array by ticket quantity (asc)
156
            usort(
157
                $active_tickets,
158
                function (EE_Ticket $a, EE_Ticket $b) {
159
                    if ($a->qty() === $b->qty()) {
160
                        return 0;
161
                    }
162
                    return ($a->qty() < $b->qty())
163
                        ? -1
164
                        : 1;
165
                }
166
            );
167
        }
168
        $this->active_tickets = $active_tickets;
169
    }
170
171
172
173
    /**
174
     * @param $ticket
175
     * @throws DomainException
176
     * @throws EE_Error
177
     * @throws UnexpectedEntityException
178
     */
179
    private function validateTicket($ticket)
180
    {
181
        if ( ! $ticket instanceof EE_Ticket) {
182
            throw new DomainException(
183
                esc_html__(
184
                    'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
185
                    'event_espresso'
186
                )
187
            );
188
        }
189 View Code Duplication
        if ($ticket->get_event_ID() !== $this->event->ID()) {
190
            throw new DomainException(
191
                sprintf(
192
                    esc_html__(
193
                        'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
194
                        'event_espresso'
195
                    ),
196
                    $ticket->get_event_ID(),
197
                    $this->event->ID()
198
                )
199
            );
200
        }
201
    }
202
203
204
205
    /**
206
     * @return EE_Datetime[]
207
     */
208
    public function getDatetimes()
209
    {
210
        return $this->datetimes;
211
    }
212
213
214
215
    /**
216
     * @param EE_Datetime $datetime
217
     * @throws EE_Error
218
     * @throws DomainException
219
     */
220
    public function setDatetime(EE_Datetime $datetime)
221
    {
222 View Code Duplication
        if ($datetime->event()->ID() !== $this->event->ID()) {
223
            throw new DomainException(
224
                sprintf(
225
                    esc_html__(
226
                        'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
227
                        'event_espresso'
228
                    ),
229
                    $datetime->event()->ID(),
230
                    $this->event->ID()
231
                )
232
            );
233
        }
234
        $this->datetimes[ $datetime->ID() ] = $datetime;
235
    }
236
237
238
239
    /**
240
     * calculate spaces remaining based on "saleable" tickets
241
     *
242
     * @return float|int
243
     * @throws EE_Error
244
     * @throws DomainException
245
     * @throws UnexpectedEntityException
246
     * @throws InvalidDataTypeException
247
     * @throws InvalidInterfaceException
248
     * @throws InvalidArgumentException
249
     */
250
    public function spacesRemaining()
251
    {
252
        $this->initialize();
253
        return $this->calculate();
254
    }
255
256
257
258
    /**
259
     * calculates total available spaces for an event with no regard for sold tickets
260
     *
261
     * @return int|float
262
     * @throws EE_Error
263
     * @throws DomainException
264
     * @throws UnexpectedEntityException
265
     * @throws InvalidDataTypeException
266
     * @throws InvalidInterfaceException
267
     * @throws InvalidArgumentException
268
     */
269
    public function totalSpacesAvailable()
270
    {
271
        $this->initialize();
272
        return $this->calculate(false);
273
    }
274
275
276
277
    /**
278
     * Loops through the active tickets for the event
279
     * and builds a series of data arrays that will be used for calculating
280
     * the total maximum available spaces, as well as the spaces remaining.
281
     * Because ticket quantities affect datetime spaces and vice versa,
282
     * we need to be constantly updating these data arrays as things change,
283
     * which is the entire reason for their existence.
284
     *
285
     * @throws EE_Error
286
     * @throws DomainException
287
     * @throws UnexpectedEntityException
288
     * @throws InvalidDataTypeException
289
     * @throws InvalidInterfaceException
290
     * @throws InvalidArgumentException
291
     */
292
    private function initialize()
293
    {
294
        if ($this->debug) {
295
            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
296
        }
297
        $this->datetime_tickets  = array();
298
        $this->datetime_spaces   = array();
299
        $this->ticket_datetimes  = array();
300
        $this->ticket_quantities = array();
301
        $this->tickets_sold      = array();
302
        $this->total_spaces      = array();
303
        $active_tickets          = $this->getActiveTickets();
304
        if ( ! empty($active_tickets)) {
305
            foreach ($active_tickets as $ticket) {
306
                $this->validateTicket($ticket);
307
                // we need to index our data arrays using strings for the purpose of sorting,
308
                // but we also need them to be unique, so  we'll just prepend a letter T to the ID
309
                $ticket_identifier = "T{$ticket->ID()}";
310
                // to start, we'll just consider the raw qty to be the maximum availability for this ticket
311
                $max_tickets = $ticket->qty();
312
                // but we'll adjust that after looping over each datetime for the ticket and checking reg limits
313
                $ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
314
                foreach ($ticket_datetimes as $datetime) {
315
                    // save all datetimes
316
                    $this->setDatetime($datetime);
317
                    $datetime_identifier = "D{$datetime->ID()}";
318
                    $reg_limit           = $datetime->reg_limit();
319
                    // ticket quantity can not exceed datetime reg limit
320
                    $max_tickets = min($max_tickets, $reg_limit);
321
                    // as described earlier, because we need to be able to constantly adjust numbers for things,
322
                    // we are going to move all of our data into the following arrays:
323
                    // datetime spaces initially represents the reg limit for each datetime,
324
                    // but this will get adjusted as tickets are accounted for
325
                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
326
                    // just an array of ticket IDs grouped by datetime
327
                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
328
                    // and an array of datetime IDs grouped by ticket
329
                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
330
                }
331
                // total quantity of sold and reserved for each ticket
332
                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
333
                // and the maximum ticket quantities for each ticket (adjusted for reg limit)
334
                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
335
            }
336
        }
337
        // sort datetime spaces by reg limit, but maintain our string indexes
338
        asort($this->datetime_spaces, SORT_NUMERIC);
339
        // datetime tickets need to be sorted in the SAME order as the above array...
340
        // so we'll just use array_merge() to take the structure of datetime_spaces
341
        // but overwrite all of the data with that from datetime_tickets
342
        $this->datetime_tickets = array_merge(
343
            $this->datetime_spaces,
344
            $this->datetime_tickets
345
        );
346
        if ($this->debug) {
347
            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
348
            \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
349
            \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
350
        }
351
    }
352
353
354
355
    /**
356
     * performs calculations on initialized data
357
     *
358
     * @param bool $consider_sold
359
     * @return int|float
360
     */
361
    private function calculate($consider_sold = true)
362
    {
363
        if ($this->debug) {
364
            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
365
        }
366
        if ($consider_sold) {
367
            // subtract amounts sold from all ticket quantities and datetime spaces
368
            $this->adjustTicketQuantitiesDueToSales();
369
        }
370
        foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
371
            $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
372
        }
373
        // total spaces available is just the sum of the spaces available for each datetime
374
        $spaces_remaining = array_sum($this->total_spaces);
375 View Code Duplication
        if ($this->debug) {
376
            \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
377
            \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
378
            \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
379
        }
380
        return $spaces_remaining;
381
    }
382
383
384
    /**
385
     * subtracts amount of  tickets sold from ticket quantities and datetime spaces
386
     */
387
    private function adjustTicketQuantitiesDueToSales()
388
    {
389
        if ($this->debug) {
390
            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
391
        }
392
        foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
393 View Code Duplication
            if (isset($this->ticket_quantities[ $ticket_identifier ])){
394
                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
395
                if ($this->debug) {
396
                    \EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
397
                }
398
            }
399
            if (
400
                isset($this->ticket_datetimes[ $ticket_identifier ])
401
                && is_array($this->ticket_datetimes[ $ticket_identifier ])
402
            ){
403
                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
404 View Code Duplication
                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
405
                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
406
                        if ($this->debug) {
407
                            \EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
408
                                'subtracting', __FILE__, __LINE__);
409
                        }
410
                    }
411
                }
412
            }
413
        }
414
    }
415
416
417
418
    /**
419
     * @param string $datetime_identifier
420
     * @param array  $tickets
421
     */
422
    private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
423
    {
424
        // make sure a reg limit is set for the datetime
425
        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
426
            ? $this->datetime_spaces[ $datetime_identifier ]
427
            : 0;
428
        // and bail if it is not
429
        if ( ! $reg_limit) {
430
            if ($this->debug) {
431
                \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
432
            }
433
            return;
434
        }
435 View Code Duplication
        if ($this->debug) {
436
            \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
437
            \EEH_Debug_Tools::printr("{$reg_limit}", 'REG LIMIT', __FILE__, __LINE__);
438
        }
439
        // number of allocated spaces always starts at zero
440
        $spaces_allocated                           = 0;
441
        $this->total_spaces[ $datetime_identifier ] = 0;
442
        foreach ($tickets as $ticket_identifier) {
443
            $spaces_allocated = $this->calculateAvailableSpacesForTicket(
444
                $datetime_identifier,
445
                $reg_limit,
446
                $ticket_identifier,
447
                $spaces_allocated
448
            );
449
        }
450
        // spaces can't be negative
451
        $spaces_allocated = max($spaces_allocated, 0);
452
        if ($spaces_allocated) {
453
            // track any non-zero values
454
            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
455
            if ($this->debug) {
456
                \EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
457
            }
458
        } else {
459
            if ($this->debug) {
460
                \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
461
            }
462
        }
463 View Code Duplication
        if ($this->debug) {
464
            \EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
465
                __LINE__);
466
            \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
467
            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
468
        }
469
    }
470
471
472
473
    /**
474
     * @param string $datetime_identifier
475
     * @param int    $reg_limit
476
     * @param string $ticket_identifier
477
     * @param int    $spaces_allocated
478
     * @return int
479
     */
480
    private function calculateAvailableSpacesForTicket(
481
        $datetime_identifier,
482
        $reg_limit,
483
        $ticket_identifier,
484
        $spaces_allocated
485
    ) {
486
        // make sure ticket quantity is set
487
        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
488
            ? $this->ticket_quantities[ $ticket_identifier ]
489
            : 0;
490
        if ($this->debug) {
491
            \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
492
            \EEH_Debug_Tools::printr("{$ticket_quantity}", "ticket $ticket_identifier quantity: ",
493
                __FILE__, __LINE__, 2);
494
        }
495
        if ($ticket_quantity) {
496
            if ($this->debug) {
497
                \EEH_Debug_Tools::printr(
498
                    ($spaces_allocated <= $reg_limit)
499
                        ? 'true'
500
                        : 'false',
501
                    ' . spaces_allocated <= reg_limit = ',
502
                    __FILE__, __LINE__
503
                );
504
            }
505
            // if the datetime is NOT at full capacity yet
506
            if ($spaces_allocated <= $reg_limit) {
507
                // then the maximum ticket quantity we can allocate is the lowest value of either:
508
                //  the number of remaining spaces for the datetime, which is the limit - spaces already taken
509
                //  or the maximum ticket quantity
510
                $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
511
                // adjust the available quantity in our tracking array
512
                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
513
                // and increment spaces allocated for this datetime
514
                $spaces_allocated += $ticket_quantity;
515
                $at_capacity = $spaces_allocated >= $reg_limit;
516
                if ($this->debug) {
517
                    \EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
518
                        __FILE__, __LINE__,   3);
519
                    if ($at_capacity) {
520
                        \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
521
                    }
522
                }
523
                // now adjust all other datetimes that allow access to this ticket
524
                $this->adjustDatetimes(
525
                    $datetime_identifier,
526
                    $ticket_identifier,
527
                    $ticket_quantity,
528
                    $at_capacity
529
                );
530
            }
531
        }
532
        return $spaces_allocated;
533
    }
534
535
536
537
    /**
538
     * subtracts ticket amounts from all datetime reg limits
539
     * that allow access to the ticket specified,
540
     * because that ticket could be used
541
     * to attend any of the datetimes it has access to
542
     *
543
     * @param string $datetime_identifier
544
     * @param string $ticket_identifier
545
     * @param bool   $at_capacity
546
     * @param int    $ticket_quantity
547
     */
548
    private function adjustDatetimes(
549
        $datetime_identifier,
550
        $ticket_identifier,
551
        $ticket_quantity,
552
        $at_capacity
553
    ) {
554
        foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
555
            if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
556
                continue;
557
            }
558
            $adjusted = $this->adjustDatetimeSpaces(
559
                $datetime_ID,
560
                $ticket_identifier,
561
                $ticket_quantity
562
            );
563
            // skip to next ticket if nothing changed
564
            if (! ($adjusted || $at_capacity)) {
565
                continue;
566
            }
567
            // then all of it's tickets are now unavailable
568
            foreach ($datetime_tickets as $datetime_ticket) {
569
                if (
570
                    ($ticket_identifier === $datetime_ticket || $at_capacity)
571
                    && isset($this->ticket_quantities[ $datetime_ticket ])
572
                    && $this->ticket_quantities[ $datetime_ticket ] > 0
573
                ) {
574
                    if ($this->debug) {
575
                        \EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
576
                            __LINE__);
577
                    }
578
                    // if this datetime is at full capacity, set any tracked available quantities to zero
579
                    // otherwise just subtract the ticket quantity
580
                    $new_quantity = $at_capacity
581
                        ? 0
582
                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
583
                    // don't let ticket quantity go below zero
584
                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
585
                    if ($this->debug) {
586
                        \EEH_Debug_Tools::printr(
587
                            $at_capacity
588
                                ? "0 because Datetime {$datetime_identifier} is at capacity"
589
                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
590
                            " . . . . {$datetime_ticket} quantity set to ",
591
                            __FILE__, __LINE__
592
                        );
593
                    }
594
                }
595
                // but we also need to adjust spaces for any other datetimes this ticket has access to
596
                if ($datetime_ticket === $ticket_identifier) {
597
                    if (isset($this->ticket_datetimes[ $datetime_ticket ])
598
                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
599
                    ) {
600
                        if ($this->debug) {
601
                            \EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
602
                                __LINE__);
603
                        }
604
                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
605
                            // don't adjust the current datetime twice
606
                            if ($datetime !== $datetime_identifier) {
607
                                $this->adjustDatetimeSpaces(
608
                                    $datetime,
609
                                    $datetime_ticket,
610
                                    $ticket_quantity
611
                                );
612
                            }
613
                        }
614
                    }
615
                }
616
            }
617
        }
618
    }
619
620
    private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
621
    {
622
        // does datetime have spaces available?
623
        // and does the supplied ticket have access to this datetime ?
624
        if (
625
            $this->datetime_spaces[ $datetime_identifier ] > 0
626
            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
627
            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
628
            ) {
629 View Code Duplication
            if ($this->debug) {
630
                \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
631
                \EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
632
            }
633
            // then decrement the available spaces for the datetime
634
            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
635
            // but don't let quantities go below zero
636
            $this->datetime_spaces[ $datetime_identifier ] = max(
637
                $this->datetime_spaces[ $datetime_identifier ],
638
                0
639
            );
640
            if ($this->debug) {
641
                \EEH_Debug_Tools::printr("{$ticket_quantity}",
642
                    " . . . {$datetime_identifier} capacity reduced by", __FILE__, __LINE__);
643
            }
644
            return true;
645
        }
646
        return false;
647
    }
648
649
}
650
// Location: EventSpacesCalculator.php
651