Completed
Branch BUG/pantheon-session-fatal-2 (dc6a1f)
by
unknown
199:51 queued 131:59
created
modules/ticket_sales_monitor/EED_Ticket_Sales_Monitor.module.php 3 patches
Doc Comments   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
      *
327 327
      * @param    EE_Ticket $ticket
328 328
      * @param int          $quantity
329
-     * @return bool
329
+     * @return integer
330 330
      * @throws EE_Error
331 331
      */
332 332
     protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
     /**
344 344
      * @param  EE_Ticket $ticket
345 345
      * @param  int       $quantity
346
-     * @return bool
346
+     * @return integer
347 347
      * @throws EE_Error
348 348
      */
349 349
     protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
@@ -969,6 +969,7 @@  discard block
 block discarded – undo
969 969
     /**
970 970
      * @param EE_Ticket[]    $tickets_with_reservations
971 971
      * @param EE_Line_Item[] $valid_reserved_ticket_line_items
972
+     * @param string $source
972 973
      * @return int
973 974
      * @throws UnexpectedEntityException
974 975
      * @throws DomainException
Please login to merge, or discard this patch.
Indentation   +1043 added lines, -1043 removed lines patch added patch discarded remove patch
@@ -20,1048 +20,1048 @@
 block discarded – undo
20 20
 class EED_Ticket_Sales_Monitor extends EED_Module
21 21
 {
22 22
 
23
-    const debug = false;
24
-
25
-    private static $nl = '';
26
-
27
-    /**
28
-     * an array of raw ticket data from EED_Ticket_Selector
29
-     *
30
-     * @var array $ticket_selections
31
-     */
32
-    protected $ticket_selections = array();
33
-
34
-    /**
35
-     * the raw ticket data from EED_Ticket_Selector is organized in rows
36
-     * according to how they are displayed in the actual Ticket_Selector
37
-     * this tracks the current row being processed
38
-     *
39
-     * @var int $current_row
40
-     */
41
-    protected $current_row = 0;
42
-
43
-    /**
44
-     * an array for tracking names of tickets that have sold out
45
-     *
46
-     * @var array $sold_out_tickets
47
-     */
48
-    protected $sold_out_tickets = array();
49
-
50
-    /**
51
-     * an array for tracking names of tickets that have had their quantities reduced
52
-     *
53
-     * @var array $decremented_tickets
54
-     */
55
-    protected $decremented_tickets = array();
56
-
57
-
58
-    /**
59
-     * set_hooks - for hooking into EE Core, other modules, etc
60
-     *
61
-     * @return    void
62
-     */
63
-    public static function set_hooks()
64
-    {
65
-        self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
66
-        // release tickets for expired carts
67
-        add_action(
68
-            'EED_Ticket_Selector__process_ticket_selections__before',
69
-            array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
70
-            1
71
-        );
72
-        // check ticket reserves AFTER MER does it's check (hence priority 20)
73
-        add_filter(
74
-            'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
75
-            array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
76
-            20,
77
-            3
78
-        );
79
-        // add notices for sold out tickets
80
-        add_action(
81
-            'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
82
-            array('EED_Ticket_Sales_Monitor', 'post_notices'),
83
-            10
84
-        );
85
-
86
-        // handle tickets deleted from cart
87
-        add_action(
88
-            'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
89
-            array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
90
-            10,
91
-            2
92
-        );
93
-        // handle emptied carts
94
-        add_action(
95
-            'AHEE__EE_Session__reset_cart__before_reset',
96
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
97
-            10,
98
-            1
99
-        );
100
-        add_action(
101
-            'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
102
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
103
-            10,
104
-            1
105
-        );
106
-        // handle cancelled registrations
107
-        add_action(
108
-            'AHEE__EE_Session__reset_checkout__before_reset',
109
-            array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
110
-            10,
111
-            1
112
-        );
113
-        // cron tasks
114
-        add_action(
115
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
116
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
117
-            10,
118
-            1
119
-        );
120
-        add_action(
121
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
122
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
123
-            10,
124
-            1
125
-        );
126
-        add_action(
127
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
128
-            array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
129
-            10,
130
-            1
131
-        );
132
-    }
133
-
134
-
135
-    /**
136
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
137
-     *
138
-     * @return void
139
-     */
140
-    public static function set_hooks_admin()
141
-    {
142
-        EED_Ticket_Sales_Monitor::set_hooks();
143
-    }
144
-
145
-
146
-    /**
147
-     * @return EED_Ticket_Sales_Monitor|EED_Module
148
-     */
149
-    public static function instance()
150
-    {
151
-        return parent::get_instance(__CLASS__);
152
-    }
153
-
154
-
155
-    /**
156
-     * @param WP_Query $WP_Query
157
-     * @return    void
158
-     */
159
-    public function run($WP_Query)
160
-    {
161
-    }
162
-
163
-
164
-
165
-    /********************************** PRE_TICKET_SALES  **********************************/
166
-
167
-
168
-    /**
169
-     * Retrieves grand totals from the line items that have no TXN ID
170
-     * and timestamps less than the current time minus the session lifespan.
171
-     * These are carts that have been abandoned before the "registrant" even attempted to checkout.
172
-     * We're going to release the tickets for these line items before attempting to add more to the cart.
173
-     *
174
-     * @return void
175
-     * @throws DomainException
176
-     * @throws EE_Error
177
-     * @throws InvalidArgumentException
178
-     * @throws InvalidDataTypeException
179
-     * @throws InvalidInterfaceException
180
-     * @throws UnexpectedEntityException
181
-     */
182
-    public static function release_tickets_for_expired_carts()
183
-    {
184
-        if (self::debug) {
185
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
186
-        }
187
-        do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
188
-        $expired_ticket_IDs = array();
189
-        /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
190
-        $session_lifespan = LoaderFactory::getLoader()->getShared(
191
-            'EventEspresso\core\domain\values\session\SessionLifespan'
192
-        );
193
-        $timestamp = $session_lifespan->expiration();
194
-        $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
195
-        if (self::debug) {
196
-            echo self::$nl . ' . time(): ' . time();
197
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
198
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
199
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
200
-            echo self::$nl . ' . timestamp: ' . $timestamp;
201
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
202
-        }
203
-        if (! empty($expired_ticket_line_items)) {
204
-            foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
205
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
206
-                    continue;
207
-                }
208
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
209
-                if (self::debug) {
210
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
211
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
212
-                         . date(
213
-                             'Y-m-d h:i a',
214
-                             $expired_ticket_line_item->timestamp(true)
215
-                         );
216
-                }
217
-            }
218
-            if (! empty($expired_ticket_IDs)) {
219
-                EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
220
-                    \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
221
-                    array(),
222
-                    __FUNCTION__
223
-                );
224
-                // now  let's get rid of expired line items so that they can't interfere with tracking
225
-                EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
226
-            }
227
-        }
228
-        do_action(
229
-            'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
230
-            $expired_ticket_IDs,
231
-            $expired_ticket_line_items
232
-        );
233
-    }
234
-
235
-
236
-
237
-    /********************************** VALIDATE_TICKET_SALE  **********************************/
238
-
239
-
240
-    /**
241
-     * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
242
-     *
243
-     * @param int       $qty
244
-     * @param EE_Ticket $ticket
245
-     * @return bool
246
-     * @throws UnexpectedEntityException
247
-     * @throws EE_Error
248
-     */
249
-    public static function validate_ticket_sale($qty = 1, EE_Ticket $ticket)
250
-    {
251
-        $qty = absint($qty);
252
-        if ($qty > 0) {
253
-            $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
254
-        }
255
-        if (self::debug) {
256
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
257
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
258
-        }
259
-        return $qty;
260
-    }
261
-
262
-
263
-    /**
264
-     * checks whether an individual ticket is available for purchase based on datetime, and ticket details
265
-     *
266
-     * @param   EE_Ticket $ticket
267
-     * @param int         $qty
268
-     * @return int
269
-     * @throws UnexpectedEntityException
270
-     * @throws EE_Error
271
-     */
272
-    protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
273
-    {
274
-        if (self::debug) {
275
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
276
-        }
277
-        if (! $ticket instanceof EE_Ticket) {
278
-            return 0;
279
-        }
280
-        if (self::debug) {
281
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
282
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
283
-        }
284
-        $ticket->refresh_from_db();
285
-        // first let's determine the ticket availability based on sales
286
-        $available = $ticket->qty('saleable');
287
-        if (self::debug) {
288
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
289
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
290
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
291
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
292
-            echo self::$nl . ' . . . available: ' . $available;
293
-        }
294
-        if ($available < 1) {
295
-            $this->_ticket_sold_out($ticket);
296
-            return 0;
297
-        }
298
-        if (self::debug) {
299
-            echo self::$nl . ' . . . qty: ' . $qty;
300
-        }
301
-        if ($available < $qty) {
302
-            $qty = $available;
303
-            if (self::debug) {
304
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
305
-            }
306
-            $this->_ticket_quantity_decremented($ticket);
307
-        }
308
-        $this->_reserve_ticket($ticket, $qty);
309
-        return $qty;
310
-    }
311
-
312
-
313
-    /**
314
-     * increments ticket reserved based on quantity passed
315
-     *
316
-     * @param    EE_Ticket $ticket
317
-     * @param int          $quantity
318
-     * @return bool
319
-     * @throws EE_Error
320
-     */
321
-    protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
322
-    {
323
-        if (self::debug) {
324
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
325
-        }
326
-        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:' . __LINE__);
327
-        return $ticket->save();
328
-    }
329
-
330
-
331
-    /**
332
-     * @param  EE_Ticket $ticket
333
-     * @param  int       $quantity
334
-     * @return bool
335
-     * @throws EE_Error
336
-     */
337
-    protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
338
-    {
339
-        if (self::debug) {
340
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
341
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
342
-        }
343
-        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
344
-        if (self::debug) {
345
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
346
-        }
347
-        return $ticket->save() ? 1 : 0;
348
-    }
349
-
350
-
351
-    /**
352
-     * removes quantities within the ticket selector based on zero ticket availability
353
-     *
354
-     * @param    EE_Ticket $ticket
355
-     * @return    void
356
-     * @throws UnexpectedEntityException
357
-     * @throws EE_Error
358
-     */
359
-    protected function _ticket_sold_out(EE_Ticket $ticket)
360
-    {
361
-        if (self::debug) {
362
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
363
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
364
-        }
365
-        $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
366
-    }
367
-
368
-
369
-    /**
370
-     * adjusts quantities within the ticket selector based on decreased ticket availability
371
-     *
372
-     * @param    EE_Ticket $ticket
373
-     * @return void
374
-     * @throws UnexpectedEntityException
375
-     * @throws EE_Error
376
-     */
377
-    protected function _ticket_quantity_decremented(EE_Ticket $ticket)
378
-    {
379
-        if (self::debug) {
380
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
381
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
382
-        }
383
-        $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
384
-    }
385
-
386
-
387
-    /**
388
-     * builds string out of ticket and event name
389
-     *
390
-     * @param    EE_Ticket $ticket
391
-     * @return string
392
-     * @throws UnexpectedEntityException
393
-     * @throws EE_Error
394
-     */
395
-    protected function _get_ticket_and_event_name(EE_Ticket $ticket)
396
-    {
397
-        $event = $ticket->get_related_event();
398
-        if ($event instanceof EE_Event) {
399
-            $ticket_name = sprintf(
400
-                _x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
401
-                $ticket->name(),
402
-                $event->name()
403
-            );
404
-        } else {
405
-            $ticket_name = $ticket->name();
406
-        }
407
-        return $ticket_name;
408
-    }
409
-
410
-
411
-
412
-    /********************************** EVENT CART  **********************************/
413
-
414
-
415
-    /**
416
-     * releases or reserves ticket(s) based on quantity passed
417
-     *
418
-     * @param  EE_Line_Item $line_item
419
-     * @param  int          $quantity
420
-     * @return void
421
-     * @throws EE_Error
422
-     * @throws InvalidArgumentException
423
-     * @throws InvalidDataTypeException
424
-     * @throws InvalidInterfaceException
425
-     */
426
-    public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
427
-    {
428
-        $ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
429
-        if ($ticket instanceof EE_Ticket) {
430
-            $ticket->add_extra_meta(
431
-                EE_Ticket::META_KEY_TICKET_RESERVATIONS,
432
-                __LINE__ . ') ' . __METHOD__ . '()'
433
-            );
434
-            if ($quantity > 0) {
435
-                EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
436
-            } else {
437
-                EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
438
-            }
439
-        }
440
-    }
441
-
442
-
443
-    /**
444
-     * releases reserved ticket(s) based on quantity passed
445
-     *
446
-     * @param  EE_Ticket $ticket
447
-     * @param  int       $quantity
448
-     * @return void
449
-     * @throws EE_Error
450
-     */
451
-    public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
452
-    {
453
-        $ticket->add_extra_meta(
454
-            EE_Ticket::META_KEY_TICKET_RESERVATIONS,
455
-            __LINE__ . ') ' . __METHOD__ . '()'
456
-        );
457
-        EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
458
-    }
459
-
460
-
461
-
462
-    /********************************** POST_NOTICES  **********************************/
463
-
464
-
465
-    /**
466
-     * @return void
467
-     * @throws EE_Error
468
-     * @throws InvalidArgumentException
469
-     * @throws ReflectionException
470
-     * @throws InvalidDataTypeException
471
-     * @throws InvalidInterfaceException
472
-     */
473
-    public static function post_notices()
474
-    {
475
-        EED_Ticket_Sales_Monitor::instance()->_post_notices();
476
-    }
477
-
478
-
479
-    /**
480
-     * @return void
481
-     * @throws EE_Error
482
-     * @throws InvalidArgumentException
483
-     * @throws ReflectionException
484
-     * @throws InvalidDataTypeException
485
-     * @throws InvalidInterfaceException
486
-     */
487
-    protected function _post_notices()
488
-    {
489
-        if (self::debug) {
490
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
491
-        }
492
-        $refresh_msg = '';
493
-        $none_added_msg = '';
494
-        if (defined('DOING_AJAX') && DOING_AJAX) {
495
-            $refresh_msg = __(
496
-                'Please refresh the page to view updated ticket quantities.',
497
-                'event_espresso'
498
-            );
499
-            $none_added_msg = __('No tickets were added for the event.', 'event_espresso');
500
-        }
501
-        if (! empty($this->sold_out_tickets)) {
502
-            EE_Error::add_attention(
503
-                sprintf(
504
-                    apply_filters(
505
-                        'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
506
-                        __(
507
-                            'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
508
-                            'event_espresso'
509
-                        )
510
-                    ),
511
-                    '<br />',
512
-                    implode('<br />', $this->sold_out_tickets),
513
-                    $none_added_msg,
514
-                    $refresh_msg
515
-                )
516
-            );
517
-            // alter code flow in the Ticket Selector for better UX
518
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
519
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
520
-            $this->sold_out_tickets = array();
521
-            // and reset the cart
522
-            EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523
-        }
524
-        if (! empty($this->decremented_tickets)) {
525
-            EE_Error::add_attention(
526
-                sprintf(
527
-                    apply_filters(
528
-                        'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
529
-                        __(
530
-                            'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
531
-                            'event_espresso'
532
-                        )
533
-                    ),
534
-                    '<br />',
535
-                    implode('<br />', $this->decremented_tickets),
536
-                    $none_added_msg,
537
-                    $refresh_msg
538
-                )
539
-            );
540
-            $this->decremented_tickets = array();
541
-        }
542
-    }
543
-
544
-
545
-
546
-    /********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
547
-
548
-
549
-    /**
550
-     * releases reserved tickets for all registrations of an EE_Transaction
551
-     * by default, will NOT release tickets for finalized transactions
552
-     *
553
-     * @param    EE_Transaction $transaction
554
-     * @return int
555
-     * @throws EE_Error
556
-     * @throws InvalidSessionDataException
557
-     */
558
-    protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
559
-    {
560
-        if (self::debug) {
561
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
562
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
563
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
564
-        }
565
-        // check if 'finalize_registration' step has been completed...
566
-        $finalized = $transaction->reg_step_completed('finalize_registration');
567
-        if (self::debug) {
568
-            // DEBUG LOG
569
-            EEH_Debug_Tools::log(
570
-                __CLASS__,
571
-                __FUNCTION__,
572
-                __LINE__,
573
-                array('finalized' => $finalized),
574
-                false,
575
-                'EE_Transaction: ' . $transaction->ID()
576
-            );
577
-        }
578
-        // how many tickets were released
579
-        $count = 0;
580
-        if (self::debug) {
581
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
582
-        }
583
-        $release_tickets_with_TXN_status = array(
584
-            EEM_Transaction::failed_status_code,
585
-            EEM_Transaction::abandoned_status_code,
586
-            EEM_Transaction::incomplete_status_code,
587
-        );
588
-        $events = array();
589
-        // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
590
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
591
-            // cancel any reserved tickets for registrations that were not approved
592
-            $registrations = $transaction->registrations();
593
-            if (self::debug) {
594
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
595
-                $reg = reset($registrations);
596
-                $ticket = $reg->ticket();
597
-                if ($ticket instanceof EE_Ticket) {
598
-                    $ticket->add_extra_meta(
599
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
600
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
601
-                    );
602
-                }
603
-            }
604
-            if (! empty($registrations)) {
605
-                foreach ($registrations as $registration) {
606
-                    if ($registration instanceof EE_Registration
607
-                        && $this->_release_reserved_ticket_for_registration($registration, $transaction)
608
-                    ) {
609
-                        $count++;
610
-                        $events[ $registration->event_ID() ] = $registration->event();
611
-                    }
612
-                }
613
-            }
614
-        }
615
-        if ($events !== array()) {
616
-            foreach ($events as $event) {
617
-                /** @var EE_Event $event */
618
-                $event->perform_sold_out_status_check();
619
-            }
620
-        }
621
-        return $count;
622
-    }
623
-
624
-
625
-    /**
626
-     * releases reserved tickets for an EE_Registration
627
-     * by default, will NOT release tickets for APPROVED registrations
628
-     *
629
-     * @param EE_Registration $registration
630
-     * @param EE_Transaction  $transaction
631
-     * @return int
632
-     * @throws EE_Error
633
-     */
634
-    protected function _release_reserved_ticket_for_registration(
635
-        EE_Registration $registration,
636
-        EE_Transaction $transaction
637
-    ) {
638
-        $STS_ID = $transaction->status_ID();
639
-        if (self::debug) {
640
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
641
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
642
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
643
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
644
-        }
645
-        if (// release Tickets for Failed Transactions and Abandoned Transactions
646
-            $STS_ID === EEM_Transaction::failed_status_code
647
-            || $STS_ID === EEM_Transaction::abandoned_status_code
648
-            || (
649
-                // also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
650
-                $STS_ID === EEM_Transaction::incomplete_status_code
651
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
652
-            )
653
-        ) {
654
-            if (self::debug) {
655
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
656
-                $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
657
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
658
-                var_dump($rsrvd);
659
-            }
660
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
661
-            return 1;
662
-        }
663
-        return 0;
664
-    }
665
-
666
-
667
-
668
-    /********************************** SESSION_CART_RESET  **********************************/
669
-
670
-
671
-    /**
672
-     * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
673
-     *
674
-     * @param EE_Session $session
675
-     * @return void
676
-     * @throws EE_Error
677
-     * @throws InvalidArgumentException
678
-     * @throws ReflectionException
679
-     * @throws InvalidDataTypeException
680
-     * @throws InvalidInterfaceException
681
-     */
682
-    public static function session_cart_reset(EE_Session $session)
683
-    {
684
-        // don't release tickets if checkout was already reset
685
-        if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
686
-            return;
687
-        }
688
-        if (self::debug) {
689
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
690
-        }
691
-        // first check of the session has a valid Checkout object
692
-        $checkout = $session->checkout();
693
-        if ($checkout instanceof EE_Checkout) {
694
-            // and use that to clear ticket reservations because it will update the associated registration meta data
695
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
696
-            return;
697
-        }
698
-        $cart = $session->cart();
699
-        if ($cart instanceof EE_Cart) {
700
-            if (self::debug) {
701
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
702
-            }
703
-            EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
704
-        } else {
705
-            if (self::debug) {
706
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
707
-                var_export($cart, true);
708
-            }
709
-        }
710
-    }
711
-
712
-
713
-    /**
714
-     * releases reserved tickets in the EE_Cart
715
-     *
716
-     * @param EE_Cart $cart
717
-     * @return void
718
-     * @throws EE_Error
719
-     * @throws InvalidArgumentException
720
-     * @throws ReflectionException
721
-     * @throws InvalidDataTypeException
722
-     * @throws InvalidInterfaceException
723
-     */
724
-    protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
725
-    {
726
-        if (self::debug) {
727
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
728
-        }
729
-        $ticket_line_items = $cart->get_tickets();
730
-        if (empty($ticket_line_items)) {
731
-            return;
732
-        }
733
-        if (self::debug) {
734
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
735
-        }
736
-        foreach ($ticket_line_items as $ticket_line_item) {
737
-            if (self::debug) {
738
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
739
-            }
740
-            if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
741
-                if (self::debug) {
742
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
743
-                }
744
-                $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
745
-                if ($ticket instanceof EE_Ticket) {
746
-                    if (self::debug) {
747
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
748
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
749
-                    }
750
-                    $ticket->add_extra_meta(
751
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
752
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
753
-                    );
754
-                    $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
755
-                }
756
-            }
757
-        }
758
-        if (self::debug) {
759
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
760
-        }
761
-    }
762
-
763
-
764
-
765
-    /********************************** SESSION_CHECKOUT_RESET  **********************************/
766
-
767
-
768
-    /**
769
-     * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
770
-     *
771
-     * @param EE_Session $session
772
-     * @return void
773
-     * @throws EE_Error
774
-     * @throws InvalidSessionDataException
775
-     */
776
-    public static function session_checkout_reset(EE_Session $session)
777
-    {
778
-        // don't release tickets if cart was already reset
779
-        if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
780
-            return;
781
-        }
782
-        $checkout = $session->checkout();
783
-        if ($checkout instanceof EE_Checkout) {
784
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
785
-        }
786
-    }
787
-
788
-
789
-    /**
790
-     * releases reserved tickets for the EE_Checkout->transaction
791
-     *
792
-     * @param EE_Checkout $checkout
793
-     * @return void
794
-     * @throws EE_Error
795
-     * @throws InvalidSessionDataException
796
-     */
797
-    protected function _session_checkout_reset(EE_Checkout $checkout)
798
-    {
799
-        if (self::debug) {
800
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
801
-        }
802
-        // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
803
-        if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
804
-            return;
805
-        }
806
-        $this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
807
-    }
808
-
809
-
810
-
811
-    /********************************** SESSION_EXPIRED_RESET  **********************************/
812
-
813
-
814
-    /**
815
-     * @param    EE_Session $session
816
-     * @return    void
817
-     */
818
-    public static function session_expired_reset(EE_Session $session)
819
-    {
820
-    }
821
-
822
-
823
-
824
-    /********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
825
-
826
-
827
-    /**
828
-     * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
829
-     * by default, will NOT release tickets for free transactions, or any that have received a payment
830
-     *
831
-     * @param EE_Transaction $transaction
832
-     * @return void
833
-     * @throws EE_Error
834
-     * @throws InvalidSessionDataException
835
-     */
836
-    public static function process_abandoned_transactions(EE_Transaction $transaction)
837
-    {
838
-        // is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
839
-        if ($transaction->is_free() || $transaction->paid() > 0) {
840
-            if (self::debug) {
841
-                // DEBUG LOG
842
-                EEH_Debug_Tools::log(
843
-                    __CLASS__,
844
-                    __FUNCTION__,
845
-                    __LINE__,
846
-                    array($transaction),
847
-                    false,
848
-                    'EE_Transaction: ' . $transaction->ID()
849
-                );
850
-            }
851
-            return;
852
-        }
853
-        // have their been any successful payments made ?
854
-        $payments = $transaction->payments();
855
-        foreach ($payments as $payment) {
856
-            if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
857
-                if (self::debug) {
858
-                    // DEBUG LOG
859
-                    EEH_Debug_Tools::log(
860
-                        __CLASS__,
861
-                        __FUNCTION__,
862
-                        __LINE__,
863
-                        array($payment),
864
-                        false,
865
-                        'EE_Transaction: ' . $transaction->ID()
866
-                    );
867
-                }
868
-                return;
869
-            }
870
-        }
871
-        // since you haven't even attempted to pay for your ticket...
872
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
873
-    }
874
-
875
-
876
-
877
-    /********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
878
-
879
-
880
-    /**
881
-     * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
882
-     *
883
-     * @param EE_Transaction $transaction
884
-     * @return void
885
-     * @throws EE_Error
886
-     * @throws InvalidSessionDataException
887
-     */
888
-    public static function process_failed_transactions(EE_Transaction $transaction)
889
-    {
890
-        // since you haven't even attempted to pay for your ticket...
891
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
892
-    }
893
-
894
-
895
-
896
-    /********************************** RESET RESERVATION COUNTS  *********************************/
897
-
898
-
899
-    /**
900
-     * Resets all ticket and datetime reserved counts to zero
901
-     * Tickets that are currently associated with a Transaction that is in progress
902
-     *
903
-     * @throws EE_Error
904
-     * @throws DomainException
905
-     * @throws InvalidDataTypeException
906
-     * @throws InvalidInterfaceException
907
-     * @throws InvalidArgumentException
908
-     * @throws UnexpectedEntityException
909
-     */
910
-    public static function reset_reservation_counts()
911
-    {
912
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
913
-        $valid_reserved_tickets = array();
914
-        /** @var EE_Transaction[] $transactions_not_in_progress */
915
-        $transactions_not_in_progress = EEM_Transaction::instance()->get_transactions_not_in_progress();
916
-        foreach ($transactions_not_in_progress as $transaction) {
917
-            // if this TXN has been fully completed, then skip it
918
-            if ($transaction->reg_step_completed('finalize_registration')) {
919
-                continue;
920
-            }
921
-            $total_line_item = $transaction->total_line_item();
922
-            // $transaction_in_progress->line
923
-            if (! $total_line_item instanceof EE_Line_Item) {
924
-                throw new DomainException(
925
-                    esc_html__(
926
-                        'Transaction does not have a valid Total Line Item associated with it.',
927
-                        'event_espresso'
928
-                    )
929
-                );
930
-            }
931
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
932
-                $total_line_item
933
-            );
934
-        }
935
-        $total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
936
-        foreach ($total_line_items as $total_line_item) {
937
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
938
-                $total_line_item
939
-            );
940
-        }
941
-        $tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
942
-        return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
943
-            $tickets_with_reservations,
944
-            $valid_reserved_tickets,
945
-            __FUNCTION__
946
-        );
947
-    }
948
-
949
-
950
-    /**
951
-     * @param EE_Line_Item $total_line_item
952
-     * @return EE_Line_Item[]
953
-     */
954
-    private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
955
-    {
956
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
957
-        $valid_reserved_tickets = array();
958
-        $ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
959
-        foreach ($ticket_line_items as $ticket_line_item) {
960
-            if ($ticket_line_item instanceof EE_Line_Item) {
961
-                $valid_reserved_tickets[] = $ticket_line_item;
962
-            }
963
-        }
964
-        return $valid_reserved_tickets;
965
-    }
966
-
967
-
968
-    /**
969
-     * @param EE_Ticket[]    $tickets_with_reservations
970
-     * @param EE_Line_Item[] $valid_reserved_ticket_line_items
971
-     * @return int
972
-     * @throws UnexpectedEntityException
973
-     * @throws DomainException
974
-     * @throws EE_Error
975
-     */
976
-    private static function release_reservations_for_tickets(
977
-        array $tickets_with_reservations,
978
-        array $valid_reserved_ticket_line_items = array(),
979
-        $source
980
-    ) {
981
-        if (self::debug) {
982
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
983
-        }
984
-        $total_tickets_released = 0;
985
-        $sold_out_events = array();
986
-        foreach ($tickets_with_reservations as $ticket_with_reservations) {
987
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
988
-                continue;
989
-            }
990
-            $reserved_qty = $ticket_with_reservations->reserved();
991
-            if (self::debug) {
992
-                echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
993
-                echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
994
-            }
995
-            foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
996
-                if ($valid_reserved_ticket_line_item instanceof EE_Line_Item
997
-                    && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
998
-                ) {
999
-                    if (self::debug) {
1000
-                        echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): '
1001
-                             . $valid_reserved_ticket_line_item->quantity();
1002
-                    }
1003
-                    $reserved_qty -= $valid_reserved_ticket_line_item->quantity();
1004
-                }
1005
-            }
1006
-            if ($reserved_qty > 0) {
1007
-                $ticket_with_reservations->add_extra_meta(
1008
-                    EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1009
-                    __LINE__ . ') ' . $source . '()'
1010
-                );
1011
-                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:' . __LINE__);
1012
-                $ticket_with_reservations->save();
1013
-                $total_tickets_released += $reserved_qty;
1014
-                $event = $ticket_with_reservations->get_related_event();
1015
-                // track sold out events
1016
-                if ($event instanceof EE_Event && $event->is_sold_out()) {
1017
-                    $sold_out_events[] = $event;
1018
-                }
1019
-            }
1020
-        }
1021
-        if (self::debug) {
1022
-            echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1023
-        }
1024
-        // double check whether sold out events should remain sold out after releasing tickets
1025
-        if ($sold_out_events !== array()) {
1026
-            foreach ($sold_out_events as $sold_out_event) {
1027
-                /** @var EE_Event $sold_out_event */
1028
-                $sold_out_event->perform_sold_out_status_check();
1029
-            }
1030
-        }
1031
-        return $total_tickets_released;
1032
-    }
1033
-
1034
-
1035
-
1036
-    /********************************** SHUTDOWN  **********************************/
1037
-
1038
-
1039
-    /**
1040
-     * @param int $timestamp
1041
-     * @return false|int
1042
-     * @throws EE_Error
1043
-     * @throws InvalidArgumentException
1044
-     * @throws InvalidDataTypeException
1045
-     * @throws InvalidInterfaceException
1046
-     */
1047
-    public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1048
-    {
1049
-        /** @type WPDB $wpdb */
1050
-        global $wpdb;
1051
-        if (! absint($timestamp)) {
1052
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1053
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
1054
-                'EventEspresso\core\domain\values\session\SessionLifespan'
1055
-            );
1056
-            $timestamp = $session_lifespan->expiration();
1057
-        }
1058
-        return $wpdb->query(
1059
-            $wpdb->prepare(
1060
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
23
+	const debug = false;
24
+
25
+	private static $nl = '';
26
+
27
+	/**
28
+	 * an array of raw ticket data from EED_Ticket_Selector
29
+	 *
30
+	 * @var array $ticket_selections
31
+	 */
32
+	protected $ticket_selections = array();
33
+
34
+	/**
35
+	 * the raw ticket data from EED_Ticket_Selector is organized in rows
36
+	 * according to how they are displayed in the actual Ticket_Selector
37
+	 * this tracks the current row being processed
38
+	 *
39
+	 * @var int $current_row
40
+	 */
41
+	protected $current_row = 0;
42
+
43
+	/**
44
+	 * an array for tracking names of tickets that have sold out
45
+	 *
46
+	 * @var array $sold_out_tickets
47
+	 */
48
+	protected $sold_out_tickets = array();
49
+
50
+	/**
51
+	 * an array for tracking names of tickets that have had their quantities reduced
52
+	 *
53
+	 * @var array $decremented_tickets
54
+	 */
55
+	protected $decremented_tickets = array();
56
+
57
+
58
+	/**
59
+	 * set_hooks - for hooking into EE Core, other modules, etc
60
+	 *
61
+	 * @return    void
62
+	 */
63
+	public static function set_hooks()
64
+	{
65
+		self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
66
+		// release tickets for expired carts
67
+		add_action(
68
+			'EED_Ticket_Selector__process_ticket_selections__before',
69
+			array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
70
+			1
71
+		);
72
+		// check ticket reserves AFTER MER does it's check (hence priority 20)
73
+		add_filter(
74
+			'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
75
+			array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
76
+			20,
77
+			3
78
+		);
79
+		// add notices for sold out tickets
80
+		add_action(
81
+			'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
82
+			array('EED_Ticket_Sales_Monitor', 'post_notices'),
83
+			10
84
+		);
85
+
86
+		// handle tickets deleted from cart
87
+		add_action(
88
+			'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
89
+			array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
90
+			10,
91
+			2
92
+		);
93
+		// handle emptied carts
94
+		add_action(
95
+			'AHEE__EE_Session__reset_cart__before_reset',
96
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
97
+			10,
98
+			1
99
+		);
100
+		add_action(
101
+			'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
102
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
103
+			10,
104
+			1
105
+		);
106
+		// handle cancelled registrations
107
+		add_action(
108
+			'AHEE__EE_Session__reset_checkout__before_reset',
109
+			array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
110
+			10,
111
+			1
112
+		);
113
+		// cron tasks
114
+		add_action(
115
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
116
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
117
+			10,
118
+			1
119
+		);
120
+		add_action(
121
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
122
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
123
+			10,
124
+			1
125
+		);
126
+		add_action(
127
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
128
+			array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
129
+			10,
130
+			1
131
+		);
132
+	}
133
+
134
+
135
+	/**
136
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
137
+	 *
138
+	 * @return void
139
+	 */
140
+	public static function set_hooks_admin()
141
+	{
142
+		EED_Ticket_Sales_Monitor::set_hooks();
143
+	}
144
+
145
+
146
+	/**
147
+	 * @return EED_Ticket_Sales_Monitor|EED_Module
148
+	 */
149
+	public static function instance()
150
+	{
151
+		return parent::get_instance(__CLASS__);
152
+	}
153
+
154
+
155
+	/**
156
+	 * @param WP_Query $WP_Query
157
+	 * @return    void
158
+	 */
159
+	public function run($WP_Query)
160
+	{
161
+	}
162
+
163
+
164
+
165
+	/********************************** PRE_TICKET_SALES  **********************************/
166
+
167
+
168
+	/**
169
+	 * Retrieves grand totals from the line items that have no TXN ID
170
+	 * and timestamps less than the current time minus the session lifespan.
171
+	 * These are carts that have been abandoned before the "registrant" even attempted to checkout.
172
+	 * We're going to release the tickets for these line items before attempting to add more to the cart.
173
+	 *
174
+	 * @return void
175
+	 * @throws DomainException
176
+	 * @throws EE_Error
177
+	 * @throws InvalidArgumentException
178
+	 * @throws InvalidDataTypeException
179
+	 * @throws InvalidInterfaceException
180
+	 * @throws UnexpectedEntityException
181
+	 */
182
+	public static function release_tickets_for_expired_carts()
183
+	{
184
+		if (self::debug) {
185
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
186
+		}
187
+		do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
188
+		$expired_ticket_IDs = array();
189
+		/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
190
+		$session_lifespan = LoaderFactory::getLoader()->getShared(
191
+			'EventEspresso\core\domain\values\session\SessionLifespan'
192
+		);
193
+		$timestamp = $session_lifespan->expiration();
194
+		$expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
195
+		if (self::debug) {
196
+			echo self::$nl . ' . time(): ' . time();
197
+			echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
198
+			echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
199
+			echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
200
+			echo self::$nl . ' . timestamp: ' . $timestamp;
201
+			echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
202
+		}
203
+		if (! empty($expired_ticket_line_items)) {
204
+			foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
205
+				if (! $expired_ticket_line_item instanceof EE_Line_Item) {
206
+					continue;
207
+				}
208
+				$expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
209
+				if (self::debug) {
210
+					echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
211
+					echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
212
+						 . date(
213
+							 'Y-m-d h:i a',
214
+							 $expired_ticket_line_item->timestamp(true)
215
+						 );
216
+				}
217
+			}
218
+			if (! empty($expired_ticket_IDs)) {
219
+				EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
220
+					\EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
221
+					array(),
222
+					__FUNCTION__
223
+				);
224
+				// now  let's get rid of expired line items so that they can't interfere with tracking
225
+				EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
226
+			}
227
+		}
228
+		do_action(
229
+			'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
230
+			$expired_ticket_IDs,
231
+			$expired_ticket_line_items
232
+		);
233
+	}
234
+
235
+
236
+
237
+	/********************************** VALIDATE_TICKET_SALE  **********************************/
238
+
239
+
240
+	/**
241
+	 * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
242
+	 *
243
+	 * @param int       $qty
244
+	 * @param EE_Ticket $ticket
245
+	 * @return bool
246
+	 * @throws UnexpectedEntityException
247
+	 * @throws EE_Error
248
+	 */
249
+	public static function validate_ticket_sale($qty = 1, EE_Ticket $ticket)
250
+	{
251
+		$qty = absint($qty);
252
+		if ($qty > 0) {
253
+			$qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
254
+		}
255
+		if (self::debug) {
256
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
257
+			echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
258
+		}
259
+		return $qty;
260
+	}
261
+
262
+
263
+	/**
264
+	 * checks whether an individual ticket is available for purchase based on datetime, and ticket details
265
+	 *
266
+	 * @param   EE_Ticket $ticket
267
+	 * @param int         $qty
268
+	 * @return int
269
+	 * @throws UnexpectedEntityException
270
+	 * @throws EE_Error
271
+	 */
272
+	protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
273
+	{
274
+		if (self::debug) {
275
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
276
+		}
277
+		if (! $ticket instanceof EE_Ticket) {
278
+			return 0;
279
+		}
280
+		if (self::debug) {
281
+			echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
282
+			echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
283
+		}
284
+		$ticket->refresh_from_db();
285
+		// first let's determine the ticket availability based on sales
286
+		$available = $ticket->qty('saleable');
287
+		if (self::debug) {
288
+			echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
289
+			echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
290
+			echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
291
+			echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
292
+			echo self::$nl . ' . . . available: ' . $available;
293
+		}
294
+		if ($available < 1) {
295
+			$this->_ticket_sold_out($ticket);
296
+			return 0;
297
+		}
298
+		if (self::debug) {
299
+			echo self::$nl . ' . . . qty: ' . $qty;
300
+		}
301
+		if ($available < $qty) {
302
+			$qty = $available;
303
+			if (self::debug) {
304
+				echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
305
+			}
306
+			$this->_ticket_quantity_decremented($ticket);
307
+		}
308
+		$this->_reserve_ticket($ticket, $qty);
309
+		return $qty;
310
+	}
311
+
312
+
313
+	/**
314
+	 * increments ticket reserved based on quantity passed
315
+	 *
316
+	 * @param    EE_Ticket $ticket
317
+	 * @param int          $quantity
318
+	 * @return bool
319
+	 * @throws EE_Error
320
+	 */
321
+	protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
322
+	{
323
+		if (self::debug) {
324
+			echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
325
+		}
326
+		$ticket->increase_reserved($quantity, 'TicketSalesMonitor:' . __LINE__);
327
+		return $ticket->save();
328
+	}
329
+
330
+
331
+	/**
332
+	 * @param  EE_Ticket $ticket
333
+	 * @param  int       $quantity
334
+	 * @return bool
335
+	 * @throws EE_Error
336
+	 */
337
+	protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
338
+	{
339
+		if (self::debug) {
340
+			echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
341
+			echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
342
+		}
343
+		$ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
344
+		if (self::debug) {
345
+			echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
346
+		}
347
+		return $ticket->save() ? 1 : 0;
348
+	}
349
+
350
+
351
+	/**
352
+	 * removes quantities within the ticket selector based on zero ticket availability
353
+	 *
354
+	 * @param    EE_Ticket $ticket
355
+	 * @return    void
356
+	 * @throws UnexpectedEntityException
357
+	 * @throws EE_Error
358
+	 */
359
+	protected function _ticket_sold_out(EE_Ticket $ticket)
360
+	{
361
+		if (self::debug) {
362
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
363
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
364
+		}
365
+		$this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
366
+	}
367
+
368
+
369
+	/**
370
+	 * adjusts quantities within the ticket selector based on decreased ticket availability
371
+	 *
372
+	 * @param    EE_Ticket $ticket
373
+	 * @return void
374
+	 * @throws UnexpectedEntityException
375
+	 * @throws EE_Error
376
+	 */
377
+	protected function _ticket_quantity_decremented(EE_Ticket $ticket)
378
+	{
379
+		if (self::debug) {
380
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
381
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
382
+		}
383
+		$this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
384
+	}
385
+
386
+
387
+	/**
388
+	 * builds string out of ticket and event name
389
+	 *
390
+	 * @param    EE_Ticket $ticket
391
+	 * @return string
392
+	 * @throws UnexpectedEntityException
393
+	 * @throws EE_Error
394
+	 */
395
+	protected function _get_ticket_and_event_name(EE_Ticket $ticket)
396
+	{
397
+		$event = $ticket->get_related_event();
398
+		if ($event instanceof EE_Event) {
399
+			$ticket_name = sprintf(
400
+				_x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
401
+				$ticket->name(),
402
+				$event->name()
403
+			);
404
+		} else {
405
+			$ticket_name = $ticket->name();
406
+		}
407
+		return $ticket_name;
408
+	}
409
+
410
+
411
+
412
+	/********************************** EVENT CART  **********************************/
413
+
414
+
415
+	/**
416
+	 * releases or reserves ticket(s) based on quantity passed
417
+	 *
418
+	 * @param  EE_Line_Item $line_item
419
+	 * @param  int          $quantity
420
+	 * @return void
421
+	 * @throws EE_Error
422
+	 * @throws InvalidArgumentException
423
+	 * @throws InvalidDataTypeException
424
+	 * @throws InvalidInterfaceException
425
+	 */
426
+	public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
427
+	{
428
+		$ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
429
+		if ($ticket instanceof EE_Ticket) {
430
+			$ticket->add_extra_meta(
431
+				EE_Ticket::META_KEY_TICKET_RESERVATIONS,
432
+				__LINE__ . ') ' . __METHOD__ . '()'
433
+			);
434
+			if ($quantity > 0) {
435
+				EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
436
+			} else {
437
+				EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
438
+			}
439
+		}
440
+	}
441
+
442
+
443
+	/**
444
+	 * releases reserved ticket(s) based on quantity passed
445
+	 *
446
+	 * @param  EE_Ticket $ticket
447
+	 * @param  int       $quantity
448
+	 * @return void
449
+	 * @throws EE_Error
450
+	 */
451
+	public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
452
+	{
453
+		$ticket->add_extra_meta(
454
+			EE_Ticket::META_KEY_TICKET_RESERVATIONS,
455
+			__LINE__ . ') ' . __METHOD__ . '()'
456
+		);
457
+		EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
458
+	}
459
+
460
+
461
+
462
+	/********************************** POST_NOTICES  **********************************/
463
+
464
+
465
+	/**
466
+	 * @return void
467
+	 * @throws EE_Error
468
+	 * @throws InvalidArgumentException
469
+	 * @throws ReflectionException
470
+	 * @throws InvalidDataTypeException
471
+	 * @throws InvalidInterfaceException
472
+	 */
473
+	public static function post_notices()
474
+	{
475
+		EED_Ticket_Sales_Monitor::instance()->_post_notices();
476
+	}
477
+
478
+
479
+	/**
480
+	 * @return void
481
+	 * @throws EE_Error
482
+	 * @throws InvalidArgumentException
483
+	 * @throws ReflectionException
484
+	 * @throws InvalidDataTypeException
485
+	 * @throws InvalidInterfaceException
486
+	 */
487
+	protected function _post_notices()
488
+	{
489
+		if (self::debug) {
490
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
491
+		}
492
+		$refresh_msg = '';
493
+		$none_added_msg = '';
494
+		if (defined('DOING_AJAX') && DOING_AJAX) {
495
+			$refresh_msg = __(
496
+				'Please refresh the page to view updated ticket quantities.',
497
+				'event_espresso'
498
+			);
499
+			$none_added_msg = __('No tickets were added for the event.', 'event_espresso');
500
+		}
501
+		if (! empty($this->sold_out_tickets)) {
502
+			EE_Error::add_attention(
503
+				sprintf(
504
+					apply_filters(
505
+						'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
506
+						__(
507
+							'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
508
+							'event_espresso'
509
+						)
510
+					),
511
+					'<br />',
512
+					implode('<br />', $this->sold_out_tickets),
513
+					$none_added_msg,
514
+					$refresh_msg
515
+				)
516
+			);
517
+			// alter code flow in the Ticket Selector for better UX
518
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
519
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
520
+			$this->sold_out_tickets = array();
521
+			// and reset the cart
522
+			EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523
+		}
524
+		if (! empty($this->decremented_tickets)) {
525
+			EE_Error::add_attention(
526
+				sprintf(
527
+					apply_filters(
528
+						'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
529
+						__(
530
+							'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
531
+							'event_espresso'
532
+						)
533
+					),
534
+					'<br />',
535
+					implode('<br />', $this->decremented_tickets),
536
+					$none_added_msg,
537
+					$refresh_msg
538
+				)
539
+			);
540
+			$this->decremented_tickets = array();
541
+		}
542
+	}
543
+
544
+
545
+
546
+	/********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
547
+
548
+
549
+	/**
550
+	 * releases reserved tickets for all registrations of an EE_Transaction
551
+	 * by default, will NOT release tickets for finalized transactions
552
+	 *
553
+	 * @param    EE_Transaction $transaction
554
+	 * @return int
555
+	 * @throws EE_Error
556
+	 * @throws InvalidSessionDataException
557
+	 */
558
+	protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
559
+	{
560
+		if (self::debug) {
561
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
562
+			echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
563
+			echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
564
+		}
565
+		// check if 'finalize_registration' step has been completed...
566
+		$finalized = $transaction->reg_step_completed('finalize_registration');
567
+		if (self::debug) {
568
+			// DEBUG LOG
569
+			EEH_Debug_Tools::log(
570
+				__CLASS__,
571
+				__FUNCTION__,
572
+				__LINE__,
573
+				array('finalized' => $finalized),
574
+				false,
575
+				'EE_Transaction: ' . $transaction->ID()
576
+			);
577
+		}
578
+		// how many tickets were released
579
+		$count = 0;
580
+		if (self::debug) {
581
+			echo self::$nl . ' . . . TXN finalized: ' . $finalized;
582
+		}
583
+		$release_tickets_with_TXN_status = array(
584
+			EEM_Transaction::failed_status_code,
585
+			EEM_Transaction::abandoned_status_code,
586
+			EEM_Transaction::incomplete_status_code,
587
+		);
588
+		$events = array();
589
+		// if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
590
+		if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
591
+			// cancel any reserved tickets for registrations that were not approved
592
+			$registrations = $transaction->registrations();
593
+			if (self::debug) {
594
+				echo self::$nl . ' . . . # registrations: ' . count($registrations);
595
+				$reg = reset($registrations);
596
+				$ticket = $reg->ticket();
597
+				if ($ticket instanceof EE_Ticket) {
598
+					$ticket->add_extra_meta(
599
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
600
+						__LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
601
+					);
602
+				}
603
+			}
604
+			if (! empty($registrations)) {
605
+				foreach ($registrations as $registration) {
606
+					if ($registration instanceof EE_Registration
607
+						&& $this->_release_reserved_ticket_for_registration($registration, $transaction)
608
+					) {
609
+						$count++;
610
+						$events[ $registration->event_ID() ] = $registration->event();
611
+					}
612
+				}
613
+			}
614
+		}
615
+		if ($events !== array()) {
616
+			foreach ($events as $event) {
617
+				/** @var EE_Event $event */
618
+				$event->perform_sold_out_status_check();
619
+			}
620
+		}
621
+		return $count;
622
+	}
623
+
624
+
625
+	/**
626
+	 * releases reserved tickets for an EE_Registration
627
+	 * by default, will NOT release tickets for APPROVED registrations
628
+	 *
629
+	 * @param EE_Registration $registration
630
+	 * @param EE_Transaction  $transaction
631
+	 * @return int
632
+	 * @throws EE_Error
633
+	 */
634
+	protected function _release_reserved_ticket_for_registration(
635
+		EE_Registration $registration,
636
+		EE_Transaction $transaction
637
+	) {
638
+		$STS_ID = $transaction->status_ID();
639
+		if (self::debug) {
640
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
641
+			echo self::$nl . ' . . registration->ID: ' . $registration->ID();
642
+			echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
643
+			echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
644
+		}
645
+		if (// release Tickets for Failed Transactions and Abandoned Transactions
646
+			$STS_ID === EEM_Transaction::failed_status_code
647
+			|| $STS_ID === EEM_Transaction::abandoned_status_code
648
+			|| (
649
+				// also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
650
+				$STS_ID === EEM_Transaction::incomplete_status_code
651
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
652
+			)
653
+		) {
654
+			if (self::debug) {
655
+				echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
656
+				$rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
657
+				echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
658
+				var_dump($rsrvd);
659
+			}
660
+			$registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
661
+			return 1;
662
+		}
663
+		return 0;
664
+	}
665
+
666
+
667
+
668
+	/********************************** SESSION_CART_RESET  **********************************/
669
+
670
+
671
+	/**
672
+	 * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
673
+	 *
674
+	 * @param EE_Session $session
675
+	 * @return void
676
+	 * @throws EE_Error
677
+	 * @throws InvalidArgumentException
678
+	 * @throws ReflectionException
679
+	 * @throws InvalidDataTypeException
680
+	 * @throws InvalidInterfaceException
681
+	 */
682
+	public static function session_cart_reset(EE_Session $session)
683
+	{
684
+		// don't release tickets if checkout was already reset
685
+		if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
686
+			return;
687
+		}
688
+		if (self::debug) {
689
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
690
+		}
691
+		// first check of the session has a valid Checkout object
692
+		$checkout = $session->checkout();
693
+		if ($checkout instanceof EE_Checkout) {
694
+			// and use that to clear ticket reservations because it will update the associated registration meta data
695
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
696
+			return;
697
+		}
698
+		$cart = $session->cart();
699
+		if ($cart instanceof EE_Cart) {
700
+			if (self::debug) {
701
+				echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
702
+			}
703
+			EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
704
+		} else {
705
+			if (self::debug) {
706
+				echo self::$nl . self::$nl . ' invalid EE_Cart: ';
707
+				var_export($cart, true);
708
+			}
709
+		}
710
+	}
711
+
712
+
713
+	/**
714
+	 * releases reserved tickets in the EE_Cart
715
+	 *
716
+	 * @param EE_Cart $cart
717
+	 * @return void
718
+	 * @throws EE_Error
719
+	 * @throws InvalidArgumentException
720
+	 * @throws ReflectionException
721
+	 * @throws InvalidDataTypeException
722
+	 * @throws InvalidInterfaceException
723
+	 */
724
+	protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
725
+	{
726
+		if (self::debug) {
727
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
728
+		}
729
+		$ticket_line_items = $cart->get_tickets();
730
+		if (empty($ticket_line_items)) {
731
+			return;
732
+		}
733
+		if (self::debug) {
734
+			echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
735
+		}
736
+		foreach ($ticket_line_items as $ticket_line_item) {
737
+			if (self::debug) {
738
+				echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
739
+			}
740
+			if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
741
+				if (self::debug) {
742
+					echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
743
+				}
744
+				$ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
745
+				if ($ticket instanceof EE_Ticket) {
746
+					if (self::debug) {
747
+						echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
748
+						echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
749
+					}
750
+					$ticket->add_extra_meta(
751
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
752
+						__LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
753
+					);
754
+					$this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
755
+				}
756
+			}
757
+		}
758
+		if (self::debug) {
759
+			echo self::$nl . self::$nl . ' RESET COMPLETED ';
760
+		}
761
+	}
762
+
763
+
764
+
765
+	/********************************** SESSION_CHECKOUT_RESET  **********************************/
766
+
767
+
768
+	/**
769
+	 * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
770
+	 *
771
+	 * @param EE_Session $session
772
+	 * @return void
773
+	 * @throws EE_Error
774
+	 * @throws InvalidSessionDataException
775
+	 */
776
+	public static function session_checkout_reset(EE_Session $session)
777
+	{
778
+		// don't release tickets if cart was already reset
779
+		if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
780
+			return;
781
+		}
782
+		$checkout = $session->checkout();
783
+		if ($checkout instanceof EE_Checkout) {
784
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
785
+		}
786
+	}
787
+
788
+
789
+	/**
790
+	 * releases reserved tickets for the EE_Checkout->transaction
791
+	 *
792
+	 * @param EE_Checkout $checkout
793
+	 * @return void
794
+	 * @throws EE_Error
795
+	 * @throws InvalidSessionDataException
796
+	 */
797
+	protected function _session_checkout_reset(EE_Checkout $checkout)
798
+	{
799
+		if (self::debug) {
800
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
801
+		}
802
+		// we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
803
+		if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
804
+			return;
805
+		}
806
+		$this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
807
+	}
808
+
809
+
810
+
811
+	/********************************** SESSION_EXPIRED_RESET  **********************************/
812
+
813
+
814
+	/**
815
+	 * @param    EE_Session $session
816
+	 * @return    void
817
+	 */
818
+	public static function session_expired_reset(EE_Session $session)
819
+	{
820
+	}
821
+
822
+
823
+
824
+	/********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
825
+
826
+
827
+	/**
828
+	 * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
829
+	 * by default, will NOT release tickets for free transactions, or any that have received a payment
830
+	 *
831
+	 * @param EE_Transaction $transaction
832
+	 * @return void
833
+	 * @throws EE_Error
834
+	 * @throws InvalidSessionDataException
835
+	 */
836
+	public static function process_abandoned_transactions(EE_Transaction $transaction)
837
+	{
838
+		// is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
839
+		if ($transaction->is_free() || $transaction->paid() > 0) {
840
+			if (self::debug) {
841
+				// DEBUG LOG
842
+				EEH_Debug_Tools::log(
843
+					__CLASS__,
844
+					__FUNCTION__,
845
+					__LINE__,
846
+					array($transaction),
847
+					false,
848
+					'EE_Transaction: ' . $transaction->ID()
849
+				);
850
+			}
851
+			return;
852
+		}
853
+		// have their been any successful payments made ?
854
+		$payments = $transaction->payments();
855
+		foreach ($payments as $payment) {
856
+			if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
857
+				if (self::debug) {
858
+					// DEBUG LOG
859
+					EEH_Debug_Tools::log(
860
+						__CLASS__,
861
+						__FUNCTION__,
862
+						__LINE__,
863
+						array($payment),
864
+						false,
865
+						'EE_Transaction: ' . $transaction->ID()
866
+					);
867
+				}
868
+				return;
869
+			}
870
+		}
871
+		// since you haven't even attempted to pay for your ticket...
872
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
873
+	}
874
+
875
+
876
+
877
+	/********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
878
+
879
+
880
+	/**
881
+	 * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
882
+	 *
883
+	 * @param EE_Transaction $transaction
884
+	 * @return void
885
+	 * @throws EE_Error
886
+	 * @throws InvalidSessionDataException
887
+	 */
888
+	public static function process_failed_transactions(EE_Transaction $transaction)
889
+	{
890
+		// since you haven't even attempted to pay for your ticket...
891
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
892
+	}
893
+
894
+
895
+
896
+	/********************************** RESET RESERVATION COUNTS  *********************************/
897
+
898
+
899
+	/**
900
+	 * Resets all ticket and datetime reserved counts to zero
901
+	 * Tickets that are currently associated with a Transaction that is in progress
902
+	 *
903
+	 * @throws EE_Error
904
+	 * @throws DomainException
905
+	 * @throws InvalidDataTypeException
906
+	 * @throws InvalidInterfaceException
907
+	 * @throws InvalidArgumentException
908
+	 * @throws UnexpectedEntityException
909
+	 */
910
+	public static function reset_reservation_counts()
911
+	{
912
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
913
+		$valid_reserved_tickets = array();
914
+		/** @var EE_Transaction[] $transactions_not_in_progress */
915
+		$transactions_not_in_progress = EEM_Transaction::instance()->get_transactions_not_in_progress();
916
+		foreach ($transactions_not_in_progress as $transaction) {
917
+			// if this TXN has been fully completed, then skip it
918
+			if ($transaction->reg_step_completed('finalize_registration')) {
919
+				continue;
920
+			}
921
+			$total_line_item = $transaction->total_line_item();
922
+			// $transaction_in_progress->line
923
+			if (! $total_line_item instanceof EE_Line_Item) {
924
+				throw new DomainException(
925
+					esc_html__(
926
+						'Transaction does not have a valid Total Line Item associated with it.',
927
+						'event_espresso'
928
+					)
929
+				);
930
+			}
931
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
932
+				$total_line_item
933
+			);
934
+		}
935
+		$total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
936
+		foreach ($total_line_items as $total_line_item) {
937
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
938
+				$total_line_item
939
+			);
940
+		}
941
+		$tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
942
+		return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
943
+			$tickets_with_reservations,
944
+			$valid_reserved_tickets,
945
+			__FUNCTION__
946
+		);
947
+	}
948
+
949
+
950
+	/**
951
+	 * @param EE_Line_Item $total_line_item
952
+	 * @return EE_Line_Item[]
953
+	 */
954
+	private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
955
+	{
956
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
957
+		$valid_reserved_tickets = array();
958
+		$ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
959
+		foreach ($ticket_line_items as $ticket_line_item) {
960
+			if ($ticket_line_item instanceof EE_Line_Item) {
961
+				$valid_reserved_tickets[] = $ticket_line_item;
962
+			}
963
+		}
964
+		return $valid_reserved_tickets;
965
+	}
966
+
967
+
968
+	/**
969
+	 * @param EE_Ticket[]    $tickets_with_reservations
970
+	 * @param EE_Line_Item[] $valid_reserved_ticket_line_items
971
+	 * @return int
972
+	 * @throws UnexpectedEntityException
973
+	 * @throws DomainException
974
+	 * @throws EE_Error
975
+	 */
976
+	private static function release_reservations_for_tickets(
977
+		array $tickets_with_reservations,
978
+		array $valid_reserved_ticket_line_items = array(),
979
+		$source
980
+	) {
981
+		if (self::debug) {
982
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
983
+		}
984
+		$total_tickets_released = 0;
985
+		$sold_out_events = array();
986
+		foreach ($tickets_with_reservations as $ticket_with_reservations) {
987
+			if (! $ticket_with_reservations instanceof EE_Ticket) {
988
+				continue;
989
+			}
990
+			$reserved_qty = $ticket_with_reservations->reserved();
991
+			if (self::debug) {
992
+				echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
993
+				echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
994
+			}
995
+			foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
996
+				if ($valid_reserved_ticket_line_item instanceof EE_Line_Item
997
+					&& $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
998
+				) {
999
+					if (self::debug) {
1000
+						echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): '
1001
+							 . $valid_reserved_ticket_line_item->quantity();
1002
+					}
1003
+					$reserved_qty -= $valid_reserved_ticket_line_item->quantity();
1004
+				}
1005
+			}
1006
+			if ($reserved_qty > 0) {
1007
+				$ticket_with_reservations->add_extra_meta(
1008
+					EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1009
+					__LINE__ . ') ' . $source . '()'
1010
+				);
1011
+				$ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:' . __LINE__);
1012
+				$ticket_with_reservations->save();
1013
+				$total_tickets_released += $reserved_qty;
1014
+				$event = $ticket_with_reservations->get_related_event();
1015
+				// track sold out events
1016
+				if ($event instanceof EE_Event && $event->is_sold_out()) {
1017
+					$sold_out_events[] = $event;
1018
+				}
1019
+			}
1020
+		}
1021
+		if (self::debug) {
1022
+			echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1023
+		}
1024
+		// double check whether sold out events should remain sold out after releasing tickets
1025
+		if ($sold_out_events !== array()) {
1026
+			foreach ($sold_out_events as $sold_out_event) {
1027
+				/** @var EE_Event $sold_out_event */
1028
+				$sold_out_event->perform_sold_out_status_check();
1029
+			}
1030
+		}
1031
+		return $total_tickets_released;
1032
+	}
1033
+
1034
+
1035
+
1036
+	/********************************** SHUTDOWN  **********************************/
1037
+
1038
+
1039
+	/**
1040
+	 * @param int $timestamp
1041
+	 * @return false|int
1042
+	 * @throws EE_Error
1043
+	 * @throws InvalidArgumentException
1044
+	 * @throws InvalidDataTypeException
1045
+	 * @throws InvalidInterfaceException
1046
+	 */
1047
+	public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1048
+	{
1049
+		/** @type WPDB $wpdb */
1050
+		global $wpdb;
1051
+		if (! absint($timestamp)) {
1052
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1053
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
1054
+				'EventEspresso\core\domain\values\session\SessionLifespan'
1055
+			);
1056
+			$timestamp = $session_lifespan->expiration();
1057
+		}
1058
+		return $wpdb->query(
1059
+			$wpdb->prepare(
1060
+				'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1061 1061
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1062
-                // use GMT time because that's what LIN_timestamps are in
1063
-                date('Y-m-d H:i:s', $timestamp)
1064
-            )
1065
-        );
1066
-    }
1062
+				// use GMT time because that's what LIN_timestamps are in
1063
+				date('Y-m-d H:i:s', $timestamp)
1064
+			)
1065
+		);
1066
+	}
1067 1067
 }
