Completed
Branch BUG-10375-migrations-not-repor... (1e9646)
by
unknown
62:53 queued 49:42
created

ProcessTicketSelector::validatePostData()   D

Complexity

Conditions 19
Paths 29

Size

Total Lines 107
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 69
nc 29
nop 1
dl 0
loc 107
rs 4.764
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace EventEspresso\modules\ticket_selector;
3
4
if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
    exit('No direct script access allowed');
6
}
7
8
9
10
/**
11
 * Class ProcessTicketSelector
12
 * Description
13
 *
14
 * @package       Event Espresso
15
 * @subpackage    core
16
 * @author        Brent Christensen
17
 * @since         4.9.0
18
 */
19
class ProcessTicketSelector
20
{
21
22
    /**
23
     * array of datetimes and the spaces available for them
24
     *
25
     * @access private
26
     * @var array
27
     */
28
    private static $_available_spaces = array();
29
30
31
32
    /**
33
     * cancelTicketSelections
34
     *
35
     * @return        string
36
     */
37
    public function cancelTicketSelections()
38
    {
39
        // check nonce
40
        if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) {
41
            return false;
42
        }
43
        \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
44
        if (\EE_Registry::instance()->REQ->is_set('event_id')) {
45
            wp_safe_redirect(
46
                \EEH_Event_View::event_link_url(
47
                    \EE_Registry::instance()->REQ->get('event_id')
48
                )
49
            );
50
        } else {
51
            wp_safe_redirect(
52
                site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/')
53
            );
54
        }
55
        exit();
56
    }
57
58
59
60
    /**
61
     * processTicketSelectorNonce
62
     *
63
     * @param  string $nonce_name
64
     * @param string  $id
65
     * @return bool
66
     */
67
    private function processTicketSelectorNonce($nonce_name, $id = '')
68
    {
69
        $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce";
70
        if (
71
            ! is_admin()
72
            && (
73
                ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id)
74
                || ! wp_verify_nonce(
75
                    \EE_Registry::instance()->REQ->get($nonce_name_with_id),
76
                    $nonce_name
77
                )
78
            )
79
        ) {
80
            \EE_Error::add_error(
81
                sprintf(
82
                    __(
83
                        'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.',
84
                        'event_espresso'
85
                    ),
86
                    '<br/>'
87
                ),
88
                __FILE__,
89
                __FUNCTION__,
90
                __LINE__
91
            );
92
            return false;
93
        }
94
        return true;
95
    }
96
97
98
99
    /**
100
     * process_ticket_selections
101
     *
102
     * @return array|bool
103
     * @throws \EE_Error
104
     */
105
    public function processTicketSelections()
106
    {
107
        do_action('EED_Ticket_Selector__process_ticket_selections__before');
108
        // do we have an event id?
109 View Code Duplication
        if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) {
110
            // $_POST['tkt-slctr-event-id'] was not set ?!?!?!?
111
            \EE_Error::add_error(
112
                sprintf(
113
                    __(
114
                        'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.',
115
                        'event_espresso'
116
                    ),
117
                    '<br/>'
118
                ),
119
                __FILE__,
120
                __FUNCTION__,
121
                __LINE__
122
            );
123
        }
124
        //if event id is valid
125
        $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id'));
126
        // check nonce
127
        if ( ! $this->processTicketSelectorNonce('process_ticket_selections', $id)) {
128
            return false;
129
        }
130
        //		d( \EE_Registry::instance()->REQ );
131
        self::$_available_spaces = array(
132
            'tickets'   => array(),
133
            'datetimes' => array(),
134
        );
135
        //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart.
136
        // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc.
137
        \EE_Registry::instance()->load_core('Session');
138
        // unless otherwise requested, clear the session
139
        if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) {
140
            \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
141
        }
142
        //d( \EE_Registry::instance()->SSN );
143
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
144
        // validate/sanitize data
145
        $valid = $this->validatePostData($id);
146
        //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
147
        //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ );
148
        //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ );
149
        //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ );
150
        //check total tickets ordered vs max number of attendees that can register
151
        if ($valid['total_tickets'] > $valid['max_atndz']) {
152
            // ordering too many tickets !!!
153
            $total_tickets_string = _n(
154
                'You have attempted to purchase %s ticket.',
155
                'You have attempted to purchase %s tickets.',
156
                $valid['total_tickets'],
157
                'event_espresso'
158
            );
159
            $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']);
160
            // dev only message
161
            $max_atndz_string = _n(
162
                'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
163
                'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
164
                $valid['max_atndz'],
165
                'event_espresso'
166
            );
167
            $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']);
168
            \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
169
        } else {
170
            // all data appears to be valid
171
            $tckts_slctd = false;
172
            $tickets_added = 0;
173
            $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid);
174
            if ($valid['total_tickets'] > 0) {
175
                // load cart
176
                \EE_Registry::instance()->load_core('Cart');
177
                // cycle thru the number of data rows sent from the event listing
178
                for ($x = 0; $x < $valid['rows']; $x++) {
179
                    // does this row actually contain a ticket quantity?
180
                    if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) {
181
                        // YES we have a ticket quantity
182
                        $tckts_slctd = true;
183
                        //						d( $valid['ticket_obj'][$x] );
184
                        if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) {
185
                            // then add ticket to cart
186
                            $tickets_added += $this->addTicketToCart(
187
                                $valid['ticket_obj'][$x],
188
                                $valid['qty'][$x]
189
                            );
190
                            if (\EE_Error::has_error()) {
191
                                break;
192
                            }
193
                        } else {
194
                            // nothing added to cart retrieved
195
                            \EE_Error::add_error(
196
                                sprintf(
197
                                    __(
198
                                        'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.',
199
                                        'event_espresso'
200
                                    ),
201
                                    '<br/>'
202
                                ),
203
                                __FILE__, __FUNCTION__, __LINE__
204
                            );
205
                        }
206
                    }
207
                }
208
            }
209
            do_action(
210
                'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
211
                \EE_Registry::instance()->CART,
212
                $this
213
            );
214
            //d( \EE_Registry::instance()->CART );
215
            //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
216
            if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) {
217
                if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
218
                    do_action(
219
                        'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout',
220
                        \EE_Registry::instance()->CART,
221
                        $this
222
                    );
223
                    \EE_Registry::instance()->CART->recalculate_all_cart_totals();
224
                    \EE_Registry::instance()->CART->save_cart(false);
225
                    // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<<  OR HERE TO KILL REDIRECT AFTER CART UPDATE
226
                    // just return TRUE for registrations being made from admin
227
                    if (is_admin()) {
228
                        return true;
229
                    }
230
                    \EE_Error::get_notices(false, true);
231
                    wp_safe_redirect(
232
                        apply_filters(
233
                            'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url',
234
                            \EE_Registry::instance()->CFG->core->reg_page_url()
235
                        )
236
                    );
237
                    exit();
238
                } else {
239
                    if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) {
240
                        // nothing added to cart
241
                        \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'),
242
                            __FILE__, __FUNCTION__, __LINE__);
243
                    }
244
                }
245
            } else {
246
                // no ticket quantities were selected
247
                \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.',
248
                    'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
249
            }
250
        }
251
        //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT
252
        // at this point, just return if registration is being made from admin
253
        if (is_admin()) {
254
            return false;
255
        }
256
        if ($valid['return_url']) {
257
            \EE_Error::get_notices(false, true);
258
            wp_safe_redirect($valid['return_url']);
259
            exit();
260
        } elseif (isset($event_to_add['id'])) {
0 ignored issues
show
Bug introduced by
The variable $event_to_add seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
261
            \EE_Error::get_notices(false, true);
262
            wp_safe_redirect(get_permalink($event_to_add['id']));
263
            exit();
264
        } else {
265
            echo \EE_Error::get_notices();
266
        }
267
        return false;
268
    }
269
270
271
272
    /**
273
     * validate_post_data
274
     *
275
     * @param int $id
276
     * @return array|FALSE
277
     */
278
    private function validatePostData($id = 0)
279
    {
280
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
281
        if ( ! $id) {
282
            \EE_Error::add_error(
283
                __('The event id provided was not valid.', 'event_espresso'),
284
                __FILE__,
285
                __FUNCTION__,
286
                __LINE__
287
            );
288
            return false;
289
        }
290
        // start with an empty array()
291
        $valid_data = array();
292
        // grab valid id
293
        $valid_data['id'] = $id;
294
        // array of other form names
295
        $inputs_to_clean = array(
296
            'event_id'   => 'tkt-slctr-event-id',
297
            'max_atndz'  => 'tkt-slctr-max-atndz-',
298
            'rows'       => 'tkt-slctr-rows-',
299
            'qty'        => 'tkt-slctr-qty-',
300
            'ticket_id'  => 'tkt-slctr-ticket-id-',
301
            'return_url' => 'tkt-slctr-return-url-',
302
        );
303
        // let's track the total number of tickets ordered.'
304
        $valid_data['total_tickets'] = 0;
305
        // cycle through $inputs_to_clean array
306
        foreach ($inputs_to_clean as $what => $input_to_clean) {
307
            // check for POST data
308
            if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) {
309
                // grab value
310
                $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id);
311
                switch ($what) {
312
                    // integers
313
                    case 'event_id':
314
                        $valid_data[$what] = absint($input_value);
315
                        // get event via the event id we put in the form
316
                        $valid_data['event'] = \EE_Registry::instance()
317
                                                           ->load_model('Event')
318
                                                           ->get_one_by_ID($valid_data['event_id']);
319
                        break;
320
                    case 'rows':
321
                    case 'max_atndz':
322
                        $valid_data[$what] = absint($input_value);
323
                        break;
324
                    // arrays of integers
325
                    case 'qty':
326
                        /** @var array $row_qty */
327
                        $row_qty = $input_value;
328
                        // if qty is coming from a radio button input, then we need to assemble an array of rows
329
                        if ( ! is_array($row_qty)) {
330
                            // get number of rows
331
                            $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id)
332
                                ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id))