Please login to merge, or discard this patch.
Spacing   +83 added lines, -83 removed lines patch added patch discarded remove patch
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
     public static function release_tickets_for_expired_carts()
183 183
     {
184 184
         if (self::debug) {
185
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
185
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
186 186
         }
187 187
         do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
188 188
         $expired_ticket_IDs = array();
@@ -193,29 +193,29 @@  discard block
 block discarded – undo
193 193
         $timestamp = $session_lifespan->expiration();
194 194
         $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
195 195
         if (self::debug) {
196
-            echo self::$nl . ' . time(): ' . time();
197
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
198
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
199
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
200
-            echo self::$nl . ' . timestamp: ' . $timestamp;
201
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
196
+            echo self::$nl.' . time(): '.time();
197
+            echo self::$nl.' . time() as date: '.date('Y-m-d H:i a');
198
+            echo self::$nl.' . session expiration: '.$session_lifespan->expiration();
199
+            echo self::$nl.' . session expiration as date: '.date('Y-m-d H:i a', $session_lifespan->expiration());
200
+            echo self::$nl.' . timestamp: '.$timestamp;
201
+            echo self::$nl.' . $expired_ticket_line_items: '.count($expired_ticket_line_items);
202 202
         }
203
-        if (! empty($expired_ticket_line_items)) {
203
+        if ( ! empty($expired_ticket_line_items)) {
204 204
             foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
205
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
205
+                if ( ! $expired_ticket_line_item instanceof EE_Line_Item) {
206 206
                     continue;
207 207
                 }
208
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
208
+                $expired_ticket_IDs[$expired_ticket_line_item->OBJ_ID()] = $expired_ticket_line_item->OBJ_ID();
209 209
                 if (self::debug) {
210
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
211
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
210
+                    echo self::$nl.' . $expired_ticket_line_item->OBJ_ID(): '.$expired_ticket_line_item->OBJ_ID();
211
+                    echo self::$nl.' . $expired_ticket_line_item->timestamp(): '
212 212
                          . date(
213 213
                              'Y-m-d h:i a',
214 214
                              $expired_ticket_line_item->timestamp(true)
215 215
                          );
216 216
                 }
217 217
             }
218
-            if (! empty($expired_ticket_IDs)) {
218
+            if ( ! empty($expired_ticket_IDs)) {
219 219
                 EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
220 220
                     \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
221 221
                     array(),
@@ -253,8 +253,8 @@  discard block
 block discarded – undo
253 253
             $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
254 254
         }
255 255
         if (self::debug) {
256
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
257
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
256
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
257
+            echo self::$nl.self::$nl.'<b> RETURNED QTY: '.$qty.'</b>';
258 258
         }
259 259
         return $qty;
260 260
     }
@@ -272,36 +272,36 @@  discard block
 block discarded – undo
272 272
     protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
273 273
     {
274 274
         if (self::debug) {
275
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
275
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
276 276
         }
277
-        if (! $ticket instanceof EE_Ticket) {
277
+        if ( ! $ticket instanceof EE_Ticket) {
278 278
             return 0;
279 279
         }
280 280
         if (self::debug) {
281
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
282
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
281
+            echo self::$nl.'<b> . ticket->ID: '.$ticket->ID().'</b>';
282
+            echo self::$nl.' . original ticket->reserved: '.$ticket->reserved();
283 283
         }
284 284
         $ticket->refresh_from_db();
285 285
         // first let's determine the ticket availability based on sales
286 286
         $available = $ticket->qty('saleable');
287 287
         if (self::debug) {
288
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
289
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
290
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
291
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
292
-            echo self::$nl . ' . . . available: ' . $available;
288
+            echo self::$nl.' . . . ticket->qty: '.$ticket->qty();
289
+            echo self::$nl.' . . . ticket->sold: '.$ticket->sold();
290
+            echo self::$nl.' . . . ticket->reserved: '.$ticket->reserved();
291
+            echo self::$nl.' . . . ticket->qty(saleable): '.$ticket->qty('saleable');
292
+            echo self::$nl.' . . . available: '.$available;
293 293
         }
294 294
         if ($available < 1) {
295 295
             $this->_ticket_sold_out($ticket);
296 296
             return 0;
297 297
         }
298 298
         if (self::debug) {
299
-            echo self::$nl . ' . . . qty: ' . $qty;
299
+            echo self::$nl.' . . . qty: '.$qty;
300 300
         }
301 301
         if ($available < $qty) {
302 302
             $qty = $available;
303 303
             if (self::debug) {
304
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
304
+                echo self::$nl.' . . . QTY ADJUSTED: '.$qty;
305 305
             }
306 306
             $this->_ticket_quantity_decremented($ticket);
307 307
         }
@@ -321,9 +321,9 @@  discard block
 block discarded – undo
321 321
     protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
322 322
     {
323 323
         if (self::debug) {
324
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
324
+            echo self::$nl.self::$nl.' . . . INCREASE RESERVED: '.$quantity;
325 325
         }
326
-        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:' . __LINE__);
326
+        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:'.__LINE__);
327 327
         return $ticket->save();
328 328
     }
329 329
 
@@ -337,12 +337,12 @@  discard block
 block discarded – undo
337 337
     protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
338 338
     {
339 339
         if (self::debug) {
340
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
341
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
340
+            echo self::$nl.' . . . ticket->ID: '.$ticket->ID();
341
+            echo self::$nl.' . . . ticket->reserved before: '.$ticket->reserved();
342 342
         }
343
-        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
343
+        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:'.__LINE__);
344 344
         if (self::debug) {
345
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
345
+            echo self::$nl.' . . . ticket->reserved after: '.$ticket->reserved();
346 346
         }
347 347
         return $ticket->save() ? 1 : 0;
348 348
     }
@@ -359,8 +359,8 @@  discard block
 block discarded – undo
359 359
     protected function _ticket_sold_out(EE_Ticket $ticket)
360 360
     {
361 361
         if (self::debug) {
362
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
363
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
362
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
363
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
364 364
         }
365 365
         $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
366 366
     }
@@ -377,8 +377,8 @@  discard block
 block discarded – undo
377 377
     protected function _ticket_quantity_decremented(EE_Ticket $ticket)
378 378
     {
379 379
         if (self::debug) {
380
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
381
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
380
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
381
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
382 382
         }
383 383
         $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
384 384
     }
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
         if ($ticket instanceof EE_Ticket) {
430 430
             $ticket->add_extra_meta(
431 431
                 EE_Ticket::META_KEY_TICKET_RESERVATIONS,
432
-                __LINE__ . ') ' . __METHOD__ . '()'
432
+                __LINE__.') '.__METHOD__.'()'
433 433
             );
434 434
             if ($quantity > 0) {
435 435
                 EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
     {
453 453
         $ticket->add_extra_meta(
454 454
             EE_Ticket::META_KEY_TICKET_RESERVATIONS,
455
-            __LINE__ . ') ' . __METHOD__ . '()'
455
+            __LINE__.') '.__METHOD__.'()'
456 456
         );
457 457
         EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
458 458
     }
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
     protected function _post_notices()
488 488
     {
489 489
         if (self::debug) {
490
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
490
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
491 491
         }
492 492
         $refresh_msg = '';
493 493
         $none_added_msg = '';
@@ -498,7 +498,7 @@  discard block
 block discarded – undo
498 498
             );
499 499
             $none_added_msg = __('No tickets were added for the event.', 'event_espresso');
500 500
         }
501
-        if (! empty($this->sold_out_tickets)) {
501
+        if ( ! empty($this->sold_out_tickets)) {
502 502
             EE_Error::add_attention(
503 503
                 sprintf(
504 504
                     apply_filters(
@@ -521,7 +521,7 @@  discard block
 block discarded – undo
521 521
             // and reset the cart
522 522
             EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523 523
         }
524
-        if (! empty($this->decremented_tickets)) {
524
+        if ( ! empty($this->decremented_tickets)) {
525 525
             EE_Error::add_attention(
526 526
                 sprintf(
527 527
                     apply_filters(
@@ -558,9 +558,9 @@  discard block
 block discarded – undo
558 558
     protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
559 559
     {
560 560
         if (self::debug) {
561
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
562
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
563
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
561
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
562
+            echo self::$nl.' . transaction->ID: '.$transaction->ID();
563
+            echo self::$nl.' . TXN status_ID: '.$transaction->status_ID();
564 564
         }
565 565
         // check if 'finalize_registration' step has been completed...
566 566
         $finalized = $transaction->reg_step_completed('finalize_registration');
@@ -572,13 +572,13 @@  discard block
 block discarded – undo
572 572
                 __LINE__,
573 573
                 array('finalized' => $finalized),
574 574
                 false,
575
-                'EE_Transaction: ' . $transaction->ID()
575
+                'EE_Transaction: '.$transaction->ID()
576 576
             );
577 577
         }
578 578
         // how many tickets were released
579 579
         $count = 0;
580 580
         if (self::debug) {
581
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
581
+            echo self::$nl.' . . . TXN finalized: '.$finalized;
582 582
         }
583 583
         $release_tickets_with_TXN_status = array(
584 584
             EEM_Transaction::failed_status_code,
@@ -587,27 +587,27 @@  discard block
 block discarded – undo
587 587
         );
588 588
         $events = array();
589 589
         // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
590
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
590
+        if ( ! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
591 591
             // cancel any reserved tickets for registrations that were not approved
592 592
             $registrations = $transaction->registrations();
593 593
             if (self::debug) {
594
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
594
+                echo self::$nl.' . . . # registrations: '.count($registrations);
595 595
                 $reg = reset($registrations);
596 596
                 $ticket = $reg->ticket();
597 597
                 if ($ticket instanceof EE_Ticket) {
598 598
                     $ticket->add_extra_meta(
599 599
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
600
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
600
+                        __LINE__.') Release All Tickets TXN:'.$transaction->ID()
601 601
                     );
602 602
                 }
603 603
             }
604
-            if (! empty($registrations)) {
604
+            if ( ! empty($registrations)) {
605 605
                 foreach ($registrations as $registration) {
606 606
                     if ($registration instanceof EE_Registration
607 607
                         && $this->_release_reserved_ticket_for_registration($registration, $transaction)
608 608
                     ) {
609 609
                         $count++;
610
-                        $events[ $registration->event_ID() ] = $registration->event();
610
+                        $events[$registration->event_ID()] = $registration->event();
611 611
                     }
612 612
                 }
613 613
             }
@@ -637,10 +637,10 @@  discard block
 block discarded – undo
637 637
     ) {
638 638
         $STS_ID = $transaction->status_ID();
639 639
         if (self::debug) {
640
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
641
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
642
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
643
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
640
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
641
+            echo self::$nl.' . . registration->ID: '.$registration->ID();
642
+            echo self::$nl.' . . registration->status_ID: '.$registration->status_ID();
643
+            echo self::$nl.' . . transaction->status_ID(): '.$STS_ID;
644 644
         }
645 645
         if (// release Tickets for Failed Transactions and Abandoned Transactions
646 646
             $STS_ID === EEM_Transaction::failed_status_code
@@ -652,12 +652,12 @@  discard block
 block discarded – undo
652 652
             )
653 653
         ) {
654 654
             if (self::debug) {
655
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
655
+                echo self::$nl.self::$nl.' . . RELEASE RESERVED TICKET';
656 656
                 $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
657
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
657
+                echo self::$nl.' . . . registration HAS_RESERVED_TICKET_KEY: ';
658 658
                 var_dump($rsrvd);
659 659
             }
660
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
660
+            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'.__LINE__);
661 661
             return 1;
662 662
         }
663 663
         return 0;
@@ -686,7 +686,7 @@  discard block
 block discarded – undo
686 686
             return;
687 687
         }
688 688
         if (self::debug) {
689
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
689
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
690 690
         }
691 691
         // first check of the session has a valid Checkout object
692 692
         $checkout = $session->checkout();
@@ -698,12 +698,12 @@  discard block
 block discarded – undo
698 698
         $cart = $session->cart();
699 699
         if ($cart instanceof EE_Cart) {
700 700
             if (self::debug) {
701
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
701
+                echo self::$nl.self::$nl.' cart instance of EE_Cart: ';
702 702
             }
703 703
             EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
704 704
         } else {
705 705
             if (self::debug) {
706
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
706
+                echo self::$nl.self::$nl.' invalid EE_Cart: ';
707 707
                 var_export($cart, true);
708 708
             }
709 709
         }
@@ -724,39 +724,39 @@  discard block
 block discarded – undo
724 724
     protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
725 725
     {
726 726
         if (self::debug) {
727
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
727
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
728 728
         }
729 729
         $ticket_line_items = $cart->get_tickets();
730 730
         if (empty($ticket_line_items)) {
731 731
             return;
732 732
         }
733 733
         if (self::debug) {
734
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
734
+            echo '<br /> . ticket_line_item count: '.count($ticket_line_items);
735 735
         }
736 736
         foreach ($ticket_line_items as $ticket_line_item) {
737 737
             if (self::debug) {
738
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
738
+                echo self::$nl.' . ticket_line_item->ID(): '.$ticket_line_item->ID();
739 739
             }
740 740
             if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
741 741
                 if (self::debug) {
742
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
742
+                    echo self::$nl.' . . ticket_line_item->OBJ_ID(): '.$ticket_line_item->OBJ_ID();
743 743
                 }
744 744
                 $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
745 745
                 if ($ticket instanceof EE_Ticket) {
746 746
                     if (self::debug) {
747
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
748
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
747
+                        echo self::$nl.' . . ticket->ID(): '.$ticket->ID();
748
+                        echo self::$nl.' . . ticket_line_item->quantity(): '.$ticket_line_item->quantity();
749 749
                     }
750 750
                     $ticket->add_extra_meta(
751 751
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
752
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
752
+                        __LINE__.') '.__METHOD__.'() SID = '.$session->id()
753 753
                     );
754 754
                     $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
755 755
                 }
756 756
             }
757 757
         }
758 758
         if (self::debug) {
759
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
759
+            echo self::$nl.self::$nl.' RESET COMPLETED ';
760 760
         }
761 761
     }
762 762
 
@@ -797,7 +797,7 @@  discard block
 block discarded – undo
797 797
     protected function _session_checkout_reset(EE_Checkout $checkout)
798 798
     {
799 799
         if (self::debug) {
800
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
800
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
801 801
         }
802 802
         // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
803 803
         if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
@@ -845,7 +845,7 @@  discard block
 block discarded – undo
845 845
                     __LINE__,
846 846
                     array($transaction),
847 847
                     false,
848
-                    'EE_Transaction: ' . $transaction->ID()
848
+                    'EE_Transaction: '.$transaction->ID()
849 849
                 );
850 850
             }
851 851
             return;
@@ -862,7 +862,7 @@  discard block
 block discarded – undo
862 862
                         __LINE__,
863 863
                         array($payment),
864 864
                         false,
865
-                        'EE_Transaction: ' . $transaction->ID()
865
+                        'EE_Transaction: '.$transaction->ID()
866 866
                     );
867 867
                 }
868 868
                 return;
@@ -920,7 +920,7 @@  discard block
 block discarded – undo
920 920
             }
921 921
             $total_line_item = $transaction->total_line_item();
922 922
             // $transaction_in_progress->line
923
-            if (! $total_line_item instanceof EE_Line_Item) {
923
+            if ( ! $total_line_item instanceof EE_Line_Item) {
924 924
                 throw new DomainException(
925 925
                     esc_html__(
926 926
                         'Transaction does not have a valid Total Line Item associated with it.',
@@ -979,25 +979,25 @@  discard block
 block discarded – undo
979 979
         $source
980 980
     ) {
981 981
         if (self::debug) {
982
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
982
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
983 983
         }
984 984
         $total_tickets_released = 0;
985 985
         $sold_out_events = array();
986 986
         foreach ($tickets_with_reservations as $ticket_with_reservations) {
987
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
987
+            if ( ! $ticket_with_reservations instanceof EE_Ticket) {
988 988
                 continue;
989 989
             }
990 990
             $reserved_qty = $ticket_with_reservations->reserved();
991 991
             if (self::debug) {
992
-                echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
993
-                echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
992
+                echo self::$nl.' . $ticket_with_reservations->ID(): '.$ticket_with_reservations->ID();
993
+                echo self::$nl.' . $reserved_qty: '.$reserved_qty;
994 994
             }
995 995
             foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
996 996
                 if ($valid_reserved_ticket_line_item instanceof EE_Line_Item
997 997
                     && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
998 998
                 ) {
999 999
                     if (self::debug) {
1000
-                        echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): '
1000
+                        echo self::$nl.' . $valid_reserved_ticket_line_item->quantity(): '
1001 1001
                              . $valid_reserved_ticket_line_item->quantity();
1002 1002
                     }
1003 1003
                     $reserved_qty -= $valid_reserved_ticket_line_item->quantity();
@@ -1006,9 +1006,9 @@  discard block
 block discarded – undo
1006 1006
             if ($reserved_qty > 0) {
1007 1007
                 $ticket_with_reservations->add_extra_meta(
1008 1008
                     EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1009
-                    __LINE__ . ') ' . $source . '()'
1009
+                    __LINE__.') '.$source.'()'
1010 1010
                 );
1011
-                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:' . __LINE__);
1011
+                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:'.__LINE__);
1012 1012
                 $ticket_with_reservations->save();
1013 1013
                 $total_tickets_released += $reserved_qty;
1014 1014
                 $event = $ticket_with_reservations->get_related_event();
@@ -1019,7 +1019,7 @@  discard block
 block discarded – undo
1019 1019
             }
1020 1020
         }
1021 1021
         if (self::debug) {
1022
-            echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1022
+            echo self::$nl.' . $total_tickets_released: '.$total_tickets_released;
1023 1023
         }
1024 1024
         // double check whether sold out events should remain sold out after releasing tickets
1025 1025
         if ($sold_out_events !== array()) {
@@ -1048,7 +1048,7 @@  discard block
 block discarded – undo
1048 1048
     {
1049 1049
         /** @type WPDB $wpdb */
1050 1050
         global $wpdb;
1051
-        if (! absint($timestamp)) {
1051
+        if ( ! absint($timestamp)) {
1052 1052
             /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1053 1053
             $session_lifespan = LoaderFactory::getLoader()->getShared(
1054 1054
                 'EventEspresso\core\domain\values\session\SessionLifespan'
@@ -1057,7 +1057,7 @@  discard block
 block discarded – undo
1057 1057
         }
1058 1058
         return $wpdb->query(
1059 1059
             $wpdb->prepare(
1060
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1060
+                'DELETE FROM '.EEM_Line_Item::instance()->table().'
1061 1061
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1062 1062
                 // use GMT time because that's what LIN_timestamps are in
1063 1063
                 date('Y-m-d H:i:s', $timestamp)
Please login to merge, or discard this patch.
core/EE_Session.core.php 4 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
     /**
543 543
      * @initiate session
544 544
      * @access   private
545
-     * @return TRUE on success, FALSE on fail
545
+     * @return boolean on success, FALSE on fail
546 546
      * @throws EE_Error
547 547
      * @throws InvalidArgumentException
548 548
      * @throws InvalidDataTypeException
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
      * @update session data  prior to saving to the db
779 779
      * @access public
780 780
      * @param bool $new_session
781
-     * @return TRUE on success, FALSE on fail
781
+     * @return boolean on success, FALSE on fail
782 782
      * @throws EE_Error
783 783
      * @throws InvalidArgumentException
784 784
      * @throws InvalidDataTypeException
@@ -879,7 +879,7 @@  discard block
 block discarded – undo
879 879
      * _save_session_to_db
880 880
      *
881 881
      * @param bool $clear_session
882
-     * @return string
882
+     * @return boolean
883 883
      * @throws EE_Error
884 884
      * @throws InvalidArgumentException
885 885
      * @throws InvalidDataTypeException
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -6,7 +6,6 @@
 block discarded – undo
6 6
 use EventEspresso\core\exceptions\InvalidInterfaceException;
7 7
 use EventEspresso\core\exceptions\InvalidSessionDataException;
8 8
 use EventEspresso\core\services\cache\CacheStorageInterface;
9
-use EventEspresso\core\services\loaders\LoaderFactory;
10 9
 use EventEspresso\core\services\request\RequestInterface;
11 10
 use EventEspresso\core\services\session\SessionStartHandler;
12 11
 
Please login to merge, or discard this patch.
Indentation   +1261 added lines, -1261 removed lines patch added patch discarded remove patch
@@ -25,1259 +25,1259 @@  discard block
 block discarded – undo
25 25
 class EE_Session implements SessionIdentifierInterface
26 26
 {
27 27
 
28
-    const session_id_prefix = 'ee_ssn_';
29
-
30
-    const hash_check_prefix = 'ee_shc_';
31
-
32
-    const OPTION_NAME_SETTINGS = 'ee_session_settings';
33
-
34
-    const STATUS_CLOSED = 0;
35
-
36
-    const STATUS_OPEN = 1;
37
-
38
-    /**
39
-     * instance of the EE_Session object
40
-     *
41
-     * @var EE_Session
42
-     */
43
-    private static $_instance;
44
-
45
-    /**
46
-     * @var CacheStorageInterface $cache_storage
47
-     */
48
-    protected $cache_storage;
49
-
50
-    /**
51
-     * @var EE_Encryption $encryption
52
-     */
53
-    protected $encryption;
54
-
55
-    /**
56
-     * @var SessionStartHandler $session_start_handler
57
-     */
58
-    protected $session_start_handler;
59
-
60
-    /**
61
-     * the session id
62
-     *
63
-     * @var string
64
-     */
65
-    private $_sid;
66
-
67
-    /**
68
-     * session id salt
69
-     *
70
-     * @var string
71
-     */
72
-    private $_sid_salt;
73
-
74
-    /**
75
-     * session data
76
-     *
77
-     * @var array
78
-     */
79
-    private $_session_data = array();
80
-
81
-    /**
82
-     * how long an EE session lasts
83
-     * default session lifespan of 1 hour (for not so instant IPNs)
84
-     *
85
-     * @var SessionLifespan $session_lifespan
86
-     */
87
-    private $session_lifespan;
88
-
89
-    /**
90
-     * session expiration time as Unix timestamp in GMT
91
-     *
92
-     * @var int
93
-     */
94
-    private $_expiration;
95
-
96
-    /**
97
-     * whether or not session has expired at some point
98
-     *
99
-     * @var boolean
100
-     */
101
-    private $_expired = false;
102
-
103
-    /**
104
-     * current time as Unix timestamp in GMT
105
-     *
106
-     * @var int
107
-     */
108
-    private $_time;
109
-
110
-    /**
111
-     * whether to encrypt session data
112
-     *
113
-     * @var bool
114
-     */
115
-    private $_use_encryption;
116
-
117
-    /**
118
-     * well... according to the server...
119
-     *
120
-     * @var null
121
-     */
122
-    private $_user_agent;
123
-
124
-    /**
125
-     * do you really trust the server ?
126
-     *
127
-     * @var null
128
-     */
129
-    private $_ip_address;
130
-
131
-    /**
132
-     * current WP user_id
133
-     *
134
-     * @var null
135
-     */
136
-    private $_wp_user_id;
137
-
138
-    /**
139
-     * array for defining default session vars
140
-     *
141
-     * @var array
142
-     */
143
-    private $_default_session_vars = array(
144
-        'id'            => null,
145
-        'user_id'       => null,
146
-        'ip_address'    => null,
147
-        'user_agent'    => null,
148
-        'init_access'   => null,
149
-        'last_access'   => null,
150
-        'expiration'    => null,
151
-        'pages_visited' => array(),
152
-    );
153
-
154
-    /**
155
-     * timestamp for when last garbage collection cycle was performed
156
-     *
157
-     * @var int $_last_gc
158
-     */
159
-    private $_last_gc;
160
-
161
-    /**
162
-     * @var RequestInterface $request
163
-     */
164
-    protected $request;
165
-
166
-    /**
167
-     * whether session is active or not
168
-     *
169
-     * @var int $status
170
-     */
171
-    private $status = EE_Session::STATUS_CLOSED;
172
-
173
-
174
-    /**
175
-     * @singleton method used to instantiate class object
176
-     * @param CacheStorageInterface $cache_storage
177
-     * @param SessionLifespan|null  $lifespan
178
-     * @param RequestInterface      $request
179
-     * @param SessionStartHandler   $session_start_handler
180
-     * @param EE_Encryption         $encryption
181
-     * @return EE_Session
182
-     * @throws InvalidArgumentException
183
-     * @throws InvalidDataTypeException
184
-     * @throws InvalidInterfaceException
185
-     */
186
-    public static function instance(
187
-        CacheStorageInterface $cache_storage = null,
188
-        SessionLifespan $lifespan = null,
189
-        RequestInterface $request = null,
190
-        SessionStartHandler $session_start_handler = null,
191
-        EE_Encryption $encryption = null
192
-    ) {
193
-        // check if class object is instantiated
194
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
195
-        // add_filter( 'FHEE_load_EE_Session', '__return_false' );
196
-        if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
197
-            self::$_instance = new self(
198
-                $cache_storage,
199
-                $lifespan,
200
-                $request,
201
-                $session_start_handler,
202
-                $encryption
203
-            );
204
-        }
205
-        return self::$_instance;
206
-    }
207
-
208
-
209
-    /**
210
-     * protected constructor to prevent direct creation
211
-     *
212
-     * @param CacheStorageInterface $cache_storage
213
-     * @param SessionLifespan       $lifespan
214
-     * @param RequestInterface      $request
215
-     * @param SessionStartHandler   $session_start_handler
216
-     * @param EE_Encryption         $encryption
217
-     * @throws InvalidArgumentException
218
-     * @throws InvalidDataTypeException
219
-     * @throws InvalidInterfaceException
220
-     */
221
-    protected function __construct(
222
-        CacheStorageInterface $cache_storage,
223
-        SessionLifespan $lifespan,
224
-        RequestInterface $request,
225
-        SessionStartHandler $session_start_handler,
226
-        EE_Encryption $encryption = null
227
-    ) {
228
-        // session loading is turned ON by default,
229
-        // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
230
-        // (which currently fires on the init hook at priority 9),
231
-        // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
232
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
233
-            return;
234
-        }
235
-        $this->session_start_handler = $session_start_handler;
236
-        $this->session_lifespan = $lifespan;
237
-        $this->request = $request;
238
-        if (! defined('ESPRESSO_SESSION')) {
239
-            define('ESPRESSO_SESSION', true);
240
-        }
241
-        // retrieve session options from db
242
-        $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
243
-        if (! empty($session_settings)) {
244
-            // cycle though existing session options
245
-            foreach ($session_settings as $var_name => $session_setting) {
246
-                // set values for class properties
247
-                $var_name = '_' . $var_name;
248
-                $this->{$var_name} = $session_setting;
249
-            }
250
-        }
251
-        $this->cache_storage = $cache_storage;
252
-        // are we using encryption?
253
-        $this->_use_encryption = $encryption instanceof EE_Encryption
254
-                                 && EE_Registry::instance()->CFG->admin->encode_session_data();
255
-        // encrypt data via: $this->encryption->encrypt();
256
-        $this->encryption = $encryption;
257
-        // filter hook allows outside functions/classes/plugins to change default empty cart
258
-        $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
259
-        array_merge($this->_default_session_vars, $extra_default_session_vars);
260
-        // apply default session vars
261
-        $this->_set_defaults();
262
-        add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
263
-        // check request for 'clear_session' param
264
-        add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
265
-        // once everything is all said and done,
266
-        add_action('shutdown', array($this, 'update'), 100);
267
-        add_action('shutdown', array($this, 'garbageCollection'), 1000);
268
-        $this->configure_garbage_collection_filters();
269
-    }
270
-
271
-
272
-    /**
273
-     * @return bool
274
-     * @throws InvalidArgumentException
275
-     * @throws InvalidDataTypeException
276
-     * @throws InvalidInterfaceException
277
-     */
278
-    public static function isLoadedAndActive()
279
-    {
280
-        return did_action('AHEE__EE_System__core_loaded_and_ready')
281
-               && EE_Session::instance() instanceof EE_Session
282
-               && EE_Session::instance()->isActive();
283
-    }
284
-
285
-
286
-    /**
287
-     * @return bool
288
-     */
289
-    public function isActive()
290
-    {
291
-        return $this->status === EE_Session::STATUS_OPEN;
292
-    }
293
-
294
-
295
-    /**
296
-     * @return void
297
-     * @throws EE_Error
298
-     * @throws InvalidArgumentException
299
-     * @throws InvalidDataTypeException
300
-     * @throws InvalidInterfaceException
301
-     * @throws InvalidSessionDataException
302
-     */
303
-    public function open_session()
304
-    {
305
-        // check for existing session and retrieve it from db
306
-        if (! $this->_espresso_session()) {
307
-            // or just start a new one
308
-            $this->_create_espresso_session();
309
-        }
310
-    }
311
-
312
-
313
-    /**
314
-     * @return bool
315
-     */
316
-    public function expired()
317
-    {
318
-        return $this->_expired;
319
-    }
320
-
321
-
322
-    /**
323
-     * @return void
324
-     */
325
-    public function reset_expired()
326
-    {
327
-        $this->_expired = false;
328
-    }
329
-
330
-
331
-    /**
332
-     * @return int
333
-     */
334
-    public function expiration()
335
-    {
336
-        return $this->_expiration;
337
-    }
338
-
339
-
340
-    /**
341
-     * @return int
342
-     */
343
-    public function extension()
344
-    {
345
-        return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
346
-    }
347
-
348
-
349
-    /**
350
-     * @param int $time number of seconds to add to session expiration
351
-     */
352
-    public function extend_expiration($time = 0)
353
-    {
354
-        $time = $time ? $time : $this->extension();
355
-        $this->_expiration += absint($time);
356
-    }
357
-
358
-
359
-    /**
360
-     * @return int
361
-     */
362
-    public function lifespan()
363
-    {
364
-        return $this->session_lifespan->inSeconds();
365
-    }
366
-
367
-
368
-    /**
369
-     * This just sets some defaults for the _session data property
370
-     *
371
-     * @access private
372
-     * @return void
373
-     */
374
-    private function _set_defaults()
375
-    {
376
-        // set some defaults
377
-        foreach ($this->_default_session_vars as $key => $default_var) {
378
-            if (is_array($default_var)) {
379
-                $this->_session_data[ $key ] = array();
380
-            } else {
381
-                $this->_session_data[ $key ] = '';
382
-            }
383
-        }
384
-    }
385
-
386
-
387
-    /**
388
-     * @retrieve  session data
389
-     * @access    public
390
-     * @return    string
391
-     */
392
-    public function id()
393
-    {
394
-        return $this->_sid;
395
-    }
396
-
397
-
398
-    /**
399
-     * @param \EE_Cart $cart
400
-     * @return bool
401
-     */
402
-    public function set_cart(EE_Cart $cart)
403
-    {
404
-        $this->_session_data['cart'] = $cart;
405
-        return true;
406
-    }
407
-
408
-
409
-    /**
410
-     * reset_cart
411
-     */
412
-    public function reset_cart()
413
-    {
414
-        do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
415
-        $this->_session_data['cart'] = null;
416
-    }
417
-
418
-
419
-    /**
420
-     * @return \EE_Cart
421
-     */
422
-    public function cart()
423
-    {
424
-        return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
425
-            ? $this->_session_data['cart']
426
-            : null;
427
-    }
428
-
429
-
430
-    /**
431
-     * @param \EE_Checkout $checkout
432
-     * @return bool
433
-     */
434
-    public function set_checkout(EE_Checkout $checkout)
435
-    {
436
-        $this->_session_data['checkout'] = $checkout;
437
-        return true;
438
-    }
439
-
440
-
441
-    /**
442
-     * reset_checkout
443
-     */
444
-    public function reset_checkout()
445
-    {
446
-        do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
447
-        $this->_session_data['checkout'] = null;
448
-    }
449
-
450
-
451
-    /**
452
-     * @return \EE_Checkout
453
-     */
454
-    public function checkout()
455
-    {
456
-        return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
457
-            ? $this->_session_data['checkout']
458
-            : null;
459
-    }
460
-
461
-
462
-    /**
463
-     * @param \EE_Transaction $transaction
464
-     * @return bool
465
-     * @throws EE_Error
466
-     */
467
-    public function set_transaction(EE_Transaction $transaction)
468
-    {
469
-        // first remove the session from the transaction before we save the transaction in the session
470
-        $transaction->set_txn_session_data(null);
471
-        $this->_session_data['transaction'] = $transaction;
472
-        return true;
473
-    }
474
-
475
-
476
-    /**
477
-     * reset_transaction
478
-     */
479
-    public function reset_transaction()
480
-    {
481
-        do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
482
-        $this->_session_data['transaction'] = null;
483
-    }
484
-
485
-
486
-    /**
487
-     * @return \EE_Transaction
488
-     */
489
-    public function transaction()
490
-    {
491
-        return isset($this->_session_data['transaction'])
492
-               && $this->_session_data['transaction'] instanceof EE_Transaction
493
-            ? $this->_session_data['transaction']
494
-            : null;
495
-    }
496
-
497
-
498
-    /**
499
-     * retrieve session data
500
-     *
501
-     * @param null $key
502
-     * @param bool $reset_cache
503
-     * @return array
504
-     */
505
-    public function get_session_data($key = null, $reset_cache = false)
506
-    {
507
-        if ($reset_cache) {
508
-            $this->reset_cart();
509
-            $this->reset_checkout();
510
-            $this->reset_transaction();
511
-        }
512
-        if (! empty($key)) {
513
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
514
-        }
515
-        return $this->_session_data;
516
-    }
517
-
518
-
519
-    /**
520
-     * Returns TRUE on success, FALSE on fail
521
-     *
522
-     * @param array $data
523
-     * @return bool
524
-     */
525
-    public function set_session_data($data)
526
-    {
527
-        // nothing ??? bad data ??? go home!
528
-        if (empty($data) || ! is_array($data)) {
529
-            EE_Error::add_error(
530
-                esc_html__(
531
-                    'No session data or invalid session data was provided.',
532
-                    'event_espresso'
533
-                ),
534
-                __FILE__,
535
-                __FUNCTION__,
536
-                __LINE__
537
-            );
538
-            return false;
539
-        }
540
-        foreach ($data as $key => $value) {
541
-            if (isset($this->_default_session_vars[ $key ])) {
542
-                EE_Error::add_error(
543
-                    sprintf(
544
-                        esc_html__(
545
-                            'Sorry! %s is a default session datum and can not be reset.',
546
-                            'event_espresso'
547
-                        ),
548
-                        $key
549
-                    ),
550
-                    __FILE__,
551
-                    __FUNCTION__,
552
-                    __LINE__
553
-                );
554
-                return false;
555
-            }
556
-            $this->_session_data[ $key ] = $value;
557
-        }
558
-        return true;
559
-    }
560
-
561
-
562
-    /**
563
-     * @initiate session
564
-     * @access   private
565
-     * @return TRUE on success, FALSE on fail
566
-     * @throws EE_Error
567
-     * @throws InvalidArgumentException
568
-     * @throws InvalidDataTypeException
569
-     * @throws InvalidInterfaceException
570
-     * @throws InvalidSessionDataException
571
-     */
572
-    private function _espresso_session()
573
-    {
574
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
575
-        $this->session_start_handler->startSession();
576
-        $this->status = EE_Session::STATUS_OPEN;
577
-        // get our modified session ID
578
-        $this->_sid = $this->_generate_session_id();
579
-        // and the visitors IP
580
-        $this->_ip_address = $this->request->ipAddress();
581
-        // set the "user agent"
582
-        $this->_user_agent = $this->request->userAgent();
583
-        // now let's retrieve what's in the db
584
-        $session_data = $this->_retrieve_session_data();
585
-        if (! empty($session_data)) {
586
-            // get the current time in UTC
587
-            $this->_time = $this->_time !== null ? $this->_time : time();
588
-            // and reset the session expiration
589
-            $this->_expiration = isset($session_data['expiration'])
590
-                ? $session_data['expiration']
591
-                : $this->_time + $this->session_lifespan->inSeconds();
592
-        } else {
593
-            // set initial site access time and the session expiration
594
-            $this->_set_init_access_and_expiration();
595
-            // set referer
596
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
597
-                ? esc_attr($_SERVER['HTTP_REFERER'])
598
-                : '';
599
-            // no previous session = go back and create one (on top of the data above)
600
-            return false;
601
-        }
602
-        // now the user agent
603
-        if ($session_data['user_agent'] !== $this->_user_agent) {
604
-            return false;
605
-        }
606
-        // wait a minute... how old are you?
607
-        if ($this->_time > $this->_expiration) {
608
-            // yer too old fer me!
609
-            $this->_expired = true;
610
-            // wipe out everything that isn't a default session datum
611
-            $this->clear_session(__CLASS__, __FUNCTION__);
612
-        }
613
-        // make event espresso session data available to plugin
614
-        $this->_session_data = array_merge($this->_session_data, $session_data);
615
-        return true;
616
-    }
617
-
618
-
619
-    /**
620
-     * _get_session_data
621
-     * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
622
-     * databases
623
-     *
624
-     * @return array
625
-     * @throws EE_Error
626
-     * @throws InvalidArgumentException
627
-     * @throws InvalidSessionDataException
628
-     * @throws InvalidDataTypeException
629
-     * @throws InvalidInterfaceException
630
-     */
631
-    protected function _retrieve_session_data()
632
-    {
633
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
634
-        try {
635
-            // we're using WP's Transient API to store session data using the PHP session ID as the option name
636
-            $session_data = $this->cache_storage->get($ssn_key, false);
637
-            if (empty($session_data)) {
638
-                return array();
639
-            }
640
-            if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
641
-                $hash_check = $this->cache_storage->get(
642
-                    EE_Session::hash_check_prefix . $this->_sid,
643
-                    false
644
-                );
645
-                if ($hash_check && $hash_check !== md5($session_data)) {
646
-                    EE_Error::add_error(
647
-                        sprintf(
648
-                            __(
649
-                                'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
650
-                                'event_espresso'
651
-                            ),
652
-                            EE_Session::session_id_prefix . $this->_sid
653
-                        ),
654
-                        __FILE__,
655
-                        __FUNCTION__,
656
-                        __LINE__
657
-                    );
658
-                }
659
-            }
660
-        } catch (Exception $e) {
661
-            // let's just eat that error for now and attempt to correct any corrupted data
662
-            global $wpdb;
663
-            $row = $wpdb->get_row(
664
-                $wpdb->prepare(
665
-                    "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
666
-                    '_transient_' . $ssn_key
667
-                )
668
-            );
669
-            $session_data = is_object($row) ? $row->option_value : null;
670
-            if ($session_data) {
671
-                $session_data = preg_replace_callback(
672
-                    '!s:(d+):"(.*?)";!',
673
-                    function ($match) {
674
-                        return $match[1] === strlen($match[2])
675
-                            ? $match[0]
676
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
677
-                    },
678
-                    $session_data
679
-                );
680
-            }
681
-            $session_data = maybe_unserialize($session_data);
682
-        }
683
-        // in case the data is encoded... try to decode it
684
-        $session_data = $this->encryption instanceof EE_Encryption
685
-            ? $this->encryption->base64_string_decode($session_data)
686
-            : $session_data;
687
-        if (! is_array($session_data)) {
688
-            try {
689
-                $session_data = maybe_unserialize($session_data);
690
-            } catch (Exception $e) {
691
-                $msg = esc_html__(
692
-                    'An error occurred while attempting to unserialize the session data.',
693
-                    'event_espresso'
694
-                );
695
-                $msg .= WP_DEBUG
696
-                    ? '<br><pre>'
697
-                      . print_r($session_data, true)
698
-                      . '</pre><br>'
699
-                      . $this->find_serialize_error($session_data)
700
-                    : '';
701
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
702
-                throw new InvalidSessionDataException($msg, 0, $e);
703
-            }
704
-        }
705
-        // just a check to make sure the session array is indeed an array
706
-        if (! is_array($session_data)) {
707
-            // no?!?! then something is wrong
708
-            $msg = esc_html__(
709
-                'The session data is missing, invalid, or corrupted.',
710
-                'event_espresso'
711
-            );
712
-            $msg .= WP_DEBUG
713
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
714
-                : '';
715
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
716
-            throw new InvalidSessionDataException($msg);
717
-        }
718
-        if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
719
-            $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
720
-                $session_data['transaction']
721
-            );
722
-        }
723
-        return $session_data;
724
-    }
725
-
726
-
727
-    /**
728
-     * _generate_session_id
729
-     * Retrieves the PHP session id either directly from the PHP session,
730
-     * or from the $_REQUEST array if it was passed in from an AJAX request.
731
-     * The session id is then salted and hashed (mmm sounds tasty)
732
-     * so that it can be safely used as a $_REQUEST param
733
-     *
734
-     * @return string
735
-     */
736
-    protected function _generate_session_id()
737
-    {
738
-        // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
739
-        if (isset($_REQUEST['EESID'])) {
740
-            $session_id = sanitize_text_field($_REQUEST['EESID']);
741
-        } else {
742
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
743
-        }
744
-        return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
745
-    }
746
-
747
-
748
-    /**
749
-     * _get_sid_salt
750
-     *
751
-     * @return string
752
-     */
753
-    protected function _get_sid_salt()
754
-    {
755
-        // was session id salt already saved to db ?
756
-        if (empty($this->_sid_salt)) {
757
-            // no?  then maybe use WP defined constant
758
-            if (defined('AUTH_SALT')) {
759
-                $this->_sid_salt = AUTH_SALT;
760
-            }
761
-            // if salt doesn't exist or is too short
762
-            if (strlen($this->_sid_salt) < 32) {
763
-                // create a new one
764
-                $this->_sid_salt = wp_generate_password(64);
765
-            }
766
-            // and save it as a permanent session setting
767
-            $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
768
-        }
769
-        return $this->_sid_salt;
770
-    }
771
-
772
-
773
-    /**
774
-     * _set_init_access_and_expiration
775
-     *
776
-     * @return void
777
-     */
778
-    protected function _set_init_access_and_expiration()
779
-    {
780
-        $this->_time = time();
781
-        $this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
782
-        // set initial site access time
783
-        $this->_session_data['init_access'] = $this->_time;
784
-        // and the session expiration
785
-        $this->_session_data['expiration'] = $this->_expiration;
786
-    }
787
-
788
-
789
-    /**
790
-     * @update session data  prior to saving to the db
791
-     * @access public
792
-     * @param bool $new_session
793
-     * @return TRUE on success, FALSE on fail
794
-     * @throws EE_Error
795
-     * @throws InvalidArgumentException
796
-     * @throws InvalidDataTypeException
797
-     * @throws InvalidInterfaceException
798
-     */
799
-    public function update($new_session = false)
800
-    {
801
-        $this->_session_data = $this->_session_data !== null
802
-                               && is_array($this->_session_data)
803
-                               && isset($this->_session_data['id'])
804
-            ? $this->_session_data
805
-            : array();
806
-        if (empty($this->_session_data)) {
807
-            $this->_set_defaults();
808
-        }
809
-        $session_data = array();
810
-        foreach ($this->_session_data as $key => $value) {
811
-            switch ($key) {
812
-                case 'id':
813
-                    // session ID
814
-                    $session_data['id'] = $this->_sid;
815
-                    break;
816
-                case 'ip_address':
817
-                    // visitor ip address
818
-                    $session_data['ip_address'] = $this->request->ipAddress();
819
-                    break;
820
-                case 'user_agent':
821
-                    // visitor user_agent
822
-                    $session_data['user_agent'] = $this->_user_agent;
823
-                    break;
824
-                case 'init_access':
825
-                    $session_data['init_access'] = absint($value);
826
-                    break;
827
-                case 'last_access':
828
-                    // current access time
829
-                    $session_data['last_access'] = $this->_time;
830
-                    break;
831
-                case 'expiration':
832
-                    // when the session expires
833
-                    $session_data['expiration'] = ! empty($this->_expiration)
834
-                        ? $this->_expiration
835
-                        : $session_data['init_access'] + $this->session_lifespan->inSeconds();
836
-                    break;
837
-                case 'user_id':
838
-                    // current user if logged in
839
-                    $session_data['user_id'] = $this->_wp_user_id();
840
-                    break;
841
-                case 'pages_visited':
842
-                    $page_visit = $this->_get_page_visit();
843
-                    if ($page_visit) {
844
-                        // set pages visited where the first will be the http referrer
845
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
846
-                        // we'll only save the last 10 page visits.
847
-                        $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
848
-                    }
849
-                    break;
850
-                default:
851
-                    // carry any other data over
852
-                    $session_data[ $key ] = $this->_session_data[ $key ];
853
-            }
854
-        }
855
-        $this->_session_data = $session_data;
856
-        // creating a new session does not require saving to the db just yet
857
-        if (! $new_session) {
858
-            // ready? let's save
859
-            if ($this->_save_session_to_db()) {
860
-                return true;
861
-            }
862
-            return false;
863
-        }
864
-        // meh, why not?
865
-        return true;
866
-    }
867
-
868
-
869
-    /**
870
-     * @create session data array
871
-     * @access public
872
-     * @return bool
873
-     * @throws EE_Error
874
-     * @throws InvalidArgumentException
875
-     * @throws InvalidDataTypeException
876
-     * @throws InvalidInterfaceException
877
-     */
878
-    private function _create_espresso_session()
879
-    {
880
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
881
-        // use the update function for now with $new_session arg set to TRUE
882
-        return $this->update(true) ? true : false;
883
-    }
884
-
885
-    /**
886
-     * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
887
-     * too). This is used when determining if we want to save the session or not.
888
-     * @since 4.9.67.p
889
-     * @return bool
890
-     */
891
-    private function sessionHasStuffWorthSaving()
892
-    {
893
-        return $this->cart() instanceof EE_Cart
894
-            || (
895
-                isset($this->_session_data['ee_notices'])
896
-                && (
897
-                    ! empty($this->_session_data['ee_notices']['attention'])
898
-                    || !empty($this->_session_data['ee_notices']['errors'])
899
-                    || !empty($this->_session_data['ee_notices']['success'])
900
-                )
901
-            );
902
-    }
903
-    /**
904
-     * _save_session_to_db
905
-     *
906
-     * @param bool $clear_session
907
-     * @return string
908
-     * @throws EE_Error
909
-     * @throws InvalidArgumentException
910
-     * @throws InvalidDataTypeException
911
-     * @throws InvalidInterfaceException
912
-     */
913
-    private function _save_session_to_db($clear_session = false)
914
-    {
915
-        // don't save sessions for crawlers
916
-        // and unless we're deleting the session data, don't save anything if there isn't a cart
917
-        if ($this->request->isBot()
918
-            || (
919
-                ! $clear_session
920
-                && ! $this->sessionHasStuffWorthSaving()
921
-                && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
922
-            )
923
-        ) {
924
-            return false;
925
-        }
926
-        $transaction = $this->transaction();
927
-        if ($transaction instanceof EE_Transaction) {
928
-            if (! $transaction->ID()) {
929
-                $transaction->save();
930
-            }
931
-            $this->_session_data['transaction'] = $transaction->ID();
932
-        }
933
-        // then serialize all of our session data
934
-        $session_data = serialize($this->_session_data);
935
-        // do we need to also encode it to avoid corrupted data when saved to the db?
936
-        $session_data = $this->_use_encryption
937
-            ? $this->encryption->base64_string_encode($session_data)
938
-            : $session_data;
939
-        // maybe save hash check
940
-        if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
941
-            $this->cache_storage->add(
942
-                EE_Session::hash_check_prefix . $this->_sid,
943
-                md5($session_data),
944
-                $this->session_lifespan->inSeconds()
945
-            );
946
-        }
947
-        // we're using the Transient API for storing session data,
948
-        return $this->cache_storage->add(
949
-            EE_Session::session_id_prefix . $this->_sid,
950
-            $session_data,
951
-            $this->session_lifespan->inSeconds()
952
-        );
953
-    }
954
-
955
-
956
-    /**
957
-     * @get    the full page request the visitor is accessing
958
-     * @access public
959
-     * @return string
960
-     */
961
-    public function _get_page_visit()
962
-    {
963
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
964
-        // check for request url
965
-        if (isset($_SERVER['REQUEST_URI'])) {
966
-            $http_host = '';
967
-            $page_id = '?';
968
-            $e_reg = '';
969
-            $request_uri = esc_url($_SERVER['REQUEST_URI']);
970
-            $ru_bits = explode('?', $request_uri);
971
-            $request_uri = $ru_bits[0];
972
-            // check for and grab host as well
973
-            if (isset($_SERVER['HTTP_HOST'])) {
974
-                $http_host = esc_url($_SERVER['HTTP_HOST']);
975
-            }
976
-            // check for page_id in SERVER REQUEST
977
-            if (isset($_REQUEST['page_id'])) {
978
-                // rebuild $e_reg without any of the extra parameters
979
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
980
-            }
981
-            // check for $e_reg in SERVER REQUEST
982
-            if (isset($_REQUEST['ee'])) {
983
-                // rebuild $e_reg without any of the extra parameters
984
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
985
-            }
986
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
987
-        }
988
-        return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
989
-    }
990
-
991
-
992
-    /**
993
-     * @the    current wp user id
994
-     * @access public
995
-     * @return int
996
-     */
997
-    public function _wp_user_id()
998
-    {
999
-        // if I need to explain the following lines of code, then you shouldn't be looking at this!
1000
-        $this->_wp_user_id = get_current_user_id();
1001
-        return $this->_wp_user_id;
1002
-    }
1003
-
1004
-
1005
-    /**
1006
-     * Clear EE_Session data
1007
-     *
1008
-     * @access public
1009
-     * @param string $class
1010
-     * @param string $function
1011
-     * @return void
1012
-     * @throws EE_Error
1013
-     * @throws InvalidArgumentException
1014
-     * @throws InvalidDataTypeException
1015
-     * @throws InvalidInterfaceException
1016
-     */
1017
-    public function clear_session($class = '', $function = '')
1018
-    {
28
+	const session_id_prefix = 'ee_ssn_';
29
+
30
+	const hash_check_prefix = 'ee_shc_';
31
+
32
+	const OPTION_NAME_SETTINGS = 'ee_session_settings';
33
+
34
+	const STATUS_CLOSED = 0;
35
+
36
+	const STATUS_OPEN = 1;
37
+
38
+	/**
39
+	 * instance of the EE_Session object
40
+	 *
41
+	 * @var EE_Session
42
+	 */
43
+	private static $_instance;
44
+
45
+	/**
46
+	 * @var CacheStorageInterface $cache_storage
47
+	 */
48
+	protected $cache_storage;
49
+
50
+	/**
51
+	 * @var EE_Encryption $encryption
52
+	 */
53
+	protected $encryption;
54
+
55
+	/**
56
+	 * @var SessionStartHandler $session_start_handler
57
+	 */
58
+	protected $session_start_handler;
59
+
60
+	/**
61
+	 * the session id
62
+	 *
63
+	 * @var string
64
+	 */
65
+	private $_sid;
66
+
67
+	/**
68
+	 * session id salt
69
+	 *
70
+	 * @var string
71
+	 */
72
+	private $_sid_salt;
73
+
74
+	/**
75
+	 * session data
76
+	 *
77
+	 * @var array
78
+	 */
79
+	private $_session_data = array();
80
+
81
+	/**
82
+	 * how long an EE session lasts
83
+	 * default session lifespan of 1 hour (for not so instant IPNs)
84
+	 *
85
+	 * @var SessionLifespan $session_lifespan
86
+	 */
87
+	private $session_lifespan;
88
+
89
+	/**
90
+	 * session expiration time as Unix timestamp in GMT
91
+	 *
92
+	 * @var int
93
+	 */
94
+	private $_expiration;
95
+
96
+	/**
97
+	 * whether or not session has expired at some point
98
+	 *
99
+	 * @var boolean
100
+	 */
101
+	private $_expired = false;
102
+
103
+	/**
104
+	 * current time as Unix timestamp in GMT
105
+	 *
106
+	 * @var int
107
+	 */
108
+	private $_time;
109
+
110
+	/**
111
+	 * whether to encrypt session data
112
+	 *
113
+	 * @var bool
114
+	 */
115
+	private $_use_encryption;
116
+
117
+	/**
118
+	 * well... according to the server...
119
+	 *
120
+	 * @var null
121
+	 */
122
+	private $_user_agent;
123
+
124
+	/**
125
+	 * do you really trust the server ?
126
+	 *
127
+	 * @var null
128
+	 */
129
+	private $_ip_address;
130
+
131
+	/**
132
+	 * current WP user_id
133
+	 *
134
+	 * @var null
135
+	 */
136
+	private $_wp_user_id;
137
+
138
+	/**
139
+	 * array for defining default session vars
140
+	 *
141
+	 * @var array
142
+	 */
143
+	private $_default_session_vars = array(
144
+		'id'            => null,
145
+		'user_id'       => null,
146
+		'ip_address'    => null,
147
+		'user_agent'    => null,
148
+		'init_access'   => null,
149
+		'last_access'   => null,
150
+		'expiration'    => null,
151
+		'pages_visited' => array(),
152
+	);
153
+
154
+	/**
155
+	 * timestamp for when last garbage collection cycle was performed
156
+	 *
157
+	 * @var int $_last_gc
158
+	 */
159
+	private $_last_gc;
160
+
161
+	/**
162
+	 * @var RequestInterface $request
163
+	 */
164
+	protected $request;
165
+
166
+	/**
167
+	 * whether session is active or not
168
+	 *
169
+	 * @var int $status
170
+	 */
171
+	private $status = EE_Session::STATUS_CLOSED;
172
+
173
+
174
+	/**
175
+	 * @singleton method used to instantiate class object
176
+	 * @param CacheStorageInterface $cache_storage
177
+	 * @param SessionLifespan|null  $lifespan
178
+	 * @param RequestInterface      $request
179
+	 * @param SessionStartHandler   $session_start_handler
180
+	 * @param EE_Encryption         $encryption
181
+	 * @return EE_Session
182
+	 * @throws InvalidArgumentException
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws InvalidInterfaceException
185
+	 */
186
+	public static function instance(
187
+		CacheStorageInterface $cache_storage = null,
188
+		SessionLifespan $lifespan = null,
189
+		RequestInterface $request = null,
190
+		SessionStartHandler $session_start_handler = null,
191
+		EE_Encryption $encryption = null
192
+	) {
193
+		// check if class object is instantiated
194
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
195
+		// add_filter( 'FHEE_load_EE_Session', '__return_false' );
196
+		if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
197
+			self::$_instance = new self(
198
+				$cache_storage,
199
+				$lifespan,
200
+				$request,
201
+				$session_start_handler,
202
+				$encryption
203
+			);
204
+		}
205
+		return self::$_instance;
206
+	}
207
+
208
+
209
+	/**
210
+	 * protected constructor to prevent direct creation
211
+	 *
212
+	 * @param CacheStorageInterface $cache_storage
213
+	 * @param SessionLifespan       $lifespan
214
+	 * @param RequestInterface      $request
215
+	 * @param SessionStartHandler   $session_start_handler
216
+	 * @param EE_Encryption         $encryption
217
+	 * @throws InvalidArgumentException
218
+	 * @throws InvalidDataTypeException
219
+	 * @throws InvalidInterfaceException
220
+	 */
221
+	protected function __construct(
222
+		CacheStorageInterface $cache_storage,
223
+		SessionLifespan $lifespan,
224
+		RequestInterface $request,
225
+		SessionStartHandler $session_start_handler,
226
+		EE_Encryption $encryption = null
227
+	) {
228
+		// session loading is turned ON by default,
229
+		// but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
230
+		// (which currently fires on the init hook at priority 9),
231
+		// can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
232
+		if (! apply_filters('FHEE_load_EE_Session', true)) {
233
+			return;
234
+		}
235
+		$this->session_start_handler = $session_start_handler;
236
+		$this->session_lifespan = $lifespan;
237
+		$this->request = $request;
238
+		if (! defined('ESPRESSO_SESSION')) {
239
+			define('ESPRESSO_SESSION', true);
240
+		}
241
+		// retrieve session options from db
242
+		$session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
243
+		if (! empty($session_settings)) {
244
+			// cycle though existing session options
245
+			foreach ($session_settings as $var_name => $session_setting) {
246
+				// set values for class properties
247
+				$var_name = '_' . $var_name;
248
+				$this->{$var_name} = $session_setting;
249
+			}
250
+		}
251
+		$this->cache_storage = $cache_storage;
252
+		// are we using encryption?
253
+		$this->_use_encryption = $encryption instanceof EE_Encryption
254
+								 && EE_Registry::instance()->CFG->admin->encode_session_data();
255
+		// encrypt data via: $this->encryption->encrypt();
256
+		$this->encryption = $encryption;
257
+		// filter hook allows outside functions/classes/plugins to change default empty cart
258
+		$extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
259
+		array_merge($this->_default_session_vars, $extra_default_session_vars);
260
+		// apply default session vars
261
+		$this->_set_defaults();
262
+		add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
263
+		// check request for 'clear_session' param
264
+		add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
265
+		// once everything is all said and done,
266
+		add_action('shutdown', array($this, 'update'), 100);
267
+		add_action('shutdown', array($this, 'garbageCollection'), 1000);
268
+		$this->configure_garbage_collection_filters();
269
+	}
270
+
271
+
272
+	/**
273
+	 * @return bool
274
+	 * @throws InvalidArgumentException
275
+	 * @throws InvalidDataTypeException
276
+	 * @throws InvalidInterfaceException
277
+	 */
278
+	public static function isLoadedAndActive()
279
+	{
280
+		return did_action('AHEE__EE_System__core_loaded_and_ready')
281
+			   && EE_Session::instance() instanceof EE_Session
282
+			   && EE_Session::instance()->isActive();
283
+	}
284
+
285
+
286
+	/**
287
+	 * @return bool
288
+	 */
289
+	public function isActive()
290
+	{
291
+		return $this->status === EE_Session::STATUS_OPEN;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @return void
297
+	 * @throws EE_Error
298
+	 * @throws InvalidArgumentException
299
+	 * @throws InvalidDataTypeException
300
+	 * @throws InvalidInterfaceException
301
+	 * @throws InvalidSessionDataException
302
+	 */
303
+	public function open_session()
304
+	{
305
+		// check for existing session and retrieve it from db
306
+		if (! $this->_espresso_session()) {
307
+			// or just start a new one
308
+			$this->_create_espresso_session();
309
+		}
310
+	}
311
+
312
+
313
+	/**
314
+	 * @return bool
315
+	 */
316
+	public function expired()
317
+	{
318
+		return $this->_expired;
319
+	}
320
+
321
+
322
+	/**
323
+	 * @return void
324
+	 */
325
+	public function reset_expired()
326
+	{
327
+		$this->_expired = false;
328
+	}
329
+
330
+
331
+	/**
332
+	 * @return int
333
+	 */
334
+	public function expiration()
335
+	{
336
+		return $this->_expiration;
337
+	}
338
+
339
+
340
+	/**
341
+	 * @return int
342
+	 */
343
+	public function extension()
344
+	{
345
+		return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
346
+	}
347
+
348
+
349
+	/**
350
+	 * @param int $time number of seconds to add to session expiration
351
+	 */
352
+	public function extend_expiration($time = 0)
353
+	{
354
+		$time = $time ? $time : $this->extension();
355
+		$this->_expiration += absint($time);
356
+	}
357
+
358
+
359
+	/**
360
+	 * @return int
361
+	 */
362
+	public function lifespan()
363
+	{
364
+		return $this->session_lifespan->inSeconds();
365
+	}
366
+
367
+
368
+	/**
369
+	 * This just sets some defaults for the _session data property
370
+	 *
371
+	 * @access private
372
+	 * @return void
373
+	 */
374
+	private function _set_defaults()
375
+	{
376
+		// set some defaults
377
+		foreach ($this->_default_session_vars as $key => $default_var) {
378
+			if (is_array($default_var)) {
379
+				$this->_session_data[ $key ] = array();
380
+			} else {
381
+				$this->_session_data[ $key ] = '';
382
+			}
383
+		}
384
+	}
385
+
386
+
387
+	/**
388
+	 * @retrieve  session data
389
+	 * @access    public
390
+	 * @return    string
391
+	 */
392
+	public function id()
393
+	{
394
+		return $this->_sid;
395
+	}
396
+
397
+
398
+	/**
399
+	 * @param \EE_Cart $cart
400
+	 * @return bool
401
+	 */
402
+	public function set_cart(EE_Cart $cart)
403
+	{
404
+		$this->_session_data['cart'] = $cart;
405
+		return true;
406
+	}
407
+
408
+
409
+	/**
410
+	 * reset_cart
411
+	 */
412
+	public function reset_cart()
413
+	{
414
+		do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
415
+		$this->_session_data['cart'] = null;
416
+	}
417
+
418
+
419
+	/**
420
+	 * @return \EE_Cart
421
+	 */
422
+	public function cart()
423
+	{
424
+		return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
425
+			? $this->_session_data['cart']
426
+			: null;
427
+	}
428
+
429
+
430
+	/**
431
+	 * @param \EE_Checkout $checkout
432
+	 * @return bool
433
+	 */
434
+	public function set_checkout(EE_Checkout $checkout)
435
+	{
436
+		$this->_session_data['checkout'] = $checkout;
437
+		return true;
438
+	}
439
+
440
+
441
+	/**
442
+	 * reset_checkout
443
+	 */
444
+	public function reset_checkout()
445
+	{
446
+		do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
447
+		$this->_session_data['checkout'] = null;
448
+	}
449
+
450
+
451
+	/**
452
+	 * @return \EE_Checkout
453
+	 */
454
+	public function checkout()
455
+	{
456
+		return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
457
+			? $this->_session_data['checkout']
458
+			: null;
459
+	}
460
+
461
+
462
+	/**
463
+	 * @param \EE_Transaction $transaction
464
+	 * @return bool
465
+	 * @throws EE_Error
466
+	 */
467
+	public function set_transaction(EE_Transaction $transaction)
468
+	{
469
+		// first remove the session from the transaction before we save the transaction in the session
470
+		$transaction->set_txn_session_data(null);
471
+		$this->_session_data['transaction'] = $transaction;
472
+		return true;
473
+	}
474
+
475
+
476
+	/**
477
+	 * reset_transaction
478
+	 */
479
+	public function reset_transaction()
480
+	{
481
+		do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
482
+		$this->_session_data['transaction'] = null;
483
+	}
484
+
485
+
486
+	/**
487
+	 * @return \EE_Transaction
488
+	 */
489
+	public function transaction()
490
+	{
491
+		return isset($this->_session_data['transaction'])
492
+			   && $this->_session_data['transaction'] instanceof EE_Transaction
493
+			? $this->_session_data['transaction']
494
+			: null;
495
+	}
496
+
497
+
498
+	/**
499
+	 * retrieve session data
500
+	 *
501
+	 * @param null $key
502
+	 * @param bool $reset_cache
503
+	 * @return array
504
+	 */
505
+	public function get_session_data($key = null, $reset_cache = false)
506
+	{
507
+		if ($reset_cache) {
508
+			$this->reset_cart();
509
+			$this->reset_checkout();
510
+			$this->reset_transaction();
511
+		}
512
+		if (! empty($key)) {
513
+			return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
514
+		}
515
+		return $this->_session_data;
516
+	}
517
+
518
+
519
+	/**
520
+	 * Returns TRUE on success, FALSE on fail
521
+	 *
522
+	 * @param array $data
523
+	 * @return bool
524
+	 */
525
+	public function set_session_data($data)
526
+	{
527
+		// nothing ??? bad data ??? go home!
528
+		if (empty($data) || ! is_array($data)) {
529
+			EE_Error::add_error(
530
+				esc_html__(
531
+					'No session data or invalid session data was provided.',
532
+					'event_espresso'
533
+				),
534
+				__FILE__,
535
+				__FUNCTION__,
536
+				__LINE__
537
+			);
538
+			return false;
539
+		}
540
+		foreach ($data as $key => $value) {
541
+			if (isset($this->_default_session_vars[ $key ])) {
542
+				EE_Error::add_error(
543
+					sprintf(
544
+						esc_html__(
545
+							'Sorry! %s is a default session datum and can not be reset.',
546
+							'event_espresso'
547
+						),
548
+						$key
549
+					),
550
+					__FILE__,
551
+					__FUNCTION__,
552
+					__LINE__
553
+				);
554
+				return false;
555
+			}
556
+			$this->_session_data[ $key ] = $value;
557
+		}
558
+		return true;
559
+	}
560
+
561
+
562
+	/**
563
+	 * @initiate session
564
+	 * @access   private
565
+	 * @return TRUE on success, FALSE on fail
566
+	 * @throws EE_Error
567
+	 * @throws InvalidArgumentException
568
+	 * @throws InvalidDataTypeException
569
+	 * @throws InvalidInterfaceException
570
+	 * @throws InvalidSessionDataException
571
+	 */
572
+	private function _espresso_session()
573
+	{
574
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
575
+		$this->session_start_handler->startSession();
576
+		$this->status = EE_Session::STATUS_OPEN;
577
+		// get our modified session ID
578
+		$this->_sid = $this->_generate_session_id();
579
+		// and the visitors IP
580
+		$this->_ip_address = $this->request->ipAddress();
581
+		// set the "user agent"
582
+		$this->_user_agent = $this->request->userAgent();
583
+		// now let's retrieve what's in the db
584
+		$session_data = $this->_retrieve_session_data();
585
+		if (! empty($session_data)) {
586
+			// get the current time in UTC
587
+			$this->_time = $this->_time !== null ? $this->_time : time();
588
+			// and reset the session expiration
589
+			$this->_expiration = isset($session_data['expiration'])
590
+				? $session_data['expiration']
591
+				: $this->_time + $this->session_lifespan->inSeconds();
592
+		} else {
593
+			// set initial site access time and the session expiration
594
+			$this->_set_init_access_and_expiration();
595
+			// set referer
596
+			$this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
597
+				? esc_attr($_SERVER['HTTP_REFERER'])
598
+				: '';
599
+			// no previous session = go back and create one (on top of the data above)
600
+			return false;
601
+		}
602
+		// now the user agent
603
+		if ($session_data['user_agent'] !== $this->_user_agent) {
604
+			return false;
605
+		}
606
+		// wait a minute... how old are you?
607
+		if ($this->_time > $this->_expiration) {
608
+			// yer too old fer me!
609
+			$this->_expired = true;
610
+			// wipe out everything that isn't a default session datum
611
+			$this->clear_session(__CLASS__, __FUNCTION__);
612
+		}
613
+		// make event espresso session data available to plugin
614
+		$this->_session_data = array_merge($this->_session_data, $session_data);
615
+		return true;
616
+	}
617
+
618
+
619
+	/**
620
+	 * _get_session_data
621
+	 * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
622
+	 * databases
623
+	 *
624
+	 * @return array
625
+	 * @throws EE_Error
626
+	 * @throws InvalidArgumentException
627
+	 * @throws InvalidSessionDataException
628
+	 * @throws InvalidDataTypeException
629
+	 * @throws InvalidInterfaceException
630
+	 */
631
+	protected function _retrieve_session_data()
632
+	{
633
+		$ssn_key = EE_Session::session_id_prefix . $this->_sid;
634
+		try {
635
+			// we're using WP's Transient API to store session data using the PHP session ID as the option name
636
+			$session_data = $this->cache_storage->get($ssn_key, false);
637
+			if (empty($session_data)) {
638
+				return array();
639
+			}
640
+			if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
641
+				$hash_check = $this->cache_storage->get(
642
+					EE_Session::hash_check_prefix . $this->_sid,
643
+					false
644
+				);
645
+				if ($hash_check && $hash_check !== md5($session_data)) {
646
+					EE_Error::add_error(
647
+						sprintf(
648
+							__(
649
+								'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
650
+								'event_espresso'
651
+							),
652
+							EE_Session::session_id_prefix . $this->_sid
653
+						),
654
+						__FILE__,
655
+						__FUNCTION__,
656
+						__LINE__
657
+					);
658
+				}
659
+			}
660
+		} catch (Exception $e) {
661
+			// let's just eat that error for now and attempt to correct any corrupted data
662
+			global $wpdb;
663
+			$row = $wpdb->get_row(
664
+				$wpdb->prepare(
665
+					"SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
666
+					'_transient_' . $ssn_key
667
+				)
668
+			);
669
+			$session_data = is_object($row) ? $row->option_value : null;
670
+			if ($session_data) {
671
+				$session_data = preg_replace_callback(
672
+					'!s:(d+):"(.*?)";!',
673
+					function ($match) {
674
+						return $match[1] === strlen($match[2])
675
+							? $match[0]
676
+							: 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
677
+					},
678
+					$session_data
679
+				);
680
+			}
681
+			$session_data = maybe_unserialize($session_data);
682
+		}
683
+		// in case the data is encoded... try to decode it
684
+		$session_data = $this->encryption instanceof EE_Encryption
685
+			? $this->encryption->base64_string_decode($session_data)
686
+			: $session_data;
687
+		if (! is_array($session_data)) {
688
+			try {
689
+				$session_data = maybe_unserialize($session_data);
690
+			} catch (Exception $e) {
691
+				$msg = esc_html__(
692
+					'An error occurred while attempting to unserialize the session data.',
693
+					'event_espresso'
694
+				);
695
+				$msg .= WP_DEBUG
696
+					? '<br><pre>'
697
+					  . print_r($session_data, true)
698
+					  . '</pre><br>'
699
+					  . $this->find_serialize_error($session_data)
700
+					: '';
701
+				$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
702
+				throw new InvalidSessionDataException($msg, 0, $e);
703
+			}
704
+		}
705
+		// just a check to make sure the session array is indeed an array
706
+		if (! is_array($session_data)) {
707
+			// no?!?! then something is wrong
708
+			$msg = esc_html__(
709
+				'The session data is missing, invalid, or corrupted.',
710
+				'event_espresso'
711
+			);
712
+			$msg .= WP_DEBUG
713
+				? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
714
+				: '';
715
+			$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
716
+			throw new InvalidSessionDataException($msg);
717
+		}
718
+		if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
719
+			$session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
720
+				$session_data['transaction']
721
+			);
722
+		}
723
+		return $session_data;
724
+	}
725
+
726
+
727
+	/**
728
+	 * _generate_session_id
729
+	 * Retrieves the PHP session id either directly from the PHP session,
730
+	 * or from the $_REQUEST array if it was passed in from an AJAX request.
731
+	 * The session id is then salted and hashed (mmm sounds tasty)
732
+	 * so that it can be safely used as a $_REQUEST param
733
+	 *
734
+	 * @return string
735
+	 */
736
+	protected function _generate_session_id()
737
+	{
738
+		// check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
739
+		if (isset($_REQUEST['EESID'])) {
740
+			$session_id = sanitize_text_field($_REQUEST['EESID']);
741
+		} else {
742
+			$session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
743
+		}
744
+		return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
745
+	}
746
+
747
+
748
+	/**
749
+	 * _get_sid_salt
750
+	 *
751
+	 * @return string
752
+	 */
753
+	protected function _get_sid_salt()
754
+	{
755
+		// was session id salt already saved to db ?
756
+		if (empty($this->_sid_salt)) {
757
+			// no?  then maybe use WP defined constant
758
+			if (defined('AUTH_SALT')) {
759
+				$this->_sid_salt = AUTH_SALT;
760
+			}
761
+			// if salt doesn't exist or is too short
762
+			if (strlen($this->_sid_salt) < 32) {
763
+				// create a new one
764
+				$this->_sid_salt = wp_generate_password(64);
765
+			}
766
+			// and save it as a permanent session setting
767
+			$this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
768
+		}
769
+		return $this->_sid_salt;
770
+	}
771
+
772
+
773
+	/**
774
+	 * _set_init_access_and_expiration
775
+	 *
776
+	 * @return void
777
+	 */
778
+	protected function _set_init_access_and_expiration()
779
+	{
780
+		$this->_time = time();
781
+		$this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
782
+		// set initial site access time
783
+		$this->_session_data['init_access'] = $this->_time;
784
+		// and the session expiration
785
+		$this->_session_data['expiration'] = $this->_expiration;
786
+	}
787
+
788
+
789
+	/**
790
+	 * @update session data  prior to saving to the db
791
+	 * @access public
792
+	 * @param bool $new_session
793
+	 * @return TRUE on success, FALSE on fail
794
+	 * @throws EE_Error
795
+	 * @throws InvalidArgumentException
796
+	 * @throws InvalidDataTypeException
797
+	 * @throws InvalidInterfaceException
798
+	 */
799
+	public function update($new_session = false)
800
+	{
801
+		$this->_session_data = $this->_session_data !== null
802
+							   && is_array($this->_session_data)
803
+							   && isset($this->_session_data['id'])
804
+			? $this->_session_data
805
+			: array();
806
+		if (empty($this->_session_data)) {
807
+			$this->_set_defaults();
808
+		}
809
+		$session_data = array();
810
+		foreach ($this->_session_data as $key => $value) {
811
+			switch ($key) {
812
+				case 'id':
813
+					// session ID
814
+					$session_data['id'] = $this->_sid;
815
+					break;
816
+				case 'ip_address':
817
+					// visitor ip address
818
+					$session_data['ip_address'] = $this->request->ipAddress();
819
+					break;
820
+				case 'user_agent':
821
+					// visitor user_agent
822
+					$session_data['user_agent'] = $this->_user_agent;
823
+					break;
824
+				case 'init_access':
825
+					$session_data['init_access'] = absint($value);
826
+					break;
827
+				case 'last_access':
828
+					// current access time
829
+					$session_data['last_access'] = $this->_time;
830
+					break;
831
+				case 'expiration':
832
+					// when the session expires
833
+					$session_data['expiration'] = ! empty($this->_expiration)
834
+						? $this->_expiration
835
+						: $session_data['init_access'] + $this->session_lifespan->inSeconds();
836
+					break;
837
+				case 'user_id':
838
+					// current user if logged in
839
+					$session_data['user_id'] = $this->_wp_user_id();
840
+					break;
841
+				case 'pages_visited':
842
+					$page_visit = $this->_get_page_visit();
843
+					if ($page_visit) {
844
+						// set pages visited where the first will be the http referrer
845
+						$this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
846
+						// we'll only save the last 10 page visits.
847
+						$session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
848
+					}
849
+					break;
850
+				default:
851
+					// carry any other data over
852
+					$session_data[ $key ] = $this->_session_data[ $key ];
853
+			}
854
+		}
855
+		$this->_session_data = $session_data;
856
+		// creating a new session does not require saving to the db just yet
857
+		if (! $new_session) {
858
+			// ready? let's save
859
+			if ($this->_save_session_to_db()) {
860
+				return true;
861
+			}
862
+			return false;
863
+		}
864
+		// meh, why not?
865
+		return true;
866
+	}
867
+
868
+
869
+	/**
870
+	 * @create session data array
871
+	 * @access public
872
+	 * @return bool
873
+	 * @throws EE_Error
874
+	 * @throws InvalidArgumentException
875
+	 * @throws InvalidDataTypeException
876
+	 * @throws InvalidInterfaceException
877
+	 */
878
+	private function _create_espresso_session()
879
+	{
880
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
881
+		// use the update function for now with $new_session arg set to TRUE
882
+		return $this->update(true) ? true : false;
883
+	}
884
+
885
+	/**
886
+	 * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
887
+	 * too). This is used when determining if we want to save the session or not.
888
+	 * @since 4.9.67.p
889
+	 * @return bool
890
+	 */
891
+	private function sessionHasStuffWorthSaving()
892
+	{
893
+		return $this->cart() instanceof EE_Cart
894
+			|| (
895
+				isset($this->_session_data['ee_notices'])
896
+				&& (
897
+					! empty($this->_session_data['ee_notices']['attention'])
898
+					|| !empty($this->_session_data['ee_notices']['errors'])
899
+					|| !empty($this->_session_data['ee_notices']['success'])
900
+				)
901
+			);
902
+	}
903
+	/**
904
+	 * _save_session_to_db
905
+	 *
906
+	 * @param bool $clear_session
907
+	 * @return string
908
+	 * @throws EE_Error
909
+	 * @throws InvalidArgumentException
910
+	 * @throws InvalidDataTypeException
911
+	 * @throws InvalidInterfaceException
912
+	 */
913
+	private function _save_session_to_db($clear_session = false)
914
+	{
915
+		// don't save sessions for crawlers
916
+		// and unless we're deleting the session data, don't save anything if there isn't a cart
917
+		if ($this->request->isBot()
918
+			|| (
919
+				! $clear_session
920
+				&& ! $this->sessionHasStuffWorthSaving()
921
+				&& apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
922
+			)
923
+		) {
924
+			return false;
925
+		}
926
+		$transaction = $this->transaction();
927
+		if ($transaction instanceof EE_Transaction) {
928
+			if (! $transaction->ID()) {
929
+				$transaction->save();
930
+			}
931
+			$this->_session_data['transaction'] = $transaction->ID();
932
+		}
933
+		// then serialize all of our session data
934
+		$session_data = serialize($this->_session_data);
935
+		// do we need to also encode it to avoid corrupted data when saved to the db?
936
+		$session_data = $this->_use_encryption
937
+			? $this->encryption->base64_string_encode($session_data)
938
+			: $session_data;
939
+		// maybe save hash check
940
+		if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
941
+			$this->cache_storage->add(
942
+				EE_Session::hash_check_prefix . $this->_sid,
943
+				md5($session_data),
944
+				$this->session_lifespan->inSeconds()
945
+			);
946
+		}
947
+		// we're using the Transient API for storing session data,
948
+		return $this->cache_storage->add(
949
+			EE_Session::session_id_prefix . $this->_sid,
950
+			$session_data,
951
+			$this->session_lifespan->inSeconds()
952
+		);
953
+	}
954
+
955
+
956
+	/**
957
+	 * @get    the full page request the visitor is accessing
958
+	 * @access public
959
+	 * @return string
960
+	 */
961
+	public function _get_page_visit()
962
+	{
963
+		$page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
964
+		// check for request url
965
+		if (isset($_SERVER['REQUEST_URI'])) {
966
+			$http_host = '';
967
+			$page_id = '?';
968
+			$e_reg = '';
969
+			$request_uri = esc_url($_SERVER['REQUEST_URI']);
970
+			$ru_bits = explode('?', $request_uri);
971
+			$request_uri = $ru_bits[0];
972
+			// check for and grab host as well
973
+			if (isset($_SERVER['HTTP_HOST'])) {
974
+				$http_host = esc_url($_SERVER['HTTP_HOST']);
975
+			}
976
+			// check for page_id in SERVER REQUEST
977
+			if (isset($_REQUEST['page_id'])) {
978
+				// rebuild $e_reg without any of the extra parameters
979
+				$page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
980
+			}
981
+			// check for $e_reg in SERVER REQUEST
982
+			if (isset($_REQUEST['ee'])) {
983
+				// rebuild $e_reg without any of the extra parameters
984
+				$e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
985
+			}
986
+			$page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
987
+		}
988
+		return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
989
+	}
990
+
991
+
992
+	/**
993
+	 * @the    current wp user id
994
+	 * @access public
995
+	 * @return int
996
+	 */
997
+	public function _wp_user_id()
998
+	{
999
+		// if I need to explain the following lines of code, then you shouldn't be looking at this!
1000
+		$this->_wp_user_id = get_current_user_id();
1001
+		return $this->_wp_user_id;
1002
+	}
1003
+
1004
+
1005
+	/**
1006
+	 * Clear EE_Session data
1007
+	 *
1008
+	 * @access public
1009
+	 * @param string $class
1010
+	 * @param string $function
1011
+	 * @return void
1012
+	 * @throws EE_Error
1013
+	 * @throws InvalidArgumentException
1014
+	 * @throws InvalidDataTypeException
1015
+	 * @throws InvalidInterfaceException
1016
+	 */
1017
+	public function clear_session($class = '', $function = '')
1018
+	{
1019 1019
 //         echo '
1020 1020
 // <h3 style="color:#999;line-height:.9em;">
1021 1021
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1022 1022
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1023 1023
 // </h3>';
1024
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1025
-        $this->reset_cart();
1026
-        $this->reset_checkout();
1027
-        $this->reset_transaction();
1028
-        // wipe out everything that isn't a default session datum
1029
-        $this->reset_data(array_keys($this->_session_data));
1030
-        // reset initial site access time and the session expiration
1031
-        $this->_set_init_access_and_expiration();
1032
-        $this->_save_session_to_db(true);
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1038
-     *
1039
-     * @param array|mixed $data_to_reset
1040
-     * @param bool        $show_all_notices
1041
-     * @return bool
1042
-     */
1043
-    public function reset_data($data_to_reset = array(), $show_all_notices = false)
1044
-    {
1045
-        // if $data_to_reset is not in an array, then put it in one
1046
-        if (! is_array($data_to_reset)) {
1047
-            $data_to_reset = array($data_to_reset);
1048
-        }
1049
-        // nothing ??? go home!
1050
-        if (empty($data_to_reset)) {
1051
-            EE_Error::add_error(
1052
-                __(
1053
-                    'No session data could be reset, because no session var name was provided.',
1054
-                    'event_espresso'
1055
-                ),
1056
-                __FILE__,
1057
-                __FUNCTION__,
1058
-                __LINE__
1059
-            );
1060
-            return false;
1061
-        }
1062
-        $return_value = true;
1063
-        // since $data_to_reset is an array, cycle through the values
1064
-        foreach ($data_to_reset as $reset) {
1065
-            // first check to make sure it is a valid session var
1066
-            if (isset($this->_session_data[ $reset ])) {
1067
-                // then check to make sure it is not a default var
1068
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1069
-                    // remove session var
1070
-                    unset($this->_session_data[ $reset ]);
1071
-                    if ($show_all_notices) {
1072
-                        EE_Error::add_success(
1073
-                            sprintf(
1074
-                                __('The session variable %s was removed.', 'event_espresso'),
1075
-                                $reset
1076
-                            ),
1077
-                            __FILE__,
1078
-                            __FUNCTION__,
1079
-                            __LINE__
1080
-                        );
1081
-                    }
1082
-                } else {
1083
-                    // yeeeeeeeeerrrrrrrrrrr OUT !!!!
1084
-                    if ($show_all_notices) {
1085
-                        EE_Error::add_error(
1086
-                            sprintf(
1087
-                                __(
1088
-                                    'Sorry! %s is a default session datum and can not be reset.',
1089
-                                    'event_espresso'
1090
-                                ),
1091
-                                $reset
1092
-                            ),
1093
-                            __FILE__,
1094
-                            __FUNCTION__,
1095
-                            __LINE__
1096
-                        );
1097
-                    }
1098
-                    $return_value = false;
1099
-                }
1100
-            } elseif ($show_all_notices) {
1101
-                // oops! that session var does not exist!
1102
-                EE_Error::add_error(
1103
-                    sprintf(
1104
-                        __(
1105
-                            'The session item provided, %s, is invalid or does not exist.',
1106
-                            'event_espresso'
1107
-                        ),
1108
-                        $reset
1109
-                    ),
1110
-                    __FILE__,
1111
-                    __FUNCTION__,
1112
-                    __LINE__
1113
-                );
1114
-                $return_value = false;
1115
-            }
1116
-        } // end of foreach
1117
-        return $return_value;
1118
-    }
1119
-
1120
-
1121
-    /**
1122
-     *   wp_loaded
1123
-     *
1124
-     * @access public
1125
-     * @throws EE_Error
1126
-     * @throws InvalidDataTypeException
1127
-     * @throws InvalidInterfaceException
1128
-     * @throws InvalidArgumentException
1129
-     */
1130
-    public function wp_loaded()
1131
-    {
1132
-        if ($this->request->requestParamIsSet('clear_session')) {
1133
-            $this->clear_session(__CLASS__, __FUNCTION__);
1134
-        }
1135
-    }
1136
-
1137
-
1138
-    /**
1139
-     * Used to reset the entire object (for tests).
1140
-     *
1141
-     * @since 4.3.0
1142
-     * @throws EE_Error
1143
-     * @throws InvalidDataTypeException
1144
-     * @throws InvalidInterfaceException
1145
-     * @throws InvalidArgumentException
1146
-     */
1147
-    public function reset_instance()
1148
-    {
1149
-        $this->clear_session();
1150
-        self::$_instance = null;
1151
-    }
1152
-
1153
-
1154
-    public function configure_garbage_collection_filters()
1155
-    {
1156
-        // run old filter we had for controlling session cleanup
1157
-        $expired_session_transient_delete_query_limit = absint(
1158
-            apply_filters(
1159
-                'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1160
-                50
1161
-            )
1162
-        );
1163
-        // is there a value? or one that is different than the default 50 records?
1164
-        if ($expired_session_transient_delete_query_limit === 0) {
1165
-            // hook into TransientCacheStorage in case Session cleanup was turned off
1166
-            add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1167
-        } elseif ($expired_session_transient_delete_query_limit !== 50) {
1168
-            // or use that for the new transient cleanup query limit
1169
-            add_filter(
1170
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1171
-                function () use ($expired_session_transient_delete_query_limit) {
1172
-                    return $expired_session_transient_delete_query_limit;
1173
-                }
1174
-            );
1175
-        }
1176
-    }
1177
-
1178
-
1179
-    /**
1180
-     * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1181
-     * @param $data1
1182
-     * @return string
1183
-     */
1184
-    private function find_serialize_error($data1)
1185
-    {
1186
-        $error = '<pre>';
1187
-        $data2 = preg_replace_callback(
1188
-            '!s:(\d+):"(.*?)";!',
1189
-            function ($match) {
1190
-                return ($match[1] === strlen($match[2]))
1191
-                    ? $match[0]
1192
-                    : 's:'
1193
-                      . strlen($match[2])
1194
-                      . ':"'
1195
-                      . $match[2]
1196
-                      . '";';
1197
-            },
1198
-            $data1
1199
-        );
1200
-        $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1201
-        $error .= $data1 . PHP_EOL;
1202
-        $error .= $data2 . PHP_EOL;
1203
-        for ($i = 0; $i < $max; $i++) {
1204
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1205
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1206
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1207
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1208
-                $start = ($i - 20);
1209
-                $start = ($start < 0) ? 0 : $start;
1210
-                $length = 40;
1211
-                $point = $max - $i;
1212
-                if ($point < 20) {
1213
-                    $rlength = 1;
1214
-                    $rpoint = -$point;
1215
-                } else {
1216
-                    $rpoint = $length - 20;
1217
-                    $rlength = 1;
1218
-                }
1219
-                $error .= "\t-> Section Data1  = ";
1220
-                $error .= substr_replace(
1221
-                    substr($data1, $start, $length),
1222
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1223
-                    $rpoint,
1224
-                    $rlength
1225
-                );
1226
-                $error .= PHP_EOL;
1227
-                $error .= "\t-> Section Data2  = ";
1228
-                $error .= substr_replace(
1229
-                    substr($data2, $start, $length),
1230
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1231
-                    $rpoint,
1232
-                    $rlength
1233
-                );
1234
-                $error .= PHP_EOL;
1235
-            }
1236
-        }
1237
-        $error .= '</pre>';
1238
-        return $error;
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * Saves an  array of settings used for configuring aspects of session behaviour
1244
-     *
1245
-     * @param array $updated_settings
1246
-     */
1247
-    private function updateSessionSettings(array $updated_settings = array())
1248
-    {
1249
-        // add existing settings, but only if not included in incoming $updated_settings array
1250
-        $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1251
-        update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1252
-    }
1253
-
1254
-
1255
-    /**
1256
-     * garbage_collection
1257
-     */
1258
-    public function garbageCollection()
1259
-    {
1260
-        // only perform during regular requests if last garbage collection was over an hour ago
1261
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1262
-            $this->_last_gc = time();
1263
-            $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1264
-            /** @type WPDB $wpdb */
1265
-            global $wpdb;
1266
-            // filter the query limit. Set to 0 to turn off garbage collection
1267
-            $expired_session_transient_delete_query_limit = absint(
1268
-                apply_filters(
1269
-                    'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1270
-                    50
1271
-                )
1272
-            );
1273
-            // non-zero LIMIT means take out the trash
1274
-            if ($expired_session_transient_delete_query_limit) {
1275
-                $session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1276
-                $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1277
-                // since transient expiration timestamps are set in the future, we can compare against NOW
1278
-                // but we only want to pick up any trash that's been around for more than a day
1279
-                $expiration = time() - DAY_IN_SECONDS;
1280
-                $SQL = "
1024
+		do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1025
+		$this->reset_cart();
1026
+		$this->reset_checkout();
1027
+		$this->reset_transaction();
1028
+		// wipe out everything that isn't a default session datum
1029
+		$this->reset_data(array_keys($this->_session_data));
1030
+		// reset initial site access time and the session expiration
1031
+		$this->_set_init_access_and_expiration();
1032
+		$this->_save_session_to_db(true);
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1038
+	 *
1039
+	 * @param array|mixed $data_to_reset
1040
+	 * @param bool        $show_all_notices
1041
+	 * @return bool
1042
+	 */
1043
+	public function reset_data($data_to_reset = array(), $show_all_notices = false)
1044
+	{
1045
+		// if $data_to_reset is not in an array, then put it in one
1046
+		if (! is_array($data_to_reset)) {
1047
+			$data_to_reset = array($data_to_reset);
1048
+		}
1049
+		// nothing ??? go home!
1050
+		if (empty($data_to_reset)) {
1051
+			EE_Error::add_error(
1052
+				__(
1053
+					'No session data could be reset, because no session var name was provided.',
1054
+					'event_espresso'
1055
+				),
1056
+				__FILE__,
1057
+				__FUNCTION__,
1058
+				__LINE__
1059
+			);
1060
+			return false;
1061
+		}
1062
+		$return_value = true;
1063
+		// since $data_to_reset is an array, cycle through the values
1064
+		foreach ($data_to_reset as $reset) {
1065
+			// first check to make sure it is a valid session var
1066
+			if (isset($this->_session_data[ $reset ])) {
1067
+				// then check to make sure it is not a default var
1068
+				if (! array_key_exists($reset, $this->_default_session_vars)) {
1069
+					// remove session var
1070
+					unset($this->_session_data[ $reset ]);
1071
+					if ($show_all_notices) {
1072
+						EE_Error::add_success(
1073
+							sprintf(
1074
+								__('The session variable %s was removed.', 'event_espresso'),
1075
+								$reset
1076
+							),
1077
+							__FILE__,
1078
+							__FUNCTION__,
1079
+							__LINE__
1080
+						);
1081
+					}
1082
+				} else {
1083
+					// yeeeeeeeeerrrrrrrrrrr OUT !!!!
1084
+					if ($show_all_notices) {
1085
+						EE_Error::add_error(
1086
+							sprintf(
1087
+								__(
1088
+									'Sorry! %s is a default session datum and can not be reset.',
1089
+									'event_espresso'
1090
+								),
1091
+								$reset
1092
+							),
1093
+							__FILE__,
1094
+							__FUNCTION__,
1095
+							__LINE__
1096
+						);
1097
+					}
1098
+					$return_value = false;
1099
+				}
1100
+			} elseif ($show_all_notices) {
1101
+				// oops! that session var does not exist!
1102
+				EE_Error::add_error(
1103
+					sprintf(
1104
+						__(
1105
+							'The session item provided, %s, is invalid or does not exist.',
1106
+							'event_espresso'
1107
+						),
1108
+						$reset
1109
+					),
1110
+					__FILE__,
1111
+					__FUNCTION__,
1112
+					__LINE__
1113
+				);
1114
+				$return_value = false;
1115
+			}
1116
+		} // end of foreach
1117
+		return $return_value;
1118
+	}
1119
+
1120
+
1121
+	/**
1122
+	 *   wp_loaded
1123
+	 *
1124
+	 * @access public
1125
+	 * @throws EE_Error
1126
+	 * @throws InvalidDataTypeException
1127
+	 * @throws InvalidInterfaceException
1128
+	 * @throws InvalidArgumentException
1129
+	 */
1130
+	public function wp_loaded()
1131
+	{
1132
+		if ($this->request->requestParamIsSet('clear_session')) {
1133
+			$this->clear_session(__CLASS__, __FUNCTION__);
1134
+		}
1135
+	}
1136
+
1137
+
1138
+	/**
1139
+	 * Used to reset the entire object (for tests).
1140
+	 *
1141
+	 * @since 4.3.0
1142
+	 * @throws EE_Error
1143
+	 * @throws InvalidDataTypeException
1144
+	 * @throws InvalidInterfaceException
1145
+	 * @throws InvalidArgumentException
1146
+	 */
1147
+	public function reset_instance()
1148
+	{
1149
+		$this->clear_session();
1150
+		self::$_instance = null;
1151
+	}
1152
+
1153
+
1154
+	public function configure_garbage_collection_filters()
1155
+	{
1156
+		// run old filter we had for controlling session cleanup
1157
+		$expired_session_transient_delete_query_limit = absint(
1158
+			apply_filters(
1159
+				'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1160
+				50
1161
+			)
1162
+		);
1163
+		// is there a value? or one that is different than the default 50 records?
1164
+		if ($expired_session_transient_delete_query_limit === 0) {
1165
+			// hook into TransientCacheStorage in case Session cleanup was turned off
1166
+			add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1167
+		} elseif ($expired_session_transient_delete_query_limit !== 50) {
1168
+			// or use that for the new transient cleanup query limit
1169
+			add_filter(
1170
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1171
+				function () use ($expired_session_transient_delete_query_limit) {
1172
+					return $expired_session_transient_delete_query_limit;
1173
+				}
1174
+			);
1175
+		}
1176
+	}
1177
+
1178
+
1179
+	/**
1180
+	 * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1181
+	 * @param $data1
1182
+	 * @return string
1183
+	 */
1184
+	private function find_serialize_error($data1)
1185
+	{
1186
+		$error = '<pre>';
1187
+		$data2 = preg_replace_callback(
1188
+			'!s:(\d+):"(.*?)";!',
1189
+			function ($match) {
1190
+				return ($match[1] === strlen($match[2]))
1191
+					? $match[0]
1192
+					: 's:'
1193
+					  . strlen($match[2])
1194
+					  . ':"'
1195
+					  . $match[2]
1196
+					  . '";';
1197
+			},
1198
+			$data1
1199
+		);
1200
+		$max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1201
+		$error .= $data1 . PHP_EOL;
1202
+		$error .= $data2 . PHP_EOL;
1203
+		for ($i = 0; $i < $max; $i++) {
1204
+			if (@$data1[ $i ] !== @$data2[ $i ]) {
1205
+				$error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1206
+				$error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1207
+				$error .= "\t-> Line Number = $i" . PHP_EOL;
1208
+				$start = ($i - 20);
1209
+				$start = ($start < 0) ? 0 : $start;
1210
+				$length = 40;
1211
+				$point = $max - $i;
1212
+				if ($point < 20) {
1213
+					$rlength = 1;
1214
+					$rpoint = -$point;
1215
+				} else {
1216
+					$rpoint = $length - 20;
1217
+					$rlength = 1;
1218
+				}
1219
+				$error .= "\t-> Section Data1  = ";
1220
+				$error .= substr_replace(
1221
+					substr($data1, $start, $length),
1222
+					"<b style=\"color:green\">{$data1[ $i ]}</b>",
1223
+					$rpoint,
1224
+					$rlength
1225
+				);
1226
+				$error .= PHP_EOL;
1227
+				$error .= "\t-> Section Data2  = ";
1228
+				$error .= substr_replace(
1229
+					substr($data2, $start, $length),
1230
+					"<b style=\"color:red\">{$data2[ $i ]}</b>",
1231
+					$rpoint,
1232
+					$rlength
1233
+				);
1234
+				$error .= PHP_EOL;
1235
+			}
1236
+		}
1237
+		$error .= '</pre>';
1238
+		return $error;
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * Saves an  array of settings used for configuring aspects of session behaviour
1244
+	 *
1245
+	 * @param array $updated_settings
1246
+	 */
1247
+	private function updateSessionSettings(array $updated_settings = array())
1248
+	{
1249
+		// add existing settings, but only if not included in incoming $updated_settings array
1250
+		$updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1251
+		update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1252
+	}
1253
+
1254
+
1255
+	/**
1256
+	 * garbage_collection
1257
+	 */
1258
+	public function garbageCollection()
1259
+	{
1260
+		// only perform during regular requests if last garbage collection was over an hour ago
1261
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1262
+			$this->_last_gc = time();
1263
+			$this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1264
+			/** @type WPDB $wpdb */
1265
+			global $wpdb;
1266
+			// filter the query limit. Set to 0 to turn off garbage collection
1267
+			$expired_session_transient_delete_query_limit = absint(
1268
+				apply_filters(
1269
+					'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1270
+					50
1271
+				)
1272
+			);
1273
+			// non-zero LIMIT means take out the trash
1274
+			if ($expired_session_transient_delete_query_limit) {
1275
+				$session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1276
+				$hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1277
+				// since transient expiration timestamps are set in the future, we can compare against NOW
1278
+				// but we only want to pick up any trash that's been around for more than a day
1279
+				$expiration = time() - DAY_IN_SECONDS;
1280
+				$SQL = "
1281 1281
                     SELECT option_name
1282 1282
                     FROM {$wpdb->options}
1283 1283
                     WHERE
@@ -1286,17 +1286,17 @@  discard block
 block discarded – undo
1286 1286
                     AND option_value < {$expiration}
1287 1287
                     LIMIT {$expired_session_transient_delete_query_limit}
1288 1288
                 ";
1289
-                // produces something like:
1290
-                // SELECT option_name FROM wp_options
1291
-                // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1292
-                // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1293
-                // AND option_value < 1508368198 LIMIT 50
1294
-                $expired_sessions = $wpdb->get_col($SQL);
1295
-                // valid results?
1296
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1297
-                    $this->cache_storage->deleteMany($expired_sessions, true);
1298
-                }
1299
-            }
1300
-        }
1301
-    }
1289
+				// produces something like:
1290
+				// SELECT option_name FROM wp_options
1291
+				// WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1292
+				// OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1293
+				// AND option_value < 1508368198 LIMIT 50
1294
+				$expired_sessions = $wpdb->get_col($SQL);
1295
+				// valid results?
1296
+				if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1297
+					$this->cache_storage->deleteMany($expired_sessions, true);
1298
+				}
1299
+			}
1300
+		}
1301
+	}
1302 1302
 }
Please login to merge, or discard this patch.
Spacing   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -193,7 +193,7 @@  discard block
 block discarded – undo
193 193
         // check if class object is instantiated
194 194
         // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
195 195
         // add_filter( 'FHEE_load_EE_Session', '__return_false' );
196
-        if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
196
+        if ( ! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
197 197
             self::$_instance = new self(
198 198
                 $cache_storage,
199 199
                 $lifespan,
@@ -229,22 +229,22 @@  discard block
 block discarded – undo
229 229
         // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
230 230
         // (which currently fires on the init hook at priority 9),
231 231
         // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
232
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
232
+        if ( ! apply_filters('FHEE_load_EE_Session', true)) {
233 233
             return;
234 234
         }
235 235
         $this->session_start_handler = $session_start_handler;
236 236
         $this->session_lifespan = $lifespan;
237 237
         $this->request = $request;
238
-        if (! defined('ESPRESSO_SESSION')) {
238
+        if ( ! defined('ESPRESSO_SESSION')) {
239 239
             define('ESPRESSO_SESSION', true);
240 240
         }
241 241
         // retrieve session options from db
242 242
         $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
243
-        if (! empty($session_settings)) {
243
+        if ( ! empty($session_settings)) {
244 244
             // cycle though existing session options
245 245
             foreach ($session_settings as $var_name => $session_setting) {
246 246
                 // set values for class properties
247
-                $var_name = '_' . $var_name;
247
+                $var_name = '_'.$var_name;
248 248
                 $this->{$var_name} = $session_setting;
249 249
             }
250 250
         }
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
     public function open_session()
304 304
     {
305 305
         // check for existing session and retrieve it from db
306
-        if (! $this->_espresso_session()) {
306
+        if ( ! $this->_espresso_session()) {
307 307
             // or just start a new one
308 308
             $this->_create_espresso_session();
309 309
         }
@@ -376,9 +376,9 @@  discard block
 block discarded – undo
376 376
         // set some defaults
377 377
         foreach ($this->_default_session_vars as $key => $default_var) {
378 378
             if (is_array($default_var)) {
379
-                $this->_session_data[ $key ] = array();
379
+                $this->_session_data[$key] = array();
380 380
             } else {
381
-                $this->_session_data[ $key ] = '';
381
+                $this->_session_data[$key] = '';
382 382
             }
383 383
         }
384 384
     }
@@ -509,8 +509,8 @@  discard block
 block discarded – undo
509 509
             $this->reset_checkout();
510 510
             $this->reset_transaction();
511 511
         }
512
-        if (! empty($key)) {
513
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
512
+        if ( ! empty($key)) {
513
+            return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null;
514 514
         }
515 515
         return $this->_session_data;
516 516
     }
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
             return false;
539 539
         }
540 540
         foreach ($data as $key => $value) {
541
-            if (isset($this->_default_session_vars[ $key ])) {
541
+            if (isset($this->_default_session_vars[$key])) {
542 542
                 EE_Error::add_error(
543 543
                     sprintf(
544 544
                         esc_html__(
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
                 );
554 554
                 return false;
555 555
             }
556
-            $this->_session_data[ $key ] = $value;
556
+            $this->_session_data[$key] = $value;
557 557
         }
558 558
         return true;
559 559
     }
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
         $this->_user_agent = $this->request->userAgent();
583 583
         // now let's retrieve what's in the db
584 584
         $session_data = $this->_retrieve_session_data();
585
-        if (! empty($session_data)) {
585
+        if ( ! empty($session_data)) {
586 586
             // get the current time in UTC
587 587
             $this->_time = $this->_time !== null ? $this->_time : time();
588 588
             // and reset the session expiration
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
             // set initial site access time and the session expiration
594 594
             $this->_set_init_access_and_expiration();
595 595
             // set referer
596
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
596
+            $this->_session_data['pages_visited'][$this->_session_data['init_access']] = isset($_SERVER['HTTP_REFERER'])
597 597
                 ? esc_attr($_SERVER['HTTP_REFERER'])
598 598
                 : '';
599 599
             // no previous session = go back and create one (on top of the data above)
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
      */
631 631
     protected function _retrieve_session_data()
632 632
     {
633
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
633
+        $ssn_key = EE_Session::session_id_prefix.$this->_sid;
634 634
         try {
635 635
             // we're using WP's Transient API to store session data using the PHP session ID as the option name
636 636
             $session_data = $this->cache_storage->get($ssn_key, false);
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
             }
640 640
             if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
641 641
                 $hash_check = $this->cache_storage->get(
642
-                    EE_Session::hash_check_prefix . $this->_sid,
642
+                    EE_Session::hash_check_prefix.$this->_sid,
643 643
                     false
644 644
                 );
645 645
                 if ($hash_check && $hash_check !== md5($session_data)) {
@@ -649,7 +649,7 @@  discard block
 block discarded – undo
649 649
                                 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
650 650
                                 'event_espresso'
651 651
                             ),
652
-                            EE_Session::session_id_prefix . $this->_sid
652
+                            EE_Session::session_id_prefix.$this->_sid
653 653
                         ),
654 654
                         __FILE__,
655 655
                         __FUNCTION__,
@@ -663,17 +663,17 @@  discard block
 block discarded – undo
663 663
             $row = $wpdb->get_row(
664 664
                 $wpdb->prepare(
665 665
                     "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
666
-                    '_transient_' . $ssn_key
666
+                    '_transient_'.$ssn_key
667 667
                 )
668 668
             );
669 669
             $session_data = is_object($row) ? $row->option_value : null;
670 670
             if ($session_data) {
671 671
                 $session_data = preg_replace_callback(
672 672
                     '!s:(d+):"(.*?)";!',
673
-                    function ($match) {
673
+                    function($match) {
674 674
                         return $match[1] === strlen($match[2])
675 675
                             ? $match[0]
676
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
676
+                            : 's:'.strlen($match[2]).':"'.$match[2].'";';
677 677
                     },
678 678
                     $session_data
679 679
                 );
@@ -684,7 +684,7 @@  discard block
 block discarded – undo
684 684
         $session_data = $this->encryption instanceof EE_Encryption
685 685
             ? $this->encryption->base64_string_decode($session_data)
686 686
             : $session_data;
687
-        if (! is_array($session_data)) {
687
+        if ( ! is_array($session_data)) {
688 688
             try {
689 689
                 $session_data = maybe_unserialize($session_data);
690 690
             } catch (Exception $e) {
@@ -698,21 +698,21 @@  discard block
 block discarded – undo
698 698
                       . '</pre><br>'
699 699
                       . $this->find_serialize_error($session_data)
700 700
                     : '';
701
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
701
+                $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
702 702
                 throw new InvalidSessionDataException($msg, 0, $e);
703 703
             }
704 704
         }
705 705
         // just a check to make sure the session array is indeed an array
706
-        if (! is_array($session_data)) {
706
+        if ( ! is_array($session_data)) {
707 707
             // no?!?! then something is wrong
708 708
             $msg = esc_html__(
709 709
                 'The session data is missing, invalid, or corrupted.',
710 710
                 'event_espresso'
711 711
             );
712 712
             $msg .= WP_DEBUG
713
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
713
+                ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data)
714 714
                 : '';
715
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
715
+            $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
716 716
             throw new InvalidSessionDataException($msg);
717 717
         }
718 718
         if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
@@ -739,7 +739,7 @@  discard block
 block discarded – undo
739 739
         if (isset($_REQUEST['EESID'])) {
740 740
             $session_id = sanitize_text_field($_REQUEST['EESID']);
741 741
         } else {
742
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
742
+            $session_id = md5(session_id().get_current_blog_id().$this->_get_sid_salt());
743 743
         }
744 744
         return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
745 745
     }
@@ -842,19 +842,19 @@  discard block
 block discarded – undo
842 842
                     $page_visit = $this->_get_page_visit();
843 843
                     if ($page_visit) {
844 844
                         // set pages visited where the first will be the http referrer
845
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
845
+                        $this->_session_data['pages_visited'][$this->_time] = $page_visit;
846 846
                         // we'll only save the last 10 page visits.
847 847
                         $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
848 848
                     }
849 849
                     break;
850 850
                 default:
851 851
                     // carry any other data over
852
-                    $session_data[ $key ] = $this->_session_data[ $key ];
852
+                    $session_data[$key] = $this->_session_data[$key];
853 853
             }
854 854
         }
855 855
         $this->_session_data = $session_data;
856 856
         // creating a new session does not require saving to the db just yet
857
-        if (! $new_session) {
857
+        if ( ! $new_session) {
858 858
             // ready? let's save
859 859
             if ($this->_save_session_to_db()) {
860 860
                 return true;
@@ -895,8 +895,8 @@  discard block
 block discarded – undo
895 895
                 isset($this->_session_data['ee_notices'])
896 896
                 && (
897 897
                     ! empty($this->_session_data['ee_notices']['attention'])
898
-                    || !empty($this->_session_data['ee_notices']['errors'])
899
-                    || !empty($this->_session_data['ee_notices']['success'])
898
+                    || ! empty($this->_session_data['ee_notices']['errors'])
899
+                    || ! empty($this->_session_data['ee_notices']['success'])
900 900
                 )
901 901
             );
902 902
     }
@@ -925,7 +925,7 @@  discard block
 block discarded – undo
925 925
         }
926 926
         $transaction = $this->transaction();
927 927
         if ($transaction instanceof EE_Transaction) {
928
-            if (! $transaction->ID()) {
928
+            if ( ! $transaction->ID()) {
929 929
                 $transaction->save();
930 930
             }
931 931
             $this->_session_data['transaction'] = $transaction->ID();
@@ -939,14 +939,14 @@  discard block
 block discarded – undo
939 939
         // maybe save hash check
940 940
         if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
941 941
             $this->cache_storage->add(
942
-                EE_Session::hash_check_prefix . $this->_sid,
942
+                EE_Session::hash_check_prefix.$this->_sid,
943 943
                 md5($session_data),
944 944
                 $this->session_lifespan->inSeconds()
945 945
             );
946 946
         }
947 947
         // we're using the Transient API for storing session data,
948 948
         return $this->cache_storage->add(
949
-            EE_Session::session_id_prefix . $this->_sid,
949
+            EE_Session::session_id_prefix.$this->_sid,
950 950
             $session_data,
951 951
             $this->session_lifespan->inSeconds()
952 952
         );
@@ -960,7 +960,7 @@  discard block
 block discarded – undo
960 960
      */
961 961
     public function _get_page_visit()
962 962
     {
963
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
963
+        $page_visit = home_url('/').'wp-admin/admin-ajax.php';
964 964
         // check for request url
965 965
         if (isset($_SERVER['REQUEST_URI'])) {
966 966
             $http_host = '';
@@ -976,14 +976,14 @@  discard block
 block discarded – undo
976 976
             // check for page_id in SERVER REQUEST
977 977
             if (isset($_REQUEST['page_id'])) {
978 978
                 // rebuild $e_reg without any of the extra parameters
979
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
979
+                $page_id = '?page_id='.esc_attr($_REQUEST['page_id']).'&amp;';
980 980
             }
981 981
             // check for $e_reg in SERVER REQUEST
982 982
             if (isset($_REQUEST['ee'])) {
983 983
                 // rebuild $e_reg without any of the extra parameters
984
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
984
+                $e_reg = 'ee='.esc_attr($_REQUEST['ee']);
985 985
             }
986
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
986
+            $page_visit = rtrim($http_host.$request_uri.$page_id.$e_reg, '?');
987 987
         }
988 988
         return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
989 989
     }
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1022 1022
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1023 1023
 // </h3>';
1024
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1024
+        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()');
1025 1025
         $this->reset_cart();
1026 1026
         $this->reset_checkout();
1027 1027
         $this->reset_transaction();
@@ -1043,7 +1043,7 @@  discard block
 block discarded – undo
1043 1043
     public function reset_data($data_to_reset = array(), $show_all_notices = false)
1044 1044
     {
1045 1045
         // if $data_to_reset is not in an array, then put it in one
1046
-        if (! is_array($data_to_reset)) {
1046
+        if ( ! is_array($data_to_reset)) {
1047 1047
             $data_to_reset = array($data_to_reset);
1048 1048
         }
1049 1049
         // nothing ??? go home!
@@ -1063,11 +1063,11 @@  discard block
 block discarded – undo
1063 1063
         // since $data_to_reset is an array, cycle through the values
1064 1064
         foreach ($data_to_reset as $reset) {
1065 1065
             // first check to make sure it is a valid session var
1066
-            if (isset($this->_session_data[ $reset ])) {
1066
+            if (isset($this->_session_data[$reset])) {
1067 1067
                 // then check to make sure it is not a default var
1068
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1068
+                if ( ! array_key_exists($reset, $this->_default_session_vars)) {
1069 1069
                     // remove session var
1070
-                    unset($this->_session_data[ $reset ]);
1070
+                    unset($this->_session_data[$reset]);
1071 1071
                     if ($show_all_notices) {
1072 1072
                         EE_Error::add_success(
1073 1073
                             sprintf(
@@ -1168,7 +1168,7 @@  discard block
 block discarded – undo
1168 1168
             // or use that for the new transient cleanup query limit
1169 1169
             add_filter(
1170 1170
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1171
-                function () use ($expired_session_transient_delete_query_limit) {
1171
+                function() use ($expired_session_transient_delete_query_limit) {
1172 1172
                     return $expired_session_transient_delete_query_limit;
1173 1173
                 }
1174 1174
             );
@@ -1186,7 +1186,7 @@  discard block
 block discarded – undo
1186 1186
         $error = '<pre>';
1187 1187
         $data2 = preg_replace_callback(
1188 1188
             '!s:(\d+):"(.*?)";!',
1189
-            function ($match) {
1189
+            function($match) {
1190 1190
                 return ($match[1] === strlen($match[2]))
1191 1191
                     ? $match[0]
1192 1192
                     : 's:'
@@ -1198,13 +1198,13 @@  discard block
 block discarded – undo
1198 1198
             $data1
1199 1199
         );
1200 1200
         $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1201
-        $error .= $data1 . PHP_EOL;
1202
-        $error .= $data2 . PHP_EOL;
1201
+        $error .= $data1.PHP_EOL;
1202
+        $error .= $data2.PHP_EOL;
1203 1203
         for ($i = 0; $i < $max; $i++) {
1204
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1205
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1206
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1207
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1204
+            if (@$data1[$i] !== @$data2[$i]) {
1205
+                $error .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL;
1206
+                $error .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL;
1207
+                $error .= "\t-> Line Number = $i".PHP_EOL;
1208 1208
                 $start = ($i - 20);
1209 1209
                 $start = ($start < 0) ? 0 : $start;
1210 1210
                 $length = 40;
@@ -1219,7 +1219,7 @@  discard block
 block discarded – undo
1219 1219
                 $error .= "\t-> Section Data1  = ";
1220 1220
                 $error .= substr_replace(
1221 1221
                     substr($data1, $start, $length),
1222
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1222
+                    "<b style=\"color:green\">{$data1[$i]}</b>",
1223 1223
                     $rpoint,
1224 1224
                     $rlength
1225 1225
                 );
@@ -1227,7 +1227,7 @@  discard block
 block discarded – undo
1227 1227
                 $error .= "\t-> Section Data2  = ";
1228 1228
                 $error .= substr_replace(
1229 1229
                     substr($data2, $start, $length),
1230
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1230
+                    "<b style=\"color:red\">{$data2[$i]}</b>",
1231 1231
                     $rpoint,
1232 1232
                     $rlength
1233 1233
                 );
@@ -1258,7 +1258,7 @@  discard block
 block discarded – undo
1258 1258
     public function garbageCollection()
1259 1259
     {
1260 1260
         // only perform during regular requests if last garbage collection was over an hour ago
1261
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1261
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1262 1262
             $this->_last_gc = time();
1263 1263
             $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1264 1264
             /** @type WPDB $wpdb */
@@ -1293,7 +1293,7 @@  discard block
 block discarded – undo
1293 1293
                 // AND option_value < 1508368198 LIMIT 50
1294 1294
                 $expired_sessions = $wpdb->get_col($SQL);
1295 1295
                 // valid results?
1296
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1296
+                if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1297 1297
                     $this->cache_storage->deleteMany($expired_sessions, true);
1298 1298
                 }
1299 1299
             }
Please login to merge, or discard this patch.
core/services/request/RequestInterface.php 1 patch
Indentation   +118 added lines, -118 removed lines patch added patch discarded remove patch
@@ -20,139 +20,139 @@
 block discarded – undo
20 20
 interface RequestInterface extends RequestTypeContextCheckerInterface
21 21
 {
22 22
 
23
-    /**
24
-     * @param RequestTypeContextCheckerInterface $type
25
-     */
26
-    public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type);
27
-
28
-    /**
29
-     * @return array
30
-     */
31
-    public function getParams();
32
-
33
-
34
-    /**
35
-     * @return array
36
-     */
37
-    public function postParams();
38
-
39
-
40
-    /**
41
-     * @return array
42
-     */
43
-    public function cookieParams();
44
-
45
-
46
-    /**
47
-     * @return array
48
-     */
49
-    public function serverParams();
50
-
51
-
52
-    /**
53
-     * returns contents of $_REQUEST
54
-     *
55
-     * @return array
56
-     */
57
-    public function requestParams();
23
+	/**
24
+	 * @param RequestTypeContextCheckerInterface $type
25
+	 */
26
+	public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type);
27
+
28
+	/**
29
+	 * @return array
30
+	 */
31
+	public function getParams();
32
+
33
+
34
+	/**
35
+	 * @return array
36
+	 */
37
+	public function postParams();
38
+
39
+
40
+	/**
41
+	 * @return array
42
+	 */
43
+	public function cookieParams();
44
+
45
+
46
+	/**
47
+	 * @return array
48
+	 */
49
+	public function serverParams();
50
+
51
+
52
+	/**
53
+	 * returns contents of $_REQUEST
54
+	 *
55
+	 * @return array
56
+	 */
57
+	public function requestParams();
58 58
 
59 59
 
60
-    /**
61
-     * @param string $key
62
-     * @param string $value
63
-     * @param bool   $override_ee
64
-     * @return    void
65
-     */
66
-    public function setRequestParam($key, $value, $override_ee = false);
60
+	/**
61
+	 * @param string $key
62
+	 * @param string $value
63
+	 * @param bool   $override_ee
64
+	 * @return    void
65
+	 */
66
+	public function setRequestParam($key, $value, $override_ee = false);
67 67
 
68 68
 
69
-    /**
70
-     * returns the value for a request param if the given key exists
71
-     *
72
-     * @param string $key
73
-     * @param null   $default
74
-     * @return mixed
75
-     */
76
-    public function getRequestParam($key, $default = null);
69
+	/**
70
+	 * returns the value for a request param if the given key exists
71
+	 *
72
+	 * @param string $key
73
+	 * @param null   $default
74
+	 * @return mixed
75
+	 */
76
+	public function getRequestParam($key, $default = null);
77 77
 
78 78
 
79
-    /**
80
-     * check if param exists
81
-     *
82
-     * @param string $key
83
-     * @return bool
84
-     */
85
-    public function requestParamIsSet($key);
79
+	/**
80
+	 * check if param exists
81
+	 *
82
+	 * @param string $key
83
+	 * @return bool
84
+	 */
85
+	public function requestParamIsSet($key);
86 86
 
87 87
 
88
-    /**
89
-     * check if a request parameter exists whose key that matches the supplied wildcard pattern
90
-     * and return the value for the first match found
91
-     * wildcards can be either of the following:
92
-     *      ? to represent a single character of any type
93
-     *      * to represent one or more characters of any type
94
-     *
95
-     * @param string     $pattern
96
-     * @param null|mixed $default
97
-     * @return false|int
98
-     */
99
-    public function getMatch($pattern, $default = null);
88
+	/**
89
+	 * check if a request parameter exists whose key that matches the supplied wildcard pattern
90
+	 * and return the value for the first match found
91
+	 * wildcards can be either of the following:
92
+	 *      ? to represent a single character of any type
93
+	 *      * to represent one or more characters of any type
94
+	 *
95
+	 * @param string     $pattern
96
+	 * @param null|mixed $default
97
+	 * @return false|int
98
+	 */
99
+	public function getMatch($pattern, $default = null);
100 100
 
101 101
 
102
-    /**
103
-     * check if a request parameter exists whose key matches the supplied wildcard pattern
104
-     * wildcards can be either of the following:
105
-     *      ? to represent a single character of any type
106
-     *      * to represent one or more characters of any type
107
-     * returns true if a match is found or false if not
108
-     *
109
-     * @param string $pattern
110
-     * @return false|int
111
-     */
112
-    public function matches($pattern);
102
+	/**
103
+	 * check if a request parameter exists whose key matches the supplied wildcard pattern
104
+	 * wildcards can be either of the following:
105
+	 *      ? to represent a single character of any type
106
+	 *      * to represent one or more characters of any type
107
+	 * returns true if a match is found or false if not
108
+	 *
109
+	 * @param string $pattern
110
+	 * @return false|int
111
+	 */
112
+	public function matches($pattern);
113 113
 
114 114
 
115
-    /**
116
-     * remove param
117
-     *
118
-     * @param string $key
119
-     * @param bool   $unset_from_global_too
120
-     */
121
-    public function unSetRequestParam($key, $unset_from_global_too = false);
115
+	/**
116
+	 * remove param
117
+	 *
118
+	 * @param string $key
119
+	 * @param bool   $unset_from_global_too
120
+	 */
121
+	public function unSetRequestParam($key, $unset_from_global_too = false);
122 122
 
123 123
 
124
-    /**
125
-     * @return string
126
-     */
127
-    public function ipAddress();
124
+	/**
125
+	 * @return string
126
+	 */
127
+	public function ipAddress();
128 128
 
129 129
 
130
-    /**
131
-     * @return string
132
-     */
133
-    public function requestUri();
134
-
130
+	/**
131
+	 * @return string
132
+	 */
133
+	public function requestUri();
134
+
135 135
 
136
-    /**
137
-     * @return string
138
-     */
139
-    public function userAgent();
140
-
141
-
142
-    /**
143
-     * @param string $user_agent
144
-     */
145
-    public function setUserAgent($user_agent = '');
146
-
147
-
148
-    /**
149
-     * @return bool
150
-     */
151
-    public function isBot();
152
-
153
-
154
-    /**
155
-     * @param bool $is_bot
156
-     */
157
-    public function setIsBot($is_bot);
136
+	/**
137
+	 * @return string
138
+	 */
139
+	public function userAgent();
140
+
141
+
142
+	/**
143
+	 * @param string $user_agent
144
+	 */
145
+	public function setUserAgent($user_agent = '');
146
+
147
+
148
+	/**
149
+	 * @return bool
150
+	 */
151
+	public function isBot();
152
+
153
+
154
+	/**
155
+	 * @param bool $is_bot
156
+	 */
157
+	public function setIsBot($is_bot);
158 158
 }
Please login to merge, or discard this patch.
core/middleware/EE_Detect_File_Editor_Request.core.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -14,28 +14,28 @@
 block discarded – undo
14 14
 class EE_Detect_File_Editor_Request extends EE_Middleware
15 15
 {
16 16
 
17
-    /**
18
-     * @deprecated
19
-     * @param EE_Request  $request
20
-     * @param EE_Response $response
21
-     * @return EE_Response
22
-     */
23
-    public function handle_request(EE_Request $request, EE_Response $response)
24
-    {
25
-        EE_Error::doing_it_wrong(
26
-            __METHOD__,
27
-            sprintf(
28
-                esc_html__(
29
-                    'This class is deprecated. Please use %1$s instead. All Event Espresso request stack classes have been moved to %2$s and are now under the %3$s namespace',
30
-                    'event_espresso'
31
-                ),
32
-                'EventEspresso\core\services\request\middleware\DetectFileEditorRequest',
33
-                '\core\services\request',
34
-                'EventEspresso\core\services\request'
35
-            ),
36
-            '4.9.52'
37
-        );
38
-        return $response;
39
-    }
17
+	/**
18
+	 * @deprecated
19
+	 * @param EE_Request  $request
20
+	 * @param EE_Response $response
21
+	 * @return EE_Response
22
+	 */
23
+	public function handle_request(EE_Request $request, EE_Response $response)
24
+	{
25
+		EE_Error::doing_it_wrong(
26
+			__METHOD__,
27
+			sprintf(
28
+				esc_html__(
29
+					'This class is deprecated. Please use %1$s instead. All Event Espresso request stack classes have been moved to %2$s and are now under the %3$s namespace',
30
+					'event_espresso'
31
+				),
32
+				'EventEspresso\core\services\request\middleware\DetectFileEditorRequest',
33
+				'\core\services\request',
34
+				'EventEspresso\core\services\request'
35
+			),
36
+			'4.9.52'
37
+		);
38
+		return $response;
39
+	}
40 40
 
41 41
 }
Please login to merge, or discard this patch.
core/domain/services/admin/PluginUpsells.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -83,12 +83,12 @@
 block discarded – undo
83 83
                     <div class="notice inline notice-alt">
84 84
                         <div class="ee-upsell-container">
85 85
                             <div class="ee-upsell-inner-container">
86
-                                <a href="' . $button_url . '">
87
-                                    ' . $button_text . '
86
+                                <a href="' . $button_url.'">
87
+                                    ' . $button_text.'
88 88
                                 </a>
89 89
                             </div>
90 90
                             <div class="ee-upsell-inner-container">
91
-                                <p>' . $upsell_text . '</p>
91
+                                <p>' . $upsell_text.'</p>
92 92
                             </div>
93 93
                             <div style="clear:both"></div>
94 94
                         </div>
Please login to merge, or discard this patch.
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -17,47 +17,47 @@  discard block
 block discarded – undo
17 17
 class PluginUpsells
18 18
 {
19 19
 
20
-    /**
21
-     * @var DomainInterface
22
-     */
23
-    private $domain;
20
+	/**
21
+	 * @var DomainInterface
22
+	 */
23
+	private $domain;
24 24
 
25 25
 
26
-    /**
27
-     * PluginUpsells constructor.
28
-     *
29
-     * @param DomainInterface $domain
30
-     */
31
-    public function __construct(DomainInterface $domain)
32
-    {
33
-        $this->domain = $domain;
34
-    }
26
+	/**
27
+	 * PluginUpsells constructor.
28
+	 *
29
+	 * @param DomainInterface $domain
30
+	 */
31
+	public function __construct(DomainInterface $domain)
32
+	{
33
+		$this->domain = $domain;
34
+	}
35 35
 
36 36
 
37
-    /**
38
-     * Hook in various upsells for the decaf version of EE.
39
-     */
40
-    public function decafUpsells()
41
-    {
42
-        if ($this->domain instanceof CaffeinatedInterface && ! $this->domain->isCaffeinated()) {
43
-            add_action('after_plugin_row', array($this, 'doPremiumUpsell'), 10, 3);
44
-        }
45
-    }
37
+	/**
38
+	 * Hook in various upsells for the decaf version of EE.
39
+	 */
40
+	public function decafUpsells()
41
+	{
42
+		if ($this->domain instanceof CaffeinatedInterface && ! $this->domain->isCaffeinated()) {
43
+			add_action('after_plugin_row', array($this, 'doPremiumUpsell'), 10, 3);
44
+		}
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * Callback for `after_plugin_row` to add upsell info
50
-     *
51
-     * @param string $plugin_file
52
-     * @param array  $plugin_data
53
-     * @param string $status
54
-     * @throws DomainException
55
-     */
56
-    public function doPremiumUpsell($plugin_file, $plugin_data, $status)
57
-    {
58
-        if ($plugin_file === $this->domain->pluginBasename()) {
59
-            list($button_text, $button_url, $upsell_text) = $this->getAfterPluginRowDetails();
60
-            echo '<tr class="plugin-update-tr ee-upsell-plugin-list-table active">
48
+	/**
49
+	 * Callback for `after_plugin_row` to add upsell info
50
+	 *
51
+	 * @param string $plugin_file
52
+	 * @param array  $plugin_data
53
+	 * @param string $status
54
+	 * @throws DomainException
55
+	 */
56
+	public function doPremiumUpsell($plugin_file, $plugin_data, $status)
57
+	{
58
+		if ($plugin_file === $this->domain->pluginBasename()) {
59
+			list($button_text, $button_url, $upsell_text) = $this->getAfterPluginRowDetails();
60
+			echo '<tr class="plugin-update-tr ee-upsell-plugin-list-table active">
61 61
                 <td colspan="3" class="plugin-update colspanchange">
62 62
                     <div class="notice inline notice-alt">
63 63
                         <div class="ee-upsell-container">
@@ -74,27 +74,27 @@  discard block
 block discarded – undo
74 74
                     </div>
75 75
                 </td>
76 76
               </tr>';
77
-        }
78
-    }
77
+		}
78
+	}
79 79
 
80
-    /**
81
-     * Provide the details used for the upsell container.
82
-     *
83
-     * @return array
84
-     */
85
-    protected function getAfterPluginRowDetails()
86
-    {
87
-        return array(
88
-            esc_html__('Upgrade for Support', 'event_espresso'),
89
-            'https://eventespresso.com/purchase/?slug=ee4-license-personal&utm_source=wp_admin_plugins_screen&utm_medium=link&utm_campaign=plugins_screen_upgrade_link" class="button button-primary',
90
-            sprintf(
91
-                esc_html__(
92
-                    'You\'re missing out on %1$sexpert support%2$s and %1$sone-click updates%2$s! Don\'t have an Event Espresso support license key? Support the project and buy one today!',
93
-                    'event_espresso'
94
-                ),
95
-                '<strong>',
96
-                '</strong>'
97
-            ),
98
-        );
99
-    }
80
+	/**
81
+	 * Provide the details used for the upsell container.
82
+	 *
83
+	 * @return array
84
+	 */
85
+	protected function getAfterPluginRowDetails()
86
+	{
87
+		return array(
88
+			esc_html__('Upgrade for Support', 'event_espresso'),
89
+			'https://eventespresso.com/purchase/?slug=ee4-license-personal&utm_source=wp_admin_plugins_screen&utm_medium=link&utm_campaign=plugins_screen_upgrade_link" class="button button-primary',
90
+			sprintf(
91
+				esc_html__(
92
+					'You\'re missing out on %1$sexpert support%2$s and %1$sone-click updates%2$s! Don\'t have an Event Espresso support license key? Support the project and buy one today!',
93
+					'event_espresso'
94
+				),
95
+				'<strong>',
96
+				'</strong>'
97
+			),
98
+		);
99
+	}
100 100
 }
Please login to merge, or discard this patch.
core/domain/Domain.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -66,7 +66,7 @@
 block discarded – undo
66 66
      */
67 67
     private function setCaffeinated()
68 68
     {
69
-        $this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true)
70
-            && is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php');
69
+        $this->caffeinated = ( ! defined('EE_DECAF') || EE_DECAF !== true)
70
+            && is_readable($this->pluginPath().'caffeinated/brewing_regular.php');
71 71
     }
72 72
 }
Please login to merge, or discard this patch.
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -19,54 +19,54 @@
 block discarded – undo
19 19
 class Domain extends DomainBase implements CaffeinatedInterface
20 20
 {
21 21
 
22
-    /**
23
-     * URL path component used to denote an API request
24
-     */
25
-    const API_NAMESPACE = 'ee/v';
22
+	/**
23
+	 * URL path component used to denote an API request
24
+	 */
25
+	const API_NAMESPACE = 'ee/v';
26 26
 
27
-    /**
28
-     * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin
29
-     * Page ui.
30
-     */
31
-    const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN
32
-        = 'manual_registration_status_change_from_registration_admin';
27
+	/**
28
+	 * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin
29
+	 * Page ui.
30
+	 */
31
+	const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN
32
+		= 'manual_registration_status_change_from_registration_admin';
33 33
 
34
-    const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
35
-        = 'manual_registration_status_change_from_registration_admin_and_notify';
34
+	const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
35
+		= 'manual_registration_status_change_from_registration_admin_and_notify';
36 36
 
37 37
 
38
-    /**
39
-     * Whether or not EE core is the full premium version.
40
-     * @since 4.9.59.p
41
-     * @var bool
42
-     */
43
-    private $caffeinated;
38
+	/**
39
+	 * Whether or not EE core is the full premium version.
40
+	 * @since 4.9.59.p
41
+	 * @var bool
42
+	 */
43
+	private $caffeinated;
44 44
 
45 45
 
46
-    public function __construct(FilePath $plugin_file, Version $version)
47
-    {
48
-        parent::__construct($plugin_file, $version);
49
-        $this->setCaffeinated();
50
-    }
46
+	public function __construct(FilePath $plugin_file, Version $version)
47
+	{
48
+		parent::__construct($plugin_file, $version);
49
+		$this->setCaffeinated();
50
+	}
51 51
 
52
-    /**
53
-     * Whether or not EE core is the full premium version.
54
-     * @since 4.9.59.p
55
-     * @return bool
56
-     */
57
-    public function isCaffeinated()
58
-    {
59
-        return $this->caffeinated;
60
-    }
52
+	/**
53
+	 * Whether or not EE core is the full premium version.
54
+	 * @since 4.9.59.p
55
+	 * @return bool
56
+	 */
57
+	public function isCaffeinated()
58
+	{
59
+		return $this->caffeinated;
60
+	}
61 61
 
62 62
 
63
-    /**
64
-     * Setter for $is_caffeinated property.
65
-     * @since 4.9.59.p
66
-     */
67
-    private function setCaffeinated()
68
-    {
69
-        $this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true)
70
-            && is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php');
71
-    }
63
+	/**
64
+	 * Setter for $is_caffeinated property.
65
+	 * @since 4.9.59.p
66
+	 */
67
+	private function setCaffeinated()
68
+	{
69
+		$this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true)
70
+			&& is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php');
71
+	}
72 72
 }
Please login to merge, or discard this patch.
core/services/loaders/Loader.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@
 block discarded – undo
101 101
 
102 102
 
103 103
     /**
104
-     * @param FullyQualifiedName|string $fqcn
104
+     * @param string $fqcn
105 105
      * @param array                     $arguments
106 106
      * @return mixed
107 107
      */
Please login to merge, or discard this patch.
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -15,115 +15,115 @@
 block discarded – undo
15 15
 class Loader implements LoaderInterface
16 16
 {
17 17
 
18
-    /**
19
-     * @var LoaderDecoratorInterface $new_loader
20
-     */
21
-    private $new_loader;
22
-
23
-    /**
24
-     * @var LoaderDecoratorInterface $shared_loader
25
-     */
26
-    private $shared_loader;
27
-
28
-    /**
29
-     * @var ClassInterfaceCache $class_cache
30
-     */
31
-    private $class_cache;
32
-
33
-    /**
34
-     * Loader constructor.
35
-     *
36
-     * @param LoaderDecoratorInterface        $new_loader
37
-     * @param CachingLoaderDecoratorInterface $shared_loader
38
-     * @param ClassInterfaceCache             $class_cache
39
-     */
40
-    public function __construct(
41
-        LoaderDecoratorInterface $new_loader,
42
-        CachingLoaderDecoratorInterface $shared_loader,
43
-        ClassInterfaceCache $class_cache
44
-    ) {
45
-        $this->new_loader    = $new_loader;
46
-        $this->shared_loader = $shared_loader;
47
-        $this->class_cache   = $class_cache;
48
-    }
49
-
50
-
51
-    /**
52
-     * @return LoaderDecoratorInterface
53
-     */
54
-    public function getNewLoader()
55
-    {
56
-        return $this->new_loader;
57
-    }
58
-
59
-
60
-    /**
61
-     * @return CachingLoaderDecoratorInterface
62
-     */
63
-    public function getSharedLoader()
64
-    {
65
-        return $this->shared_loader;
66
-    }
67
-
68
-
69
-    /**
70
-     * @param FullyQualifiedName|string $fqcn
71
-     * @param array                     $arguments
72
-     * @param bool                      $shared
73
-     * @return mixed
74
-     */
75
-    public function load($fqcn, array $arguments = array(), $shared = true)
76
-    {
77
-        $fqcn = $this->class_cache->getFqn($fqcn);
78
-        if ($this->class_cache->hasInterface($fqcn, 'EventEspresso\core\interfaces\ReservedInstanceInterface')) {
79
-            $shared = true;
80
-        }
81
-        return $shared
82
-            ? $this->getSharedLoader()->load($fqcn, $arguments, $shared)
83
-            : $this->getNewLoader()->load($fqcn, $arguments, $shared);
84
-    }
85
-
86
-
87
-    /**
88
-     * @param FullyQualifiedName|string $fqcn
89
-     * @param array                     $arguments
90
-     * @return mixed
91
-     */
92
-    public function getNew($fqcn, array $arguments = array())
93
-    {
94
-        return $this->load($fqcn, $arguments, false);
95
-    }
96
-
97
-
98
-    /**
99
-     * @param FullyQualifiedName|string $fqcn
100
-     * @param array                     $arguments
101
-     * @return mixed
102
-     */
103
-    public function getShared($fqcn, array $arguments = array())
104
-    {
105
-        return $this->load($fqcn, $arguments);
106
-    }
107
-
108
-
109
-    /**
110
-     * @param FullyQualifiedName|string $fqcn
111
-     * @param mixed                     $object
112
-     * @return bool
113
-     * @throws InvalidArgumentException
114
-     */
115
-    public function share($fqcn, $object)
116
-    {
117
-        $fqcn = $this->class_cache->getFqn($fqcn);
118
-        return $this->getSharedLoader()->share($fqcn, $object);
119
-    }
120
-
121
-
122
-    /**
123
-     * calls reset() on loaders if that method exists
124
-     */
125
-    public function reset()
126
-    {
127
-        $this->shared_loader->reset();
128
-    }
18
+	/**
19
+	 * @var LoaderDecoratorInterface $new_loader
20
+	 */
21
+	private $new_loader;
22
+
23
+	/**
24
+	 * @var LoaderDecoratorInterface $shared_loader
25
+	 */
26
+	private $shared_loader;
27
+
28
+	/**
29
+	 * @var ClassInterfaceCache $class_cache
30
+	 */
31
+	private $class_cache;
32
+
33
+	/**
34
+	 * Loader constructor.
35
+	 *
36
+	 * @param LoaderDecoratorInterface        $new_loader
37
+	 * @param CachingLoaderDecoratorInterface $shared_loader
38
+	 * @param ClassInterfaceCache             $class_cache
39
+	 */
40
+	public function __construct(
41
+		LoaderDecoratorInterface $new_loader,
42
+		CachingLoaderDecoratorInterface $shared_loader,
43
+		ClassInterfaceCache $class_cache
44
+	) {
45
+		$this->new_loader    = $new_loader;
46
+		$this->shared_loader = $shared_loader;
47
+		$this->class_cache   = $class_cache;
48
+	}
49
+
50
+
51
+	/**
52
+	 * @return LoaderDecoratorInterface
53
+	 */
54
+	public function getNewLoader()
55
+	{
56
+		return $this->new_loader;
57
+	}
58
+
59
+
60
+	/**
61
+	 * @return CachingLoaderDecoratorInterface
62
+	 */
63
+	public function getSharedLoader()
64
+	{
65
+		return $this->shared_loader;
66
+	}
67
+
68
+
69
+	/**
70
+	 * @param FullyQualifiedName|string $fqcn
71
+	 * @param array                     $arguments
72
+	 * @param bool                      $shared
73
+	 * @return mixed
74
+	 */
75
+	public function load($fqcn, array $arguments = array(), $shared = true)
76
+	{
77
+		$fqcn = $this->class_cache->getFqn($fqcn);
78
+		if ($this->class_cache->hasInterface($fqcn, 'EventEspresso\core\interfaces\ReservedInstanceInterface')) {
79
+			$shared = true;
80
+		}
81
+		return $shared
82
+			? $this->getSharedLoader()->load($fqcn, $arguments, $shared)
83
+			: $this->getNewLoader()->load($fqcn, $arguments, $shared);
84
+	}
85
+
86
+
87
+	/**
88
+	 * @param FullyQualifiedName|string $fqcn
89
+	 * @param array                     $arguments
90
+	 * @return mixed
91
+	 */
92
+	public function getNew($fqcn, array $arguments = array())
93
+	{
94
+		return $this->load($fqcn, $arguments, false);
95
+	}
96
+
97
+
98
+	/**
99
+	 * @param FullyQualifiedName|string $fqcn
100
+	 * @param array                     $arguments
101
+	 * @return mixed
102
+	 */
103
+	public function getShared($fqcn, array $arguments = array())
104
+	{
105
+		return $this->load($fqcn, $arguments);
106
+	}
107
+
108
+
109
+	/**
110
+	 * @param FullyQualifiedName|string $fqcn
111
+	 * @param mixed                     $object
112
+	 * @return bool
113
+	 * @throws InvalidArgumentException
114
+	 */
115
+	public function share($fqcn, $object)
116
+	{
117
+		$fqcn = $this->class_cache->getFqn($fqcn);
118
+		return $this->getSharedLoader()->share($fqcn, $object);
119
+	}
120
+
121
+
122
+	/**
123
+	 * calls reset() on loaders if that method exists
124
+	 */
125
+	public function reset()
126
+	{
127
+		$this->shared_loader->reset();
128
+	}
129 129
 }
Please login to merge, or discard this patch.
core/services/bootstrap/BootstrapDependencyInjectionContainer.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -78,13 +78,13 @@
 block discarded – undo
78 78
         // EE_Dependency_Map: info about how to load classes required by other classes
79 79
         espresso_load_required(
80 80
             'EE_Dependency_Map',
81
-            EE_CORE . 'EE_Dependency_Map.core.php'
81
+            EE_CORE.'EE_Dependency_Map.core.php'
82 82
         );
83 83
         $this->dependency_map = EE_Dependency_Map::instance($this->class_cache);
84 84
         // EE_Registry: central repository for classes (legacy)
85 85
         espresso_load_required(
86 86
             'EE_Registry',
87
-            EE_CORE . 'EE_Registry.core.php'
87
+            EE_CORE.'EE_Registry.core.php'
88 88
         );
89 89
         $this->registry = EE_Registry::instance(
90 90
             $this->dependency_map,
Please login to merge, or discard this patch.
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -25,123 +25,123 @@
 block discarded – undo
25 25
 class BootstrapDependencyInjectionContainer
26 26
 {
27 27
 
28
-    /**
29
-     * @var EE_Dependency_Map $dependency_map
30
-     */
31
-    protected $dependency_map;
32
-
33
-    /**
34
-     * @type LoaderInterface $loader
35
-     */
36
-    protected $loader;
37
-
38
-    /**
39
-     * @var EE_Registry $registry
40
-     */
41
-    protected $registry;
42
-
43
-    /**
44
-     * @var ClassInterfaceCache $class_cache
45
-     */
46
-    private $class_cache;
47
-
48
-    /**
49
-     * @var Mirror
50
-     */
51
-    private $mirror;
52
-
53
-    /**
54
-     * @var ObjectIdentifier
55
-     */
56
-    private $object_identifier;
57
-
58
-
59
-    /**
60
-     * Can't use this just yet until we exorcise some more of our singleton usage from core
61
-     */
62
-    public function buildDependencyInjectionContainer()
63
-    {
64
-        // build DI container
65
-        // $OpenCoffeeShop = new EventEspresso\core\services\container\OpenCoffeeShop();
66
-        // $OpenCoffeeShop->addRecipes();
67
-        // $CoffeeShop = $OpenCoffeeShop->CoffeeShop();
68
-    }
69
-
70
-
71
-    /**
72
-     * Setups  EE_Registry and EE_Dependency_Map
73
-     *
74
-     * @throws EE_Error
75
-     */
76
-    public function buildLegacyDependencyInjectionContainer()
77
-    {
78
-        $this->class_cache = new ClassInterfaceCache();
79
-        $this->object_identifier = new ObjectIdentifier($this->class_cache);
80
-        $this->mirror = new Mirror();
81
-        // EE_Dependency_Map: info about how to load classes required by other classes
82
-        espresso_load_required(
83
-            'EE_Dependency_Map',
84
-            EE_CORE . 'EE_Dependency_Map.core.php'
85
-        );
86
-        $this->dependency_map = EE_Dependency_Map::instance($this->class_cache);
87
-        // EE_Registry: central repository for classes (legacy)
88
-        espresso_load_required(
89
-            'EE_Registry',
90
-            EE_CORE . 'EE_Registry.core.php'
91
-        );
92
-        $this->registry = EE_Registry::instance(
93
-            $this->dependency_map,
94
-            $this->mirror,
95
-            $this->class_cache,
96
-            $this->object_identifier
97
-        );
98
-    }
99
-
100
-
101
-    /**
102
-     * Performs initial setup for the generic Loader
103
-     *
104
-     * @throws InvalidDataTypeException
105
-     * @throws InvalidInterfaceException
106
-     * @throws InvalidArgumentException
107
-     */
108
-    public function buildLoader()
109
-    {
110
-        $this->loader = LoaderFactory::getLoader(
111
-            $this->registry,
112
-            $this->class_cache,
113
-            $this->object_identifier
114
-        );
115
-        $this->loader->share('EventEspresso\core\services\loaders\ClassInterfaceCache', $this->class_cache);
116
-        $this->loader->share('EventEspresso\core\services\loaders\ObjectIdentifier', $this->object_identifier);
117
-        $this->loader->share('EventEspresso\core\services\container\Mirror', $this->mirror);
118
-        $this->dependency_map->setLoader($this->loader);
119
-    }
120
-
121
-
122
-    /**
123
-     * @return EE_Dependency_Map
124
-     */
125
-    public function getDependencyMap()
126
-    {
127
-        return $this->dependency_map;
128
-    }
129
-
130
-
131
-    /**
132
-     * @return EE_Registry
133
-     */
134
-    public function getRegistry()
135
-    {
136
-        return $this->registry;
137
-    }
138
-
139
-
140
-    /**
141
-     * @return LoaderInterface
142
-     */
143
-    public function getLoader()
144
-    {
145
-        return $this->loader;
146
-    }
28
+	/**
29
+	 * @var EE_Dependency_Map $dependency_map
30
+	 */
31
+	protected $dependency_map;
32
+
33
+	/**
34
+	 * @type LoaderInterface $loader
35
+	 */
36
+	protected $loader;
37
+
38
+	/**
39
+	 * @var EE_Registry $registry
40
+	 */
41
+	protected $registry;
42
+
43
+	/**
44
+	 * @var ClassInterfaceCache $class_cache
45
+	 */
46
+	private $class_cache;
47
+
48
+	/**
49
+	 * @var Mirror
50
+	 */
51
+	private $mirror;
52
+
53
+	/**
54
+	 * @var ObjectIdentifier
55
+	 */
56
+	private $object_identifier;
57
+
58
+
59
+	/**
60
+	 * Can't use this just yet until we exorcise some more of our singleton usage from core
61
+	 */
62
+	public function buildDependencyInjectionContainer()
63
+	{
64
+		// build DI container
65
+		// $OpenCoffeeShop = new EventEspresso\core\services\container\OpenCoffeeShop();
66
+		// $OpenCoffeeShop->addRecipes();
67
+		// $CoffeeShop = $OpenCoffeeShop->CoffeeShop();
68
+	}
69
+
70
+
71
+	/**
72
+	 * Setups  EE_Registry and EE_Dependency_Map
73
+	 *
74
+	 * @throws EE_Error
75
+	 */
76
+	public function buildLegacyDependencyInjectionContainer()
77
+	{
78
+		$this->class_cache = new ClassInterfaceCache();
79
+		$this->object_identifier = new ObjectIdentifier($this->class_cache);
80
+		$this->mirror = new Mirror();
81
+		// EE_Dependency_Map: info about how to load classes required by other classes
82
+		espresso_load_required(
83
+			'EE_Dependency_Map',
84
+			EE_CORE . 'EE_Dependency_Map.core.php'
85
+		);
86
+		$this->dependency_map = EE_Dependency_Map::instance($this->class_cache);
87
+		// EE_Registry: central repository for classes (legacy)
88
+		espresso_load_required(
89
+			'EE_Registry',
90
+			EE_CORE . 'EE_Registry.core.php'
91
+		);
92
+		$this->registry = EE_Registry::instance(
93
+			$this->dependency_map,
94
+			$this->mirror,
95
+			$this->class_cache,
96
+			$this->object_identifier
97
+		);
98
+	}
99
+
100
+
101
+	/**
102
+	 * Performs initial setup for the generic Loader
103
+	 *
104
+	 * @throws InvalidDataTypeException
105
+	 * @throws InvalidInterfaceException
106
+	 * @throws InvalidArgumentException
107
+	 */
108
+	public function buildLoader()
109
+	{
110
+		$this->loader = LoaderFactory::getLoader(
111
+			$this->registry,
112
+			$this->class_cache,
113
+			$this->object_identifier
114
+		);
115
+		$this->loader->share('EventEspresso\core\services\loaders\ClassInterfaceCache', $this->class_cache);
116
+		$this->loader->share('EventEspresso\core\services\loaders\ObjectIdentifier', $this->object_identifier);
117
+		$this->loader->share('EventEspresso\core\services\container\Mirror', $this->mirror);
118
+		$this->dependency_map->setLoader($this->loader);
119
+	}
120
+
121
+
122
+	/**
123
+	 * @return EE_Dependency_Map
124
+	 */
125
+	public function getDependencyMap()
126
+	{
127
+		return $this->dependency_map;
128
+	}
129
+
130
+
131
+	/**
132
+	 * @return EE_Registry
133
+	 */
134
+	public function getRegistry()
135
+	{
136
+		return $this->registry;
137
+	}
138
+
139
+
140
+	/**
141
+	 * @return LoaderInterface
142
+	 */
143
+	public function getLoader()
144
+	{
145
+		return $this->loader;
146
+	}
147 147
 }
Please login to merge, or discard this patch.
core/services/container/Mirror.php 2 patches
Indentation   +222 added lines, -222 removed lines patch added patch discarded remove patch
@@ -25,226 +25,226 @@
 block discarded – undo
25 25
 class Mirror
26 26
 {
27 27
 
28
-    /**
29
-     * @var ReflectionClass[] $classes
30
-     */
31
-    private $classes = array();
32
-
33
-    /**
34
-     * @var ReflectionMethod[] $constructors
35
-     */
36
-    private $constructors = array();
37
-
38
-    /**
39
-     * @var ReflectionParameter[][] $parameters
40
-     */
41
-    private $parameters = array();
42
-
43
-    /**
44
-     * @var ReflectionParameter[][] $parameters
45
-     */
46
-    private $parameter_classes = array();
47
-
48
-    /**
49
-     * @var ReflectionProperty[][] $properties
50
-     */
51
-    private $properties = array();
52
-
53
-    /**
54
-     * @var ReflectionMethod[][] $methods
55
-     */
56
-    private $methods = array();
57
-
58
-
59
-    /**
60
-     * @param string $class_name
61
-     * @return ReflectionClass
62
-     * @throws ReflectionException
63
-     * @throws InvalidDataTypeException
64
-     */
65
-    public function getReflectionClass($class_name)
66
-    {
67
-        if (! is_string($class_name)) {
68
-            throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
69
-        }
70
-        if (! isset($this->classes[ $class_name ])) {
71
-            $this->classes[ $class_name ] = new ReflectionClass($class_name);
72
-        }
73
-        return $this->classes[ $class_name ];
74
-    }
75
-
76
-
77
-    /**
78
-     * @param string $class_name
79
-     * @return ReflectionMethod
80
-     * @throws InvalidDataTypeException
81
-     * @throws ReflectionException
82
-     */
83
-    public function getConstructor($class_name)
84
-    {
85
-        if (! is_string($class_name)) {
86
-            throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
87
-        }
88
-        if (! isset($this->constructors[ $class_name ])) {
89
-            $reflection_class                  = $this->getReflectionClass($class_name);
90
-            $this->constructors[ $class_name ] = $reflection_class->getConstructor();
91
-        }
92
-        return $this->constructors[ $class_name ];
93
-    }
94
-
95
-
96
-    /**
97
-     * @param ReflectionClass $reflection_class
98
-     * @return ReflectionMethod
99
-     * @throws InvalidDataTypeException
100
-     * @throws ReflectionException
101
-     */
102
-    public function getConstructorFromReflection(ReflectionClass $reflection_class)
103
-    {
104
-        return $this->getConstructor($reflection_class->getName());
105
-    }
106
-
107
-
108
-    /**
109
-     * @param string $class_name
110
-     * @return ReflectionParameter[]
111
-     * @throws InvalidDataTypeException
112
-     * @throws ReflectionException
113
-     */
114
-    public function getParameters($class_name)
115
-    {
116
-        if (! isset($this->parameters[ $class_name ])) {
117
-            $constructor                     = $this->getConstructor($class_name);
118
-            $this->parameters[ $class_name ] = $constructor->getParameters();
119
-        }
120
-        return $this->parameters[ $class_name ];
121
-    }
122
-
123
-
124
-    /**
125
-     * @param ReflectionClass $reflection_class
126
-     * @return ReflectionParameter[]
127
-     * @throws InvalidDataTypeException
128
-     * @throws ReflectionException
129
-     */
130
-    public function getParametersFromReflection(ReflectionClass $reflection_class)
131
-    {
132
-        return $this->getParameters($reflection_class->getName());
133
-    }
134
-
135
-
136
-    /**
137
-     * @param ReflectionMethod $constructor
138
-     * @return ReflectionParameter[]
139
-     * @throws InvalidDataTypeException
140
-     * @throws ReflectionException
141
-     */
142
-    public function getParametersFromReflectionConstructor(ReflectionMethod $constructor)
143
-    {
144
-        return $this->getParameters($constructor->getDeclaringClass());
145
-    }
146
-
147
-
148
-    /**
149
-     * @param ReflectionParameter $param
150
-     * @param string              $class_name
151
-     * @param string              $index
152
-     * @return string|null
153
-     */
154
-    public function getParameterClassName(ReflectionParameter $param, $class_name, $index)
155
-    {
156
-        if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) {
157
-            return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
158
-        }
159
-        if (! isset($this->parameter_classes[ $class_name ])) {
160
-            $this->parameter_classes[ $class_name ] = array();
161
-        }
162
-        if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
163
-            $this->parameter_classes[ $class_name ][ $index ] = array();
164
-        }
165
-        $this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass()
166
-            ? $param->getClass()->name
167
-            : null;
168
-        return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
169
-    }
170
-
171
-
172
-    /**
173
-     * @param ReflectionParameter $param
174
-     * @param string              $class_name
175
-     * @param string              $index
176
-     * @return string|null
177
-     */
178
-    public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index)
179
-    {
180
-        if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) {
181
-            return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
182
-        }
183
-        if (! isset($this->parameter_classes[ $class_name ])) {
184
-            $this->parameter_classes[ $class_name ] = array();
185
-        }
186
-        if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
187
-            $this->parameter_classes[ $class_name ][ $index ] = array();
188
-        }
189
-        $this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable()
190
-            ? $param->getDefaultValue()
191
-            : null;
192
-        return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
193
-    }
194
-
195
-
196
-    /**
197
-     * @param string $class_name
198
-     * @return ReflectionProperty[]
199
-     * @throws InvalidDataTypeException
200
-     * @throws ReflectionException
201
-     */
202
-    public function getProperties($class_name)
203
-    {
204
-        if (! isset($this->properties[ $class_name ])) {
205
-            $reflection_class                = $this->getReflectionClass($class_name);
206
-            $this->properties[ $class_name ] = $reflection_class->getProperties();
207
-        }
208
-        return $this->properties[ $class_name ];
209
-    }
210
-
211
-
212
-    /**
213
-     * @param ReflectionClass $reflection_class
214
-     * @return ReflectionProperty[]
215
-     * @throws InvalidDataTypeException
216
-     * @throws ReflectionException
217
-     */
218
-    public function getPropertiesFromReflection(ReflectionClass $reflection_class)
219
-    {
220
-        return $this->getProperties($reflection_class->getName());
221
-    }
222
-
223
-
224
-    /**
225
-     * @param string $class_name
226
-     * @return ReflectionMethod[]
227
-     * @throws InvalidDataTypeException
228
-     * @throws ReflectionException
229
-     */
230
-    public function getMethods($class_name)
231
-    {
232
-        if (! isset($this->methods[ $class_name ])) {
233
-            $reflection_class             = $this->getReflectionClass($class_name);
234
-            $this->methods[ $class_name ] = $reflection_class->getMethods();
235
-        }
236
-        return $this->methods[ $class_name ];
237
-    }
238
-
239
-
240
-    /**
241
-     * @param ReflectionClass $reflection_class )
242
-     * @return ReflectionMethod[]
243
-     * @throws InvalidDataTypeException
244
-     * @throws ReflectionException
245
-     */
246
-    public function getMethodsFromReflection(ReflectionClass $reflection_class)
247
-    {
248
-        return $this->getMethods($reflection_class->getName());
249
-    }
28
+	/**
29
+	 * @var ReflectionClass[] $classes
30
+	 */
31
+	private $classes = array();
32
+
33
+	/**
34
+	 * @var ReflectionMethod[] $constructors
35
+	 */
36
+	private $constructors = array();
37
+
38
+	/**
39
+	 * @var ReflectionParameter[][] $parameters
40
+	 */
41
+	private $parameters = array();
42
+
43
+	/**
44
+	 * @var ReflectionParameter[][] $parameters
45
+	 */
46
+	private $parameter_classes = array();
47
+
48
+	/**
49
+	 * @var ReflectionProperty[][] $properties
50
+	 */
51
+	private $properties = array();
52
+
53
+	/**
54
+	 * @var ReflectionMethod[][] $methods
55
+	 */
56
+	private $methods = array();
57
+
58
+
59
+	/**
60
+	 * @param string $class_name
61
+	 * @return ReflectionClass
62
+	 * @throws ReflectionException
63
+	 * @throws InvalidDataTypeException
64
+	 */
65
+	public function getReflectionClass($class_name)
66
+	{
67
+		if (! is_string($class_name)) {
68
+			throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
69
+		}
70
+		if (! isset($this->classes[ $class_name ])) {
71
+			$this->classes[ $class_name ] = new ReflectionClass($class_name);
72
+		}
73
+		return $this->classes[ $class_name ];
74
+	}
75
+
76
+
77
+	/**
78
+	 * @param string $class_name
79
+	 * @return ReflectionMethod
80
+	 * @throws InvalidDataTypeException
81
+	 * @throws ReflectionException
82
+	 */
83
+	public function getConstructor($class_name)
84
+	{
85
+		if (! is_string($class_name)) {
86
+			throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
87
+		}
88
+		if (! isset($this->constructors[ $class_name ])) {
89
+			$reflection_class                  = $this->getReflectionClass($class_name);
90
+			$this->constructors[ $class_name ] = $reflection_class->getConstructor();
91
+		}
92
+		return $this->constructors[ $class_name ];
93
+	}
94
+
95
+
96
+	/**
97
+	 * @param ReflectionClass $reflection_class
98
+	 * @return ReflectionMethod
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws ReflectionException
101
+	 */
102
+	public function getConstructorFromReflection(ReflectionClass $reflection_class)
103
+	{
104
+		return $this->getConstructor($reflection_class->getName());
105
+	}
106
+
107
+
108
+	/**
109
+	 * @param string $class_name
110
+	 * @return ReflectionParameter[]
111
+	 * @throws InvalidDataTypeException
112
+	 * @throws ReflectionException
113
+	 */
114
+	public function getParameters($class_name)
115
+	{
116
+		if (! isset($this->parameters[ $class_name ])) {
117
+			$constructor                     = $this->getConstructor($class_name);
118
+			$this->parameters[ $class_name ] = $constructor->getParameters();
119
+		}
120
+		return $this->parameters[ $class_name ];
121
+	}
122
+
123
+
124
+	/**
125
+	 * @param ReflectionClass $reflection_class
126
+	 * @return ReflectionParameter[]
127
+	 * @throws InvalidDataTypeException
128
+	 * @throws ReflectionException
129
+	 */
130
+	public function getParametersFromReflection(ReflectionClass $reflection_class)
131
+	{
132
+		return $this->getParameters($reflection_class->getName());
133
+	}
134
+
135
+
136
+	/**
137
+	 * @param ReflectionMethod $constructor
138
+	 * @return ReflectionParameter[]
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws ReflectionException
141
+	 */
142
+	public function getParametersFromReflectionConstructor(ReflectionMethod $constructor)
143
+	{
144
+		return $this->getParameters($constructor->getDeclaringClass());
145
+	}
146
+
147
+
148
+	/**
149
+	 * @param ReflectionParameter $param
150
+	 * @param string              $class_name
151
+	 * @param string              $index
152
+	 * @return string|null
153
+	 */
154
+	public function getParameterClassName(ReflectionParameter $param, $class_name, $index)
155
+	{
156
+		if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) {
157
+			return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
158
+		}
159
+		if (! isset($this->parameter_classes[ $class_name ])) {
160
+			$this->parameter_classes[ $class_name ] = array();
161
+		}
162
+		if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
163
+			$this->parameter_classes[ $class_name ][ $index ] = array();
164
+		}
165
+		$this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass()
166
+			? $param->getClass()->name
167
+			: null;
168
+		return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param ReflectionParameter $param
174
+	 * @param string              $class_name
175
+	 * @param string              $index
176
+	 * @return string|null
177
+	 */
178
+	public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index)
179
+	{
180
+		if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) {
181
+			return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
182
+		}
183
+		if (! isset($this->parameter_classes[ $class_name ])) {
184
+			$this->parameter_classes[ $class_name ] = array();
185
+		}
186
+		if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
187
+			$this->parameter_classes[ $class_name ][ $index ] = array();
188
+		}
189
+		$this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable()
190
+			? $param->getDefaultValue()
191
+			: null;
192
+		return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
193
+	}
194
+
195
+
196
+	/**
197
+	 * @param string $class_name
198
+	 * @return ReflectionProperty[]
199
+	 * @throws InvalidDataTypeException
200
+	 * @throws ReflectionException
201
+	 */
202
+	public function getProperties($class_name)
203
+	{
204
+		if (! isset($this->properties[ $class_name ])) {
205
+			$reflection_class                = $this->getReflectionClass($class_name);
206
+			$this->properties[ $class_name ] = $reflection_class->getProperties();
207
+		}
208
+		return $this->properties[ $class_name ];
209
+	}
210
+
211
+
212
+	/**
213
+	 * @param ReflectionClass $reflection_class
214
+	 * @return ReflectionProperty[]
215
+	 * @throws InvalidDataTypeException
216
+	 * @throws ReflectionException
217
+	 */
218
+	public function getPropertiesFromReflection(ReflectionClass $reflection_class)
219
+	{
220
+		return $this->getProperties($reflection_class->getName());
221
+	}
222
+
223
+
224
+	/**
225
+	 * @param string $class_name
226
+	 * @return ReflectionMethod[]
227
+	 * @throws InvalidDataTypeException
228
+	 * @throws ReflectionException
229
+	 */
230
+	public function getMethods($class_name)
231
+	{
232
+		if (! isset($this->methods[ $class_name ])) {
233
+			$reflection_class             = $this->getReflectionClass($class_name);
234
+			$this->methods[ $class_name ] = $reflection_class->getMethods();
235
+		}
236
+		return $this->methods[ $class_name ];
237
+	}
238
+
239
+
240
+	/**
241
+	 * @param ReflectionClass $reflection_class )
242
+	 * @return ReflectionMethod[]
243
+	 * @throws InvalidDataTypeException
244
+	 * @throws ReflectionException
245
+	 */
246
+	public function getMethodsFromReflection(ReflectionClass $reflection_class)
247
+	{
248
+		return $this->getMethods($reflection_class->getName());
249
+	}
250 250
 }
Please login to merge, or discard this patch.
Spacing   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -64,13 +64,13 @@  discard block
 block discarded – undo
64 64
      */
65 65
     public function getReflectionClass($class_name)
66 66
     {
67
-        if (! is_string($class_name)) {
67
+        if ( ! is_string($class_name)) {
68 68
             throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
69 69
         }
70
-        if (! isset($this->classes[ $class_name ])) {
71
-            $this->classes[ $class_name ] = new ReflectionClass($class_name);
70
+        if ( ! isset($this->classes[$class_name])) {
71
+            $this->classes[$class_name] = new ReflectionClass($class_name);
72 72
         }
73
-        return $this->classes[ $class_name ];
73
+        return $this->classes[$class_name];
74 74
     }
75 75
 
76 76
 
@@ -82,14 +82,14 @@  discard block
 block discarded – undo
82 82
      */
83 83
     public function getConstructor($class_name)
84 84
     {
85
-        if (! is_string($class_name)) {
85
+        if ( ! is_string($class_name)) {
86 86
             throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)');
87 87
         }
88
-        if (! isset($this->constructors[ $class_name ])) {
88
+        if ( ! isset($this->constructors[$class_name])) {
89 89
             $reflection_class                  = $this->getReflectionClass($class_name);
90
-            $this->constructors[ $class_name ] = $reflection_class->getConstructor();
90
+            $this->constructors[$class_name] = $reflection_class->getConstructor();
91 91
         }
92
-        return $this->constructors[ $class_name ];
92
+        return $this->constructors[$class_name];
93 93
     }
94 94
 
95 95
 
@@ -113,11 +113,11 @@  discard block
 block discarded – undo
113 113
      */
114 114
     public function getParameters($class_name)
115 115
     {
116
-        if (! isset($this->parameters[ $class_name ])) {
116
+        if ( ! isset($this->parameters[$class_name])) {
117 117
             $constructor                     = $this->getConstructor($class_name);
118
-            $this->parameters[ $class_name ] = $constructor->getParameters();
118
+            $this->parameters[$class_name] = $constructor->getParameters();
119 119
         }
120
-        return $this->parameters[ $class_name ];
120
+        return $this->parameters[$class_name];
121 121
     }
122 122
 
123 123
 
@@ -153,19 +153,19 @@  discard block
 block discarded – undo
153 153
      */
154 154
     public function getParameterClassName(ReflectionParameter $param, $class_name, $index)
155 155
     {
156
-        if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) {
157
-            return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
156
+        if (isset($this->parameter_classes[$class_name][$index]['param_class_name'])) {
157
+            return $this->parameter_classes[$class_name][$index]['param_class_name'];
158 158
         }
159
-        if (! isset($this->parameter_classes[ $class_name ])) {
160
-            $this->parameter_classes[ $class_name ] = array();
159
+        if ( ! isset($this->parameter_classes[$class_name])) {
160
+            $this->parameter_classes[$class_name] = array();
161 161
         }
162
-        if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
163
-            $this->parameter_classes[ $class_name ][ $index ] = array();
162
+        if ( ! isset($this->parameter_classes[$class_name][$index])) {
163
+            $this->parameter_classes[$class_name][$index] = array();
164 164
         }
165
-        $this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass()
165
+        $this->parameter_classes[$class_name][$index]['param_class_name'] = $param->getClass()
166 166
             ? $param->getClass()->name
167 167
             : null;
168
-        return $this->parameter_classes[ $class_name ][ $index ]['param_class_name'];
168
+        return $this->parameter_classes[$class_name][$index]['param_class_name'];
169 169
     }
170 170
 
171 171
 
@@ -177,19 +177,19 @@  discard block
 block discarded – undo
177 177
      */
178 178
     public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index)
179 179
     {
180
-        if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) {
181
-            return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
180
+        if (isset($this->parameter_classes[$class_name][$index]['param_class_default'])) {
181
+            return $this->parameter_classes[$class_name][$index]['param_class_default'];
182 182
         }
183
-        if (! isset($this->parameter_classes[ $class_name ])) {
184
-            $this->parameter_classes[ $class_name ] = array();
183
+        if ( ! isset($this->parameter_classes[$class_name])) {
184
+            $this->parameter_classes[$class_name] = array();
185 185
         }
186
-        if (! isset($this->parameter_classes[ $class_name ][ $index ])) {
187
-            $this->parameter_classes[ $class_name ][ $index ] = array();
186
+        if ( ! isset($this->parameter_classes[$class_name][$index])) {
187
+            $this->parameter_classes[$class_name][$index] = array();
188 188
         }
189
-        $this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable()
189
+        $this->parameter_classes[$class_name][$index]['param_class_default'] = $param->isDefaultValueAvailable()
190 190
             ? $param->getDefaultValue()
191 191
             : null;
192
-        return $this->parameter_classes[ $class_name ][ $index ]['param_class_default'];
192
+        return $this->parameter_classes[$class_name][$index]['param_class_default'];
193 193
     }
194 194
 
195 195
 
@@ -201,11 +201,11 @@  discard block
 block discarded – undo
201 201
      */
202 202
     public function getProperties($class_name)
203 203
     {
204
-        if (! isset($this->properties[ $class_name ])) {
204
+        if ( ! isset($this->properties[$class_name])) {
205 205
             $reflection_class                = $this->getReflectionClass($class_name);
206
-            $this->properties[ $class_name ] = $reflection_class->getProperties();
206
+            $this->properties[$class_name] = $reflection_class->getProperties();
207 207
         }
208
-        return $this->properties[ $class_name ];
208
+        return $this->properties[$class_name];
209 209
     }
210 210
 
211 211
 
@@ -229,11 +229,11 @@  discard block
 block discarded – undo
229 229
      */
230 230
     public function getMethods($class_name)
231 231
     {
232
-        if (! isset($this->methods[ $class_name ])) {
232
+        if ( ! isset($this->methods[$class_name])) {
233 233
             $reflection_class             = $this->getReflectionClass($class_name);
234
-            $this->methods[ $class_name ] = $reflection_class->getMethods();
234
+            $this->methods[$class_name] = $reflection_class->getMethods();
235 235
         }
236
-        return $this->methods[ $class_name ];
236
+        return $this->methods[$class_name];
237 237
     }
238 238
 
239 239
 
Please login to merge, or discard this patch.