333
                                : 1;
334
                            // explode ints by the dash
335
                            $row_qty = explode('-', $row_qty);
336
                            $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1;
337
                            $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0;
338
                            $row_qty = array($row => $qty);
339
                            for ($x = 1; $x <= $rows; $x++) {
340
                                if ( ! isset($row_qty[$x])) {
341
                                    $row_qty[$x] = 0;
342
                                }
343
                            }
344
                        }
345
                        ksort($row_qty);
346
                        // cycle thru values
347
                        foreach ($row_qty as $qty) {
348
                            $qty = absint($qty);
349
                            // sanitize as integers
350
                            $valid_data[$what][] = $qty;
351
                            $valid_data['total_tickets'] += $qty;
352
                        }
353
                        break;
354
                    // array of integers
355
                    case 'ticket_id':
356
                        $value_array = array();
357
                        // cycle thru values
358
                        foreach ((array)$input_value as $key => $value) {
359
                            // allow only numbers, letters,  spaces, commas and dashes
360
                            $value_array[$key] = wp_strip_all_tags($value);
361
                            // get ticket via the ticket id we put in the form
362
                            $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value);
363
                            $valid_data['ticket_obj'][$key] = $ticket_obj;
364
                        }
365
                        $valid_data[$what] = $value_array;
366
                        break;
367
                    case 'return_url' :
368
                        // grab and sanitize return-url
369
                        $input_value = esc_url_raw($input_value);
370
                        // was the request coming from an iframe ? if so, then:
371
                        if (strpos($input_value, 'event_list=iframe')) {
372
                            // get anchor fragment
373
                            $input_value = explode('#', $input_value);
374
                            $input_value = end($input_value);
375
                            // use event list url instead, but append anchor
376
                            $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value;
377
                        }
378
                        $valid_data[$what] = $input_value;
379
                        break;
380
                }    // end switch $what
381
            }
382
        }    // end foreach $inputs_to_clean
383
        return $valid_data;
384
    }
385
386
387
388
    /**
389
     * adds a ticket to the cart
390
     *
391
     * @param \EE_Ticket $ticket
392
     * @param int        $qty
393
     * @return TRUE on success, FALSE on fail
394
     * @throws \EE_Error
395
     */
396
    private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1)
397
    {
398
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
399
        // get the number of spaces left for this datetime ticket
400
        $available_spaces = $this->ticketDatetimeAvailability($ticket);
0 ignored issues
show
Bug introduced by
It seems like $ticket defined by parameter $ticket on line 396 can be null; however, EventEspresso\modules\ti...tDatetimeAvailability() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
401
        // compare available spaces against the number of tickets being purchased
402
        if ($available_spaces >= $qty) {
403
            // allow addons to prevent a ticket from being added to cart
404
            if (
405
            ! apply_filters(
406
                'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart',
407
                true,
408
                $ticket,
409
                $qty,
410
                $available_spaces
411
            )
412
            ) {
413
                return false;
414
            }
415
            $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket));
416
            // add event to cart
417
            if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) {
0 ignored issues
show
Bug introduced by
It seems like $ticket defined by parameter $ticket on line 396 can be null; however, EE_Cart::add_ticket_to_cart() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
418
                $this->recalculateTicketDatetimeAvailability($ticket, $qty);
0 ignored issues
show
Bug introduced by
It seems like $ticket defined by parameter $ticket on line 396 can be null; however, EventEspresso\modules\ti...tDatetimeAvailability() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
419
                return true;
420
            }
421
            return false;
422
        }
423
        // tickets can not be purchased but let's find the exact number left
424
        // for the last ticket selected PRIOR to subtracting tickets
425
        $available_spaces = $this->ticketDatetimeAvailability($ticket, true);
0 ignored issues
show
Bug introduced by
It seems like $ticket defined by parameter $ticket on line 396 can be null; however, EventEspresso\modules\ti...tDatetimeAvailability() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
426
        // greedy greedy greedy eh?
427 View Code Duplication
        if ($available_spaces > 0) {
428
            if (
429
            apply_filters(
430
                'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error',
431
                true,
432
                $ticket,
433
                $qty,
434
                $available_spaces
435
            )
436
            ) {
437
                $this->displayAvailabilityError($available_spaces);
438
            }
439
        } else {
440
            \EE_Error::add_error(
441
                __(
442
                    'We\'re sorry, but there are no available spaces left for this event at this particular date and time.',
443
                    'event_espresso'
444
                ),
445
                __FILE__, __FUNCTION__, __LINE__
446
            );
447
        }
448
        return false;
449
    }
450
451
452
453
    /**
454
     * @param int $available_spaces
455
     * @throws \EE_Error
456
     */
457
    private function displayAvailabilityError($available_spaces = 1)
458
    {
459
        // add error messaging - we're using the _n function that will generate
460
        // the appropriate singular or plural message based on the number of $available_spaces
461
        if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) {
462
            $msg = sprintf(
463
                _n(
464
                    'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
465
                    'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
466
                    $available_spaces,
467
                    'event_espresso'
468
                ),
469
                $available_spaces,
470
                '<br />'
471
            );
472
        } else {
473
            $msg = sprintf(
474
                _n(
475
                    'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
476
                    'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
477
                    $available_spaces,
478
                    'event_espresso'
479
                ),
480
                $available_spaces,
481
                '<br />'
482
            );
483
        }
484
        \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
485
    }
486
487
488
489
    /**
490
     * ticketDatetimeAvailability
491
     * creates an array of tickets plus all of the datetimes available to each ticket
492
     * and tracks the spaces remaining for each of those datetimes
493
     *
494
     * @param \EE_Ticket $ticket - selected ticket
495
     * @param bool       $get_original_ticket_spaces
496
     * @return int
497
     * @throws \EE_Error
498
     */
499
    private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false)
500
    {
501
        // if the $_available_spaces array has not been set up yet...
502
        if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
503
            $this->setInitialTicketDatetimeAvailability($ticket);
504
        }
505
        $available_spaces = $ticket->qty() - $ticket->sold();
506
        if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
507
            // loop thru tickets, which will ALSO include individual ticket records AND a total
508
            foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
509
                // if we want the original datetime availability BEFORE we started subtracting tickets ?
510
                if ($get_original_ticket_spaces) {
511
                    // then grab the available spaces from the "tickets" array
512
                    // and compare with the above to get the lowest number
513
                    $available_spaces = min(
514
                        $available_spaces,
515
                        self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID]
516
                    );
517
                } else {
518
                    // we want the updated ticket availability as stored in the "datetimes" array
519
                    $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]);
520
                }
521
            }
522
        }
523
        return $available_spaces;
524
    }
525
526
527
528
    /**
529
     * @param \EE_Ticket $ticket
530
     * @return void
531
     * @throws \EE_Error
532
     */
533
    private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket)
534
    {
535
        // first, get all of the datetimes that are available to this ticket
536
        $datetimes = $ticket->get_many_related(
537
            'Datetime',
538
            array(
539
                array(
540
                    'DTT_EVT_end' => array(
541
                        '>=',
542
                        \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
543
                    ),
544
                ),
545
                'order_by' => array('DTT_EVT_start' => 'ASC'),
546
            )
547
        );
548
        if ( ! empty($datetimes)) {
549
            // now loop thru all of the datetimes
550
            foreach ($datetimes as $datetime) {
551
                if ($datetime instanceof \EE_Datetime) {
552
                    // the number of spaces available for the datetime without considering individual ticket quantities
553
                    $spaces_remaining = $datetime->spaces_remaining();
554
                    // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold
555
                    // or the datetime spaces remaining) to this ticket using the datetime ID as the key
556
                    self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min(
557
                        $ticket->qty() - $ticket->sold(),
558
                        $spaces_remaining
559
                    );
560
                    // if the remaining spaces for this datetime is already set,
561
                    // then compare that against the datetime spaces remaining, and take the lowest number,
562
                    // else just take the datetime spaces remaining, and assign to the datetimes array
563
                    self::$_available_spaces['datetimes'][$datetime->ID()] = isset(
564
                        self::$_available_spaces['datetimes'][$datetime->ID()]
565
                    )
566
                        ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining)
567
                        : $spaces_remaining;
568
                }
569
            }
570
        }
571
    }
572
573
574
575
    /**
576
     * @param    \EE_Ticket $ticket
577
     * @param    int        $qty
578
     * @return    void
579
     */
580
    private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0)
581
    {
582
        if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
583
            // loop thru tickets, which will ALSO include individual ticket records AND a total
584
            foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
585
                // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to,
586
                self::$_available_spaces['datetimes'][$DTD_ID] -= $qty;
587
            }
588
        }
589
    }
590
591
592
}
593
// End of file ProcessTicketSelector.php
594
// Location: /ProcessTicketSelector.php