Completed
Branch Gutenberg/master (9f7d04)
by
unknown
36:41 queued 27:49
created
core/EE_Session.core.php 2 patches
Indentation   +1267 added lines, -1267 removed lines patch added patch discarded remove patch
@@ -25,1265 +25,1265 @@  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
197
-            && apply_filters('FHEE_load_EE_Session', true)
198
-            && $cache_storage instanceof CacheStorageInterface
199
-            && $lifespan instanceof SessionLifespan
200
-            && $request instanceof RequestInterface
201
-            && $session_start_handler instanceof SessionStartHandler
202
-        ) {
203
-            self::$_instance = new self(
204
-                $cache_storage,
205
-                $lifespan,
206
-                $request,
207
-                $session_start_handler,
208
-                $encryption
209
-            );
210
-        }
211
-        return self::$_instance;
212
-    }
213
-
214
-
215
-    /**
216
-     * protected constructor to prevent direct creation
217
-     *
218
-     * @param CacheStorageInterface $cache_storage
219
-     * @param SessionLifespan       $lifespan
220
-     * @param RequestInterface      $request
221
-     * @param SessionStartHandler   $session_start_handler
222
-     * @param EE_Encryption         $encryption
223
-     * @throws InvalidArgumentException
224
-     * @throws InvalidDataTypeException
225
-     * @throws InvalidInterfaceException
226
-     */
227
-    protected function __construct(
228
-        CacheStorageInterface $cache_storage,
229
-        SessionLifespan $lifespan,
230
-        RequestInterface $request,
231
-        SessionStartHandler $session_start_handler,
232
-        EE_Encryption $encryption = null
233
-    ) {
234
-        // session loading is turned ON by default,
235
-        // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
236
-        // (which currently fires on the init hook at priority 9),
237
-        // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
238
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
239
-            return;
240
-        }
241
-        $this->session_start_handler = $session_start_handler;
242
-        $this->session_lifespan = $lifespan;
243
-        $this->request = $request;
244
-        if (! defined('ESPRESSO_SESSION')) {
245
-            define('ESPRESSO_SESSION', true);
246
-        }
247
-        // retrieve session options from db
248
-        $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
249
-        if (! empty($session_settings)) {
250
-            // cycle though existing session options
251
-            foreach ($session_settings as $var_name => $session_setting) {
252
-                // set values for class properties
253
-                $var_name = '_' . $var_name;
254
-                $this->{$var_name} = $session_setting;
255
-            }
256
-        }
257
-        $this->cache_storage = $cache_storage;
258
-        // are we using encryption?
259
-        $this->_use_encryption = $encryption instanceof EE_Encryption
260
-                                 && EE_Registry::instance()->CFG->admin->encode_session_data();
261
-        // encrypt data via: $this->encryption->encrypt();
262
-        $this->encryption = $encryption;
263
-        // filter hook allows outside functions/classes/plugins to change default empty cart
264
-        $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
265
-        array_merge($this->_default_session_vars, $extra_default_session_vars);
266
-        // apply default session vars
267
-        $this->_set_defaults();
268
-        add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
269
-        // check request for 'clear_session' param
270
-        add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
271
-        // once everything is all said and done,
272
-        add_action('shutdown', array($this, 'update'), 100);
273
-        add_action('shutdown', array($this, 'garbageCollection'), 1000);
274
-        $this->configure_garbage_collection_filters();
275
-    }
276
-
277
-
278
-    /**
279
-     * @return bool
280
-     * @throws InvalidArgumentException
281
-     * @throws InvalidDataTypeException
282
-     * @throws InvalidInterfaceException
283
-     */
284
-    public static function isLoadedAndActive()
285
-    {
286
-        return did_action('AHEE__EE_System__core_loaded_and_ready')
287
-               && EE_Session::instance() instanceof EE_Session
288
-               && EE_Session::instance()->isActive();
289
-    }
290
-
291
-
292
-    /**
293
-     * @return bool
294
-     */
295
-    public function isActive()
296
-    {
297
-        return $this->status === EE_Session::STATUS_OPEN;
298
-    }
299
-
300
-
301
-    /**
302
-     * @return void
303
-     * @throws EE_Error
304
-     * @throws InvalidArgumentException
305
-     * @throws InvalidDataTypeException
306
-     * @throws InvalidInterfaceException
307
-     * @throws InvalidSessionDataException
308
-     */
309
-    public function open_session()
310
-    {
311
-        // check for existing session and retrieve it from db
312
-        if (! $this->_espresso_session()) {
313
-            // or just start a new one
314
-            $this->_create_espresso_session();
315
-        }
316
-    }
317
-
318
-
319
-    /**
320
-     * @return bool
321
-     */
322
-    public function expired()
323
-    {
324
-        return $this->_expired;
325
-    }
326
-
327
-
328
-    /**
329
-     * @return void
330
-     */
331
-    public function reset_expired()
332
-    {
333
-        $this->_expired = false;
334
-    }
335
-
336
-
337
-    /**
338
-     * @return int
339
-     */
340
-    public function expiration()
341
-    {
342
-        return $this->_expiration;
343
-    }
344
-
345
-
346
-    /**
347
-     * @return int
348
-     */
349
-    public function extension()
350
-    {
351
-        return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
352
-    }
353
-
354
-
355
-    /**
356
-     * @param int $time number of seconds to add to session expiration
357
-     */
358
-    public function extend_expiration($time = 0)
359
-    {
360
-        $time = $time ? $time : $this->extension();
361
-        $this->_expiration += absint($time);
362
-    }
363
-
364
-
365
-    /**
366
-     * @return int
367
-     */
368
-    public function lifespan()
369
-    {
370
-        return $this->session_lifespan->inSeconds();
371
-    }
372
-
373
-
374
-    /**
375
-     * This just sets some defaults for the _session data property
376
-     *
377
-     * @access private
378
-     * @return void
379
-     */
380
-    private function _set_defaults()
381
-    {
382
-        // set some defaults
383
-        foreach ($this->_default_session_vars as $key => $default_var) {
384
-            if (is_array($default_var)) {
385
-                $this->_session_data[ $key ] = array();
386
-            } else {
387
-                $this->_session_data[ $key ] = '';
388
-            }
389
-        }
390
-    }
391
-
392
-
393
-    /**
394
-     * @retrieve  session data
395
-     * @access    public
396
-     * @return    string
397
-     */
398
-    public function id()
399
-    {
400
-        return $this->_sid;
401
-    }
402
-
403
-
404
-    /**
405
-     * @param \EE_Cart $cart
406
-     * @return bool
407
-     */
408
-    public function set_cart(EE_Cart $cart)
409
-    {
410
-        $this->_session_data['cart'] = $cart;
411
-        return true;
412
-    }
413
-
414
-
415
-    /**
416
-     * reset_cart
417
-     */
418
-    public function reset_cart()
419
-    {
420
-        do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
421
-        $this->_session_data['cart'] = null;
422
-    }
423
-
424
-
425
-    /**
426
-     * @return \EE_Cart
427
-     */
428
-    public function cart()
429
-    {
430
-        return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
431
-            ? $this->_session_data['cart']
432
-            : null;
433
-    }
434
-
435
-
436
-    /**
437
-     * @param \EE_Checkout $checkout
438
-     * @return bool
439
-     */
440
-    public function set_checkout(EE_Checkout $checkout)
441
-    {
442
-        $this->_session_data['checkout'] = $checkout;
443
-        return true;
444
-    }
445
-
446
-
447
-    /**
448
-     * reset_checkout
449
-     */
450
-    public function reset_checkout()
451
-    {
452
-        do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
453
-        $this->_session_data['checkout'] = null;
454
-    }
455
-
456
-
457
-    /**
458
-     * @return \EE_Checkout
459
-     */
460
-    public function checkout()
461
-    {
462
-        return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
463
-            ? $this->_session_data['checkout']
464
-            : null;
465
-    }
466
-
467
-
468
-    /**
469
-     * @param \EE_Transaction $transaction
470
-     * @return bool
471
-     * @throws EE_Error
472
-     */
473
-    public function set_transaction(EE_Transaction $transaction)
474
-    {
475
-        // first remove the session from the transaction before we save the transaction in the session
476
-        $transaction->set_txn_session_data(null);
477
-        $this->_session_data['transaction'] = $transaction;
478
-        return true;
479
-    }
480
-
481
-
482
-    /**
483
-     * reset_transaction
484
-     */
485
-    public function reset_transaction()
486
-    {
487
-        do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
488
-        $this->_session_data['transaction'] = null;
489
-    }
490
-
491
-
492
-    /**
493
-     * @return \EE_Transaction
494
-     */
495
-    public function transaction()
496
-    {
497
-        return isset($this->_session_data['transaction'])
498
-               && $this->_session_data['transaction'] instanceof EE_Transaction
499
-            ? $this->_session_data['transaction']
500
-            : null;
501
-    }
502
-
503
-
504
-    /**
505
-     * retrieve session data
506
-     *
507
-     * @param null $key
508
-     * @param bool $reset_cache
509
-     * @return array
510
-     */
511
-    public function get_session_data($key = null, $reset_cache = false)
512
-    {
513
-        if ($reset_cache) {
514
-            $this->reset_cart();
515
-            $this->reset_checkout();
516
-            $this->reset_transaction();
517
-        }
518
-        if (! empty($key)) {
519
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
520
-        }
521
-        return $this->_session_data;
522
-    }
523
-
524
-
525
-    /**
526
-     * Returns TRUE on success, FALSE on fail
527
-     *
528
-     * @param array $data
529
-     * @return bool
530
-     */
531
-    public function set_session_data($data)
532
-    {
533
-        // nothing ??? bad data ??? go home!
534
-        if (empty($data) || ! is_array($data)) {
535
-            EE_Error::add_error(
536
-                esc_html__(
537
-                    'No session data or invalid session data was provided.',
538
-                    'event_espresso'
539
-                ),
540
-                __FILE__,
541
-                __FUNCTION__,
542
-                __LINE__
543
-            );
544
-            return false;
545
-        }
546
-        foreach ($data as $key => $value) {
547
-            if (isset($this->_default_session_vars[ $key ])) {
548
-                EE_Error::add_error(
549
-                    sprintf(
550
-                        esc_html__(
551
-                            'Sorry! %s is a default session datum and can not be reset.',
552
-                            'event_espresso'
553
-                        ),
554
-                        $key
555
-                    ),
556
-                    __FILE__,
557
-                    __FUNCTION__,
558
-                    __LINE__
559
-                );
560
-                return false;
561
-            }
562
-            $this->_session_data[ $key ] = $value;
563
-        }
564
-        return true;
565
-    }
566
-
567
-
568
-    /**
569
-     * @initiate session
570
-     * @access   private
571
-     * @return TRUE on success, FALSE on fail
572
-     * @throws EE_Error
573
-     * @throws InvalidArgumentException
574
-     * @throws InvalidDataTypeException
575
-     * @throws InvalidInterfaceException
576
-     * @throws InvalidSessionDataException
577
-     */
578
-    private function _espresso_session()
579
-    {
580
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
581
-        $this->session_start_handler->startSession();
582
-        $this->status = EE_Session::STATUS_OPEN;
583
-        // get our modified session ID
584
-        $this->_sid = $this->_generate_session_id();
585
-        // and the visitors IP
586
-        $this->_ip_address = $this->request->ipAddress();
587
-        // set the "user agent"
588
-        $this->_user_agent = $this->request->userAgent();
589
-        // now let's retrieve what's in the db
590
-        $session_data = $this->_retrieve_session_data();
591
-        if (! empty($session_data)) {
592
-            // get the current time in UTC
593
-            $this->_time = $this->_time !== null ? $this->_time : time();
594
-            // and reset the session expiration
595
-            $this->_expiration = isset($session_data['expiration'])
596
-                ? $session_data['expiration']
597
-                : $this->_time + $this->session_lifespan->inSeconds();
598
-        } else {
599
-            // set initial site access time and the session expiration
600
-            $this->_set_init_access_and_expiration();
601
-            // set referer
602
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
603
-                ? esc_attr($_SERVER['HTTP_REFERER'])
604
-                : '';
605
-            // no previous session = go back and create one (on top of the data above)
606
-            return false;
607
-        }
608
-        // now the user agent
609
-        if ($session_data['user_agent'] !== $this->_user_agent) {
610
-            return false;
611
-        }
612
-        // wait a minute... how old are you?
613
-        if ($this->_time > $this->_expiration) {
614
-            // yer too old fer me!
615
-            $this->_expired = true;
616
-            // wipe out everything that isn't a default session datum
617
-            $this->clear_session(__CLASS__, __FUNCTION__);
618
-        }
619
-        // make event espresso session data available to plugin
620
-        $this->_session_data = array_merge($this->_session_data, $session_data);
621
-        return true;
622
-    }
623
-
624
-
625
-    /**
626
-     * _get_session_data
627
-     * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
628
-     * databases
629
-     *
630
-     * @return array
631
-     * @throws EE_Error
632
-     * @throws InvalidArgumentException
633
-     * @throws InvalidSessionDataException
634
-     * @throws InvalidDataTypeException
635
-     * @throws InvalidInterfaceException
636
-     */
637
-    protected function _retrieve_session_data()
638
-    {
639
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
640
-        try {
641
-            // we're using WP's Transient API to store session data using the PHP session ID as the option name
642
-            $session_data = $this->cache_storage->get($ssn_key, false);
643
-            if (empty($session_data)) {
644
-                return array();
645
-            }
646
-            if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
647
-                $hash_check = $this->cache_storage->get(
648
-                    EE_Session::hash_check_prefix . $this->_sid,
649
-                    false
650
-                );
651
-                if ($hash_check && $hash_check !== md5($session_data)) {
652
-                    EE_Error::add_error(
653
-                        sprintf(
654
-                            __(
655
-                                'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
656
-                                'event_espresso'
657
-                            ),
658
-                            EE_Session::session_id_prefix . $this->_sid
659
-                        ),
660
-                        __FILE__,
661
-                        __FUNCTION__,
662
-                        __LINE__
663
-                    );
664
-                }
665
-            }
666
-        } catch (Exception $e) {
667
-            // let's just eat that error for now and attempt to correct any corrupted data
668
-            global $wpdb;
669
-            $row = $wpdb->get_row(
670
-                $wpdb->prepare(
671
-                    "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
672
-                    '_transient_' . $ssn_key
673
-                )
674
-            );
675
-            $session_data = is_object($row) ? $row->option_value : null;
676
-            if ($session_data) {
677
-                $session_data = preg_replace_callback(
678
-                    '!s:(d+):"(.*?)";!',
679
-                    function ($match) {
680
-                        return $match[1] === strlen($match[2])
681
-                            ? $match[0]
682
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
683
-                    },
684
-                    $session_data
685
-                );
686
-            }
687
-            $session_data = maybe_unserialize($session_data);
688
-        }
689
-        // in case the data is encoded... try to decode it
690
-        $session_data = $this->encryption instanceof EE_Encryption
691
-            ? $this->encryption->base64_string_decode($session_data)
692
-            : $session_data;
693
-        if (! is_array($session_data)) {
694
-            try {
695
-                $session_data = maybe_unserialize($session_data);
696
-            } catch (Exception $e) {
697
-                $msg = esc_html__(
698
-                    'An error occurred while attempting to unserialize the session data.',
699
-                    'event_espresso'
700
-                );
701
-                $msg .= WP_DEBUG
702
-                    ? '<br><pre>'
703
-                      . print_r($session_data, true)
704
-                      . '</pre><br>'
705
-                      . $this->find_serialize_error($session_data)
706
-                    : '';
707
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
708
-                throw new InvalidSessionDataException($msg, 0, $e);
709
-            }
710
-        }
711
-        // just a check to make sure the session array is indeed an array
712
-        if (! is_array($session_data)) {
713
-            // no?!?! then something is wrong
714
-            $msg = esc_html__(
715
-                'The session data is missing, invalid, or corrupted.',
716
-                'event_espresso'
717
-            );
718
-            $msg .= WP_DEBUG
719
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
720
-                : '';
721
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
722
-            throw new InvalidSessionDataException($msg);
723
-        }
724
-        if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
725
-            $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
726
-                $session_data['transaction']
727
-            );
728
-        }
729
-        return $session_data;
730
-    }
731
-
732
-
733
-    /**
734
-     * _generate_session_id
735
-     * Retrieves the PHP session id either directly from the PHP session,
736
-     * or from the $_REQUEST array if it was passed in from an AJAX request.
737
-     * The session id is then salted and hashed (mmm sounds tasty)
738
-     * so that it can be safely used as a $_REQUEST param
739
-     *
740
-     * @return string
741
-     */
742
-    protected function _generate_session_id()
743
-    {
744
-        // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
745
-        if (isset($_REQUEST['EESID'])) {
746
-            $session_id = sanitize_text_field($_REQUEST['EESID']);
747
-        } else {
748
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
749
-        }
750
-        return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
751
-    }
752
-
753
-
754
-    /**
755
-     * _get_sid_salt
756
-     *
757
-     * @return string
758
-     */
759
-    protected function _get_sid_salt()
760
-    {
761
-        // was session id salt already saved to db ?
762
-        if (empty($this->_sid_salt)) {
763
-            // no?  then maybe use WP defined constant
764
-            if (defined('AUTH_SALT')) {
765
-                $this->_sid_salt = AUTH_SALT;
766
-            }
767
-            // if salt doesn't exist or is too short
768
-            if (strlen($this->_sid_salt) < 32) {
769
-                // create a new one
770
-                $this->_sid_salt = wp_generate_password(64);
771
-            }
772
-            // and save it as a permanent session setting
773
-            $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
774
-        }
775
-        return $this->_sid_salt;
776
-    }
777
-
778
-
779
-    /**
780
-     * _set_init_access_and_expiration
781
-     *
782
-     * @return void
783
-     */
784
-    protected function _set_init_access_and_expiration()
785
-    {
786
-        $this->_time = time();
787
-        $this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
788
-        // set initial site access time
789
-        $this->_session_data['init_access'] = $this->_time;
790
-        // and the session expiration
791
-        $this->_session_data['expiration'] = $this->_expiration;
792
-    }
793
-
794
-
795
-    /**
796
-     * @update session data  prior to saving to the db
797
-     * @access public
798
-     * @param bool $new_session
799
-     * @return TRUE on success, FALSE on fail
800
-     * @throws EE_Error
801
-     * @throws InvalidArgumentException
802
-     * @throws InvalidDataTypeException
803
-     * @throws InvalidInterfaceException
804
-     */
805
-    public function update($new_session = false)
806
-    {
807
-        $this->_session_data = $this->_session_data !== null
808
-                               && is_array($this->_session_data)
809
-                               && isset($this->_session_data['id'])
810
-            ? $this->_session_data
811
-            : array();
812
-        if (empty($this->_session_data)) {
813
-            $this->_set_defaults();
814
-        }
815
-        $session_data = array();
816
-        foreach ($this->_session_data as $key => $value) {
817
-            switch ($key) {
818
-                case 'id':
819
-                    // session ID
820
-                    $session_data['id'] = $this->_sid;
821
-                    break;
822
-                case 'ip_address':
823
-                    // visitor ip address
824
-                    $session_data['ip_address'] = $this->request->ipAddress();
825
-                    break;
826
-                case 'user_agent':
827
-                    // visitor user_agent
828
-                    $session_data['user_agent'] = $this->_user_agent;
829
-                    break;
830
-                case 'init_access':
831
-                    $session_data['init_access'] = absint($value);
832
-                    break;
833
-                case 'last_access':
834
-                    // current access time
835
-                    $session_data['last_access'] = $this->_time;
836
-                    break;
837
-                case 'expiration':
838
-                    // when the session expires
839
-                    $session_data['expiration'] = ! empty($this->_expiration)
840
-                        ? $this->_expiration
841
-                        : $session_data['init_access'] + $this->session_lifespan->inSeconds();
842
-                    break;
843
-                case 'user_id':
844
-                    // current user if logged in
845
-                    $session_data['user_id'] = $this->_wp_user_id();
846
-                    break;
847
-                case 'pages_visited':
848
-                    $page_visit = $this->_get_page_visit();
849
-                    if ($page_visit) {
850
-                        // set pages visited where the first will be the http referrer
851
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
852
-                        // we'll only save the last 10 page visits.
853
-                        $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
854
-                    }
855
-                    break;
856
-                default:
857
-                    // carry any other data over
858
-                    $session_data[ $key ] = $this->_session_data[ $key ];
859
-            }
860
-        }
861
-        $this->_session_data = $session_data;
862
-        // creating a new session does not require saving to the db just yet
863
-        if (! $new_session) {
864
-            // ready? let's save
865
-            if ($this->_save_session_to_db()) {
866
-                return true;
867
-            }
868
-            return false;
869
-        }
870
-        // meh, why not?
871
-        return true;
872
-    }
873
-
874
-
875
-    /**
876
-     * @create session data array
877
-     * @access public
878
-     * @return bool
879
-     * @throws EE_Error
880
-     * @throws InvalidArgumentException
881
-     * @throws InvalidDataTypeException
882
-     * @throws InvalidInterfaceException
883
-     */
884
-    private function _create_espresso_session()
885
-    {
886
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
887
-        // use the update function for now with $new_session arg set to TRUE
888
-        return $this->update(true) ? true : false;
889
-    }
890
-
891
-    /**
892
-     * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
893
-     * too). This is used when determining if we want to save the session or not.
894
-     * @since 4.9.67.p
895
-     * @return bool
896
-     */
897
-    private function sessionHasStuffWorthSaving()
898
-    {
899
-        return $this->cart() instanceof EE_Cart
900
-            || (
901
-                isset($this->_session_data['ee_notices'])
902
-                && (
903
-                    ! empty($this->_session_data['ee_notices']['attention'])
904
-                    || !empty($this->_session_data['ee_notices']['errors'])
905
-                    || !empty($this->_session_data['ee_notices']['success'])
906
-                )
907
-            );
908
-    }
909
-    /**
910
-     * _save_session_to_db
911
-     *
912
-     * @param bool $clear_session
913
-     * @return string
914
-     * @throws EE_Error
915
-     * @throws InvalidArgumentException
916
-     * @throws InvalidDataTypeException
917
-     * @throws InvalidInterfaceException
918
-     */
919
-    private function _save_session_to_db($clear_session = false)
920
-    {
921
-        // don't save sessions for crawlers
922
-        // and unless we're deleting the session data, don't save anything if there isn't a cart
923
-        if ($this->request->isBot()
924
-            || (
925
-                ! $clear_session
926
-                && ! $this->sessionHasStuffWorthSaving()
927
-                && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
928
-            )
929
-        ) {
930
-            return false;
931
-        }
932
-        $transaction = $this->transaction();
933
-        if ($transaction instanceof EE_Transaction) {
934
-            if (! $transaction->ID()) {
935
-                $transaction->save();
936
-            }
937
-            $this->_session_data['transaction'] = $transaction->ID();
938
-        }
939
-        // then serialize all of our session data
940
-        $session_data = serialize($this->_session_data);
941
-        // do we need to also encode it to avoid corrupted data when saved to the db?
942
-        $session_data = $this->_use_encryption
943
-            ? $this->encryption->base64_string_encode($session_data)
944
-            : $session_data;
945
-        // maybe save hash check
946
-        if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
947
-            $this->cache_storage->add(
948
-                EE_Session::hash_check_prefix . $this->_sid,
949
-                md5($session_data),
950
-                $this->session_lifespan->inSeconds()
951
-            );
952
-        }
953
-        // we're using the Transient API for storing session data,
954
-        return $this->cache_storage->add(
955
-            EE_Session::session_id_prefix . $this->_sid,
956
-            $session_data,
957
-            $this->session_lifespan->inSeconds()
958
-        );
959
-    }
960
-
961
-
962
-    /**
963
-     * @get    the full page request the visitor is accessing
964
-     * @access public
965
-     * @return string
966
-     */
967
-    public function _get_page_visit()
968
-    {
969
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
970
-        // check for request url
971
-        if (isset($_SERVER['REQUEST_URI'])) {
972
-            $http_host = '';
973
-            $page_id = '?';
974
-            $e_reg = '';
975
-            $request_uri = esc_url($_SERVER['REQUEST_URI']);
976
-            $ru_bits = explode('?', $request_uri);
977
-            $request_uri = $ru_bits[0];
978
-            // check for and grab host as well
979
-            if (isset($_SERVER['HTTP_HOST'])) {
980
-                $http_host = esc_url($_SERVER['HTTP_HOST']);
981
-            }
982
-            // check for page_id in SERVER REQUEST
983
-            if (isset($_REQUEST['page_id'])) {
984
-                // rebuild $e_reg without any of the extra parameters
985
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
986
-            }
987
-            // check for $e_reg in SERVER REQUEST
988
-            if (isset($_REQUEST['ee'])) {
989
-                // rebuild $e_reg without any of the extra parameters
990
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
991
-            }
992
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
993
-        }
994
-        return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
995
-    }
996
-
997
-
998
-    /**
999
-     * @the    current wp user id
1000
-     * @access public
1001
-     * @return int
1002
-     */
1003
-    public function _wp_user_id()
1004
-    {
1005
-        // if I need to explain the following lines of code, then you shouldn't be looking at this!
1006
-        $this->_wp_user_id = get_current_user_id();
1007
-        return $this->_wp_user_id;
1008
-    }
1009
-
1010
-
1011
-    /**
1012
-     * Clear EE_Session data
1013
-     *
1014
-     * @access public
1015
-     * @param string $class
1016
-     * @param string $function
1017
-     * @return void
1018
-     * @throws EE_Error
1019
-     * @throws InvalidArgumentException
1020
-     * @throws InvalidDataTypeException
1021
-     * @throws InvalidInterfaceException
1022
-     */
1023
-    public function clear_session($class = '', $function = '')
1024
-    {
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
197
+			&& apply_filters('FHEE_load_EE_Session', true)
198
+			&& $cache_storage instanceof CacheStorageInterface
199
+			&& $lifespan instanceof SessionLifespan
200
+			&& $request instanceof RequestInterface
201
+			&& $session_start_handler instanceof SessionStartHandler
202
+		) {
203
+			self::$_instance = new self(
204
+				$cache_storage,
205
+				$lifespan,
206
+				$request,
207
+				$session_start_handler,
208
+				$encryption
209
+			);
210
+		}
211
+		return self::$_instance;
212
+	}
213
+
214
+
215
+	/**
216
+	 * protected constructor to prevent direct creation
217
+	 *
218
+	 * @param CacheStorageInterface $cache_storage
219
+	 * @param SessionLifespan       $lifespan
220
+	 * @param RequestInterface      $request
221
+	 * @param SessionStartHandler   $session_start_handler
222
+	 * @param EE_Encryption         $encryption
223
+	 * @throws InvalidArgumentException
224
+	 * @throws InvalidDataTypeException
225
+	 * @throws InvalidInterfaceException
226
+	 */
227
+	protected function __construct(
228
+		CacheStorageInterface $cache_storage,
229
+		SessionLifespan $lifespan,
230
+		RequestInterface $request,
231
+		SessionStartHandler $session_start_handler,
232
+		EE_Encryption $encryption = null
233
+	) {
234
+		// session loading is turned ON by default,
235
+		// but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
236
+		// (which currently fires on the init hook at priority 9),
237
+		// can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
238
+		if (! apply_filters('FHEE_load_EE_Session', true)) {
239
+			return;
240
+		}
241
+		$this->session_start_handler = $session_start_handler;
242
+		$this->session_lifespan = $lifespan;
243
+		$this->request = $request;
244
+		if (! defined('ESPRESSO_SESSION')) {
245
+			define('ESPRESSO_SESSION', true);
246
+		}
247
+		// retrieve session options from db
248
+		$session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
249
+		if (! empty($session_settings)) {
250
+			// cycle though existing session options
251
+			foreach ($session_settings as $var_name => $session_setting) {
252
+				// set values for class properties
253
+				$var_name = '_' . $var_name;
254
+				$this->{$var_name} = $session_setting;
255
+			}
256
+		}
257
+		$this->cache_storage = $cache_storage;
258
+		// are we using encryption?
259
+		$this->_use_encryption = $encryption instanceof EE_Encryption
260
+								 && EE_Registry::instance()->CFG->admin->encode_session_data();
261
+		// encrypt data via: $this->encryption->encrypt();
262
+		$this->encryption = $encryption;
263
+		// filter hook allows outside functions/classes/plugins to change default empty cart
264
+		$extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
265
+		array_merge($this->_default_session_vars, $extra_default_session_vars);
266
+		// apply default session vars
267
+		$this->_set_defaults();
268
+		add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
269
+		// check request for 'clear_session' param
270
+		add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
271
+		// once everything is all said and done,
272
+		add_action('shutdown', array($this, 'update'), 100);
273
+		add_action('shutdown', array($this, 'garbageCollection'), 1000);
274
+		$this->configure_garbage_collection_filters();
275
+	}
276
+
277
+
278
+	/**
279
+	 * @return bool
280
+	 * @throws InvalidArgumentException
281
+	 * @throws InvalidDataTypeException
282
+	 * @throws InvalidInterfaceException
283
+	 */
284
+	public static function isLoadedAndActive()
285
+	{
286
+		return did_action('AHEE__EE_System__core_loaded_and_ready')
287
+			   && EE_Session::instance() instanceof EE_Session
288
+			   && EE_Session::instance()->isActive();
289
+	}
290
+
291
+
292
+	/**
293
+	 * @return bool
294
+	 */
295
+	public function isActive()
296
+	{
297
+		return $this->status === EE_Session::STATUS_OPEN;
298
+	}
299
+
300
+
301
+	/**
302
+	 * @return void
303
+	 * @throws EE_Error
304
+	 * @throws InvalidArgumentException
305
+	 * @throws InvalidDataTypeException
306
+	 * @throws InvalidInterfaceException
307
+	 * @throws InvalidSessionDataException
308
+	 */
309
+	public function open_session()
310
+	{
311
+		// check for existing session and retrieve it from db
312
+		if (! $this->_espresso_session()) {
313
+			// or just start a new one
314
+			$this->_create_espresso_session();
315
+		}
316
+	}
317
+
318
+
319
+	/**
320
+	 * @return bool
321
+	 */
322
+	public function expired()
323
+	{
324
+		return $this->_expired;
325
+	}
326
+
327
+
328
+	/**
329
+	 * @return void
330
+	 */
331
+	public function reset_expired()
332
+	{
333
+		$this->_expired = false;
334
+	}
335
+
336
+
337
+	/**
338
+	 * @return int
339
+	 */
340
+	public function expiration()
341
+	{
342
+		return $this->_expiration;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @return int
348
+	 */
349
+	public function extension()
350
+	{
351
+		return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
352
+	}
353
+
354
+
355
+	/**
356
+	 * @param int $time number of seconds to add to session expiration
357
+	 */
358
+	public function extend_expiration($time = 0)
359
+	{
360
+		$time = $time ? $time : $this->extension();
361
+		$this->_expiration += absint($time);
362
+	}
363
+
364
+
365
+	/**
366
+	 * @return int
367
+	 */
368
+	public function lifespan()
369
+	{
370
+		return $this->session_lifespan->inSeconds();
371
+	}
372
+
373
+
374
+	/**
375
+	 * This just sets some defaults for the _session data property
376
+	 *
377
+	 * @access private
378
+	 * @return void
379
+	 */
380
+	private function _set_defaults()
381
+	{
382
+		// set some defaults
383
+		foreach ($this->_default_session_vars as $key => $default_var) {
384
+			if (is_array($default_var)) {
385
+				$this->_session_data[ $key ] = array();
386
+			} else {
387
+				$this->_session_data[ $key ] = '';
388
+			}
389
+		}
390
+	}
391
+
392
+
393
+	/**
394
+	 * @retrieve  session data
395
+	 * @access    public
396
+	 * @return    string
397
+	 */
398
+	public function id()
399
+	{
400
+		return $this->_sid;
401
+	}
402
+
403
+
404
+	/**
405
+	 * @param \EE_Cart $cart
406
+	 * @return bool
407
+	 */
408
+	public function set_cart(EE_Cart $cart)
409
+	{
410
+		$this->_session_data['cart'] = $cart;
411
+		return true;
412
+	}
413
+
414
+
415
+	/**
416
+	 * reset_cart
417
+	 */
418
+	public function reset_cart()
419
+	{
420
+		do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
421
+		$this->_session_data['cart'] = null;
422
+	}
423
+
424
+
425
+	/**
426
+	 * @return \EE_Cart
427
+	 */
428
+	public function cart()
429
+	{
430
+		return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
431
+			? $this->_session_data['cart']
432
+			: null;
433
+	}
434
+
435
+
436
+	/**
437
+	 * @param \EE_Checkout $checkout
438
+	 * @return bool
439
+	 */
440
+	public function set_checkout(EE_Checkout $checkout)
441
+	{
442
+		$this->_session_data['checkout'] = $checkout;
443
+		return true;
444
+	}
445
+
446
+
447
+	/**
448
+	 * reset_checkout
449
+	 */
450
+	public function reset_checkout()
451
+	{
452
+		do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
453
+		$this->_session_data['checkout'] = null;
454
+	}
455
+
456
+
457
+	/**
458
+	 * @return \EE_Checkout
459
+	 */
460
+	public function checkout()
461
+	{
462
+		return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
463
+			? $this->_session_data['checkout']
464
+			: null;
465
+	}
466
+
467
+
468
+	/**
469
+	 * @param \EE_Transaction $transaction
470
+	 * @return bool
471
+	 * @throws EE_Error
472
+	 */
473
+	public function set_transaction(EE_Transaction $transaction)
474
+	{
475
+		// first remove the session from the transaction before we save the transaction in the session
476
+		$transaction->set_txn_session_data(null);
477
+		$this->_session_data['transaction'] = $transaction;
478
+		return true;
479
+	}
480
+
481
+
482
+	/**
483
+	 * reset_transaction
484
+	 */
485
+	public function reset_transaction()
486
+	{
487
+		do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
488
+		$this->_session_data['transaction'] = null;
489
+	}
490
+
491
+
492
+	/**
493
+	 * @return \EE_Transaction
494
+	 */
495
+	public function transaction()
496
+	{
497
+		return isset($this->_session_data['transaction'])
498
+			   && $this->_session_data['transaction'] instanceof EE_Transaction
499
+			? $this->_session_data['transaction']
500
+			: null;
501
+	}
502
+
503
+
504
+	/**
505
+	 * retrieve session data
506
+	 *
507
+	 * @param null $key
508
+	 * @param bool $reset_cache
509
+	 * @return array
510
+	 */
511
+	public function get_session_data($key = null, $reset_cache = false)
512
+	{
513
+		if ($reset_cache) {
514
+			$this->reset_cart();
515
+			$this->reset_checkout();
516
+			$this->reset_transaction();
517
+		}
518
+		if (! empty($key)) {
519
+			return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
520
+		}
521
+		return $this->_session_data;
522
+	}
523
+
524
+
525
+	/**
526
+	 * Returns TRUE on success, FALSE on fail
527
+	 *
528
+	 * @param array $data
529
+	 * @return bool
530
+	 */
531
+	public function set_session_data($data)
532
+	{
533
+		// nothing ??? bad data ??? go home!
534
+		if (empty($data) || ! is_array($data)) {
535
+			EE_Error::add_error(
536
+				esc_html__(
537
+					'No session data or invalid session data was provided.',
538
+					'event_espresso'
539
+				),
540
+				__FILE__,
541
+				__FUNCTION__,
542
+				__LINE__
543
+			);
544
+			return false;
545
+		}
546
+		foreach ($data as $key => $value) {
547
+			if (isset($this->_default_session_vars[ $key ])) {
548
+				EE_Error::add_error(
549
+					sprintf(
550
+						esc_html__(
551
+							'Sorry! %s is a default session datum and can not be reset.',
552
+							'event_espresso'
553
+						),
554
+						$key
555
+					),
556
+					__FILE__,
557
+					__FUNCTION__,
558
+					__LINE__
559
+				);
560
+				return false;
561
+			}
562
+			$this->_session_data[ $key ] = $value;
563
+		}
564
+		return true;
565
+	}
566
+
567
+
568
+	/**
569
+	 * @initiate session
570
+	 * @access   private
571
+	 * @return TRUE on success, FALSE on fail
572
+	 * @throws EE_Error
573
+	 * @throws InvalidArgumentException
574
+	 * @throws InvalidDataTypeException
575
+	 * @throws InvalidInterfaceException
576
+	 * @throws InvalidSessionDataException
577
+	 */
578
+	private function _espresso_session()
579
+	{
580
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
581
+		$this->session_start_handler->startSession();
582
+		$this->status = EE_Session::STATUS_OPEN;
583
+		// get our modified session ID
584
+		$this->_sid = $this->_generate_session_id();
585
+		// and the visitors IP
586
+		$this->_ip_address = $this->request->ipAddress();
587
+		// set the "user agent"
588
+		$this->_user_agent = $this->request->userAgent();
589
+		// now let's retrieve what's in the db
590
+		$session_data = $this->_retrieve_session_data();
591
+		if (! empty($session_data)) {
592
+			// get the current time in UTC
593
+			$this->_time = $this->_time !== null ? $this->_time : time();
594
+			// and reset the session expiration
595
+			$this->_expiration = isset($session_data['expiration'])
596
+				? $session_data['expiration']
597
+				: $this->_time + $this->session_lifespan->inSeconds();
598
+		} else {
599
+			// set initial site access time and the session expiration
600
+			$this->_set_init_access_and_expiration();
601
+			// set referer
602
+			$this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
603
+				? esc_attr($_SERVER['HTTP_REFERER'])
604
+				: '';
605
+			// no previous session = go back and create one (on top of the data above)
606
+			return false;
607
+		}
608
+		// now the user agent
609
+		if ($session_data['user_agent'] !== $this->_user_agent) {
610
+			return false;
611
+		}
612
+		// wait a minute... how old are you?
613
+		if ($this->_time > $this->_expiration) {
614
+			// yer too old fer me!
615
+			$this->_expired = true;
616
+			// wipe out everything that isn't a default session datum
617
+			$this->clear_session(__CLASS__, __FUNCTION__);
618
+		}
619
+		// make event espresso session data available to plugin
620
+		$this->_session_data = array_merge($this->_session_data, $session_data);
621
+		return true;
622
+	}
623
+
624
+
625
+	/**
626
+	 * _get_session_data
627
+	 * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
628
+	 * databases
629
+	 *
630
+	 * @return array
631
+	 * @throws EE_Error
632
+	 * @throws InvalidArgumentException
633
+	 * @throws InvalidSessionDataException
634
+	 * @throws InvalidDataTypeException
635
+	 * @throws InvalidInterfaceException
636
+	 */
637
+	protected function _retrieve_session_data()
638
+	{
639
+		$ssn_key = EE_Session::session_id_prefix . $this->_sid;
640
+		try {
641
+			// we're using WP's Transient API to store session data using the PHP session ID as the option name
642
+			$session_data = $this->cache_storage->get($ssn_key, false);
643
+			if (empty($session_data)) {
644
+				return array();
645
+			}
646
+			if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
647
+				$hash_check = $this->cache_storage->get(
648
+					EE_Session::hash_check_prefix . $this->_sid,
649
+					false
650
+				);
651
+				if ($hash_check && $hash_check !== md5($session_data)) {
652
+					EE_Error::add_error(
653
+						sprintf(
654
+							__(
655
+								'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
656
+								'event_espresso'
657
+							),
658
+							EE_Session::session_id_prefix . $this->_sid
659
+						),
660
+						__FILE__,
661
+						__FUNCTION__,
662
+						__LINE__
663
+					);
664
+				}
665
+			}
666
+		} catch (Exception $e) {
667
+			// let's just eat that error for now and attempt to correct any corrupted data
668
+			global $wpdb;
669
+			$row = $wpdb->get_row(
670
+				$wpdb->prepare(
671
+					"SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
672
+					'_transient_' . $ssn_key
673
+				)
674
+			);
675
+			$session_data = is_object($row) ? $row->option_value : null;
676
+			if ($session_data) {
677
+				$session_data = preg_replace_callback(
678
+					'!s:(d+):"(.*?)";!',
679
+					function ($match) {
680
+						return $match[1] === strlen($match[2])
681
+							? $match[0]
682
+							: 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
683
+					},
684
+					$session_data
685
+				);
686
+			}
687
+			$session_data = maybe_unserialize($session_data);
688
+		}
689
+		// in case the data is encoded... try to decode it
690
+		$session_data = $this->encryption instanceof EE_Encryption
691
+			? $this->encryption->base64_string_decode($session_data)
692
+			: $session_data;
693
+		if (! is_array($session_data)) {
694
+			try {
695
+				$session_data = maybe_unserialize($session_data);
696
+			} catch (Exception $e) {
697
+				$msg = esc_html__(
698
+					'An error occurred while attempting to unserialize the session data.',
699
+					'event_espresso'
700
+				);
701
+				$msg .= WP_DEBUG
702
+					? '<br><pre>'
703
+					  . print_r($session_data, true)
704
+					  . '</pre><br>'
705
+					  . $this->find_serialize_error($session_data)
706
+					: '';
707
+				$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
708
+				throw new InvalidSessionDataException($msg, 0, $e);
709
+			}
710
+		}
711
+		// just a check to make sure the session array is indeed an array
712
+		if (! is_array($session_data)) {
713
+			// no?!?! then something is wrong
714
+			$msg = esc_html__(
715
+				'The session data is missing, invalid, or corrupted.',
716
+				'event_espresso'
717
+			);
718
+			$msg .= WP_DEBUG
719
+				? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
720
+				: '';
721
+			$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
722
+			throw new InvalidSessionDataException($msg);
723
+		}
724
+		if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
725
+			$session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
726
+				$session_data['transaction']
727
+			);
728
+		}
729
+		return $session_data;
730
+	}
731
+
732
+
733
+	/**
734
+	 * _generate_session_id
735
+	 * Retrieves the PHP session id either directly from the PHP session,
736
+	 * or from the $_REQUEST array if it was passed in from an AJAX request.
737
+	 * The session id is then salted and hashed (mmm sounds tasty)
738
+	 * so that it can be safely used as a $_REQUEST param
739
+	 *
740
+	 * @return string
741
+	 */
742
+	protected function _generate_session_id()
743
+	{
744
+		// check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
745
+		if (isset($_REQUEST['EESID'])) {
746
+			$session_id = sanitize_text_field($_REQUEST['EESID']);
747
+		} else {
748
+			$session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
749
+		}
750
+		return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
751
+	}
752
+
753
+
754
+	/**
755
+	 * _get_sid_salt
756
+	 *
757
+	 * @return string
758
+	 */
759
+	protected function _get_sid_salt()
760
+	{
761
+		// was session id salt already saved to db ?
762
+		if (empty($this->_sid_salt)) {
763
+			// no?  then maybe use WP defined constant
764
+			if (defined('AUTH_SALT')) {
765
+				$this->_sid_salt = AUTH_SALT;
766
+			}
767
+			// if salt doesn't exist or is too short
768
+			if (strlen($this->_sid_salt) < 32) {
769
+				// create a new one
770
+				$this->_sid_salt = wp_generate_password(64);
771
+			}
772
+			// and save it as a permanent session setting
773
+			$this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
774
+		}
775
+		return $this->_sid_salt;
776
+	}
777
+
778
+
779
+	/**
780
+	 * _set_init_access_and_expiration
781
+	 *
782
+	 * @return void
783
+	 */
784
+	protected function _set_init_access_and_expiration()
785
+	{
786
+		$this->_time = time();
787
+		$this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
788
+		// set initial site access time
789
+		$this->_session_data['init_access'] = $this->_time;
790
+		// and the session expiration
791
+		$this->_session_data['expiration'] = $this->_expiration;
792
+	}
793
+
794
+
795
+	/**
796
+	 * @update session data  prior to saving to the db
797
+	 * @access public
798
+	 * @param bool $new_session
799
+	 * @return TRUE on success, FALSE on fail
800
+	 * @throws EE_Error
801
+	 * @throws InvalidArgumentException
802
+	 * @throws InvalidDataTypeException
803
+	 * @throws InvalidInterfaceException
804
+	 */
805
+	public function update($new_session = false)
806
+	{
807
+		$this->_session_data = $this->_session_data !== null
808
+							   && is_array($this->_session_data)
809
+							   && isset($this->_session_data['id'])
810
+			? $this->_session_data
811
+			: array();
812
+		if (empty($this->_session_data)) {
813
+			$this->_set_defaults();
814
+		}
815
+		$session_data = array();
816
+		foreach ($this->_session_data as $key => $value) {
817
+			switch ($key) {
818
+				case 'id':
819
+					// session ID
820
+					$session_data['id'] = $this->_sid;
821
+					break;
822
+				case 'ip_address':
823
+					// visitor ip address
824
+					$session_data['ip_address'] = $this->request->ipAddress();
825
+					break;
826
+				case 'user_agent':
827
+					// visitor user_agent
828
+					$session_data['user_agent'] = $this->_user_agent;
829
+					break;
830
+				case 'init_access':
831
+					$session_data['init_access'] = absint($value);
832
+					break;
833
+				case 'last_access':
834
+					// current access time
835
+					$session_data['last_access'] = $this->_time;
836
+					break;
837
+				case 'expiration':
838
+					// when the session expires
839
+					$session_data['expiration'] = ! empty($this->_expiration)
840
+						? $this->_expiration
841
+						: $session_data['init_access'] + $this->session_lifespan->inSeconds();
842
+					break;
843
+				case 'user_id':
844
+					// current user if logged in
845
+					$session_data['user_id'] = $this->_wp_user_id();
846
+					break;
847
+				case 'pages_visited':
848
+					$page_visit = $this->_get_page_visit();
849
+					if ($page_visit) {
850
+						// set pages visited where the first will be the http referrer
851
+						$this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
852
+						// we'll only save the last 10 page visits.
853
+						$session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
854
+					}
855
+					break;
856
+				default:
857
+					// carry any other data over
858
+					$session_data[ $key ] = $this->_session_data[ $key ];
859
+			}
860
+		}
861
+		$this->_session_data = $session_data;
862
+		// creating a new session does not require saving to the db just yet
863
+		if (! $new_session) {
864
+			// ready? let's save
865
+			if ($this->_save_session_to_db()) {
866
+				return true;
867
+			}
868
+			return false;
869
+		}
870
+		// meh, why not?
871
+		return true;
872
+	}
873
+
874
+
875
+	/**
876
+	 * @create session data array
877
+	 * @access public
878
+	 * @return bool
879
+	 * @throws EE_Error
880
+	 * @throws InvalidArgumentException
881
+	 * @throws InvalidDataTypeException
882
+	 * @throws InvalidInterfaceException
883
+	 */
884
+	private function _create_espresso_session()
885
+	{
886
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
887
+		// use the update function for now with $new_session arg set to TRUE
888
+		return $this->update(true) ? true : false;
889
+	}
890
+
891
+	/**
892
+	 * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
893
+	 * too). This is used when determining if we want to save the session or not.
894
+	 * @since 4.9.67.p
895
+	 * @return bool
896
+	 */
897
+	private function sessionHasStuffWorthSaving()
898
+	{
899
+		return $this->cart() instanceof EE_Cart
900
+			|| (
901
+				isset($this->_session_data['ee_notices'])
902
+				&& (
903
+					! empty($this->_session_data['ee_notices']['attention'])
904
+					|| !empty($this->_session_data['ee_notices']['errors'])
905
+					|| !empty($this->_session_data['ee_notices']['success'])
906
+				)
907
+			);
908
+	}
909
+	/**
910
+	 * _save_session_to_db
911
+	 *
912
+	 * @param bool $clear_session
913
+	 * @return string
914
+	 * @throws EE_Error
915
+	 * @throws InvalidArgumentException
916
+	 * @throws InvalidDataTypeException
917
+	 * @throws InvalidInterfaceException
918
+	 */
919
+	private function _save_session_to_db($clear_session = false)
920
+	{
921
+		// don't save sessions for crawlers
922
+		// and unless we're deleting the session data, don't save anything if there isn't a cart
923
+		if ($this->request->isBot()
924
+			|| (
925
+				! $clear_session
926
+				&& ! $this->sessionHasStuffWorthSaving()
927
+				&& apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
928
+			)
929
+		) {
930
+			return false;
931
+		}
932
+		$transaction = $this->transaction();
933
+		if ($transaction instanceof EE_Transaction) {
934
+			if (! $transaction->ID()) {
935
+				$transaction->save();
936
+			}
937
+			$this->_session_data['transaction'] = $transaction->ID();
938
+		}
939
+		// then serialize all of our session data
940
+		$session_data = serialize($this->_session_data);
941
+		// do we need to also encode it to avoid corrupted data when saved to the db?
942
+		$session_data = $this->_use_encryption
943
+			? $this->encryption->base64_string_encode($session_data)
944
+			: $session_data;
945
+		// maybe save hash check
946
+		if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
947
+			$this->cache_storage->add(
948
+				EE_Session::hash_check_prefix . $this->_sid,
949
+				md5($session_data),
950
+				$this->session_lifespan->inSeconds()
951
+			);
952
+		}
953
+		// we're using the Transient API for storing session data,
954
+		return $this->cache_storage->add(
955
+			EE_Session::session_id_prefix . $this->_sid,
956
+			$session_data,
957
+			$this->session_lifespan->inSeconds()
958
+		);
959
+	}
960
+
961
+
962
+	/**
963
+	 * @get    the full page request the visitor is accessing
964
+	 * @access public
965
+	 * @return string
966
+	 */
967
+	public function _get_page_visit()
968
+	{
969
+		$page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
970
+		// check for request url
971
+		if (isset($_SERVER['REQUEST_URI'])) {
972
+			$http_host = '';
973
+			$page_id = '?';
974
+			$e_reg = '';
975
+			$request_uri = esc_url($_SERVER['REQUEST_URI']);
976
+			$ru_bits = explode('?', $request_uri);
977
+			$request_uri = $ru_bits[0];
978
+			// check for and grab host as well
979
+			if (isset($_SERVER['HTTP_HOST'])) {
980
+				$http_host = esc_url($_SERVER['HTTP_HOST']);
981
+			}
982
+			// check for page_id in SERVER REQUEST
983
+			if (isset($_REQUEST['page_id'])) {
984
+				// rebuild $e_reg without any of the extra parameters
985
+				$page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
986
+			}
987
+			// check for $e_reg in SERVER REQUEST
988
+			if (isset($_REQUEST['ee'])) {
989
+				// rebuild $e_reg without any of the extra parameters
990
+				$e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
991
+			}
992
+			$page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
993
+		}
994
+		return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
995
+	}
996
+
997
+
998
+	/**
999
+	 * @the    current wp user id
1000
+	 * @access public
1001
+	 * @return int
1002
+	 */
1003
+	public function _wp_user_id()
1004
+	{
1005
+		// if I need to explain the following lines of code, then you shouldn't be looking at this!
1006
+		$this->_wp_user_id = get_current_user_id();
1007
+		return $this->_wp_user_id;
1008
+	}
1009
+
1010
+
1011
+	/**
1012
+	 * Clear EE_Session data
1013
+	 *
1014
+	 * @access public
1015
+	 * @param string $class
1016
+	 * @param string $function
1017
+	 * @return void
1018
+	 * @throws EE_Error
1019
+	 * @throws InvalidArgumentException
1020
+	 * @throws InvalidDataTypeException
1021
+	 * @throws InvalidInterfaceException
1022
+	 */
1023
+	public function clear_session($class = '', $function = '')
1024
+	{
1025 1025
 //         echo '
1026 1026
 // <h3 style="color:#999;line-height:.9em;">
1027 1027
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1028 1028
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1029 1029
 // </h3>';
1030
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1031
-        $this->reset_cart();
1032
-        $this->reset_checkout();
1033
-        $this->reset_transaction();
1034
-        // wipe out everything that isn't a default session datum
1035
-        $this->reset_data(array_keys($this->_session_data));
1036
-        // reset initial site access time and the session expiration
1037
-        $this->_set_init_access_and_expiration();
1038
-        $this->_save_session_to_db(true);
1039
-    }
1040
-
1041
-
1042
-    /**
1043
-     * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1044
-     *
1045
-     * @param array|mixed $data_to_reset
1046
-     * @param bool        $show_all_notices
1047
-     * @return bool
1048
-     */
1049
-    public function reset_data($data_to_reset = array(), $show_all_notices = false)
1050
-    {
1051
-        // if $data_to_reset is not in an array, then put it in one
1052
-        if (! is_array($data_to_reset)) {
1053
-            $data_to_reset = array($data_to_reset);
1054
-        }
1055
-        // nothing ??? go home!
1056
-        if (empty($data_to_reset)) {
1057
-            EE_Error::add_error(
1058
-                __(
1059
-                    'No session data could be reset, because no session var name was provided.',
1060
-                    'event_espresso'
1061
-                ),
1062
-                __FILE__,
1063
-                __FUNCTION__,
1064
-                __LINE__
1065
-            );
1066
-            return false;
1067
-        }
1068
-        $return_value = true;
1069
-        // since $data_to_reset is an array, cycle through the values
1070
-        foreach ($data_to_reset as $reset) {
1071
-            // first check to make sure it is a valid session var
1072
-            if (isset($this->_session_data[ $reset ])) {
1073
-                // then check to make sure it is not a default var
1074
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1075
-                    // remove session var
1076
-                    unset($this->_session_data[ $reset ]);
1077
-                    if ($show_all_notices) {
1078
-                        EE_Error::add_success(
1079
-                            sprintf(
1080
-                                __('The session variable %s was removed.', 'event_espresso'),
1081
-                                $reset
1082
-                            ),
1083
-                            __FILE__,
1084
-                            __FUNCTION__,
1085
-                            __LINE__
1086
-                        );
1087
-                    }
1088
-                } else {
1089
-                    // yeeeeeeeeerrrrrrrrrrr OUT !!!!
1090
-                    if ($show_all_notices) {
1091
-                        EE_Error::add_error(
1092
-                            sprintf(
1093
-                                __(
1094
-                                    'Sorry! %s is a default session datum and can not be reset.',
1095
-                                    'event_espresso'
1096
-                                ),
1097
-                                $reset
1098
-                            ),
1099
-                            __FILE__,
1100
-                            __FUNCTION__,
1101
-                            __LINE__
1102
-                        );
1103
-                    }
1104
-                    $return_value = false;
1105
-                }
1106
-            } elseif ($show_all_notices) {
1107
-                // oops! that session var does not exist!
1108
-                EE_Error::add_error(
1109
-                    sprintf(
1110
-                        __(
1111
-                            'The session item provided, %s, is invalid or does not exist.',
1112
-                            'event_espresso'
1113
-                        ),
1114
-                        $reset
1115
-                    ),
1116
-                    __FILE__,
1117
-                    __FUNCTION__,
1118
-                    __LINE__
1119
-                );
1120
-                $return_value = false;
1121
-            }
1122
-        } // end of foreach
1123
-        return $return_value;
1124
-    }
1125
-
1126
-
1127
-    /**
1128
-     *   wp_loaded
1129
-     *
1130
-     * @access public
1131
-     * @throws EE_Error
1132
-     * @throws InvalidDataTypeException
1133
-     * @throws InvalidInterfaceException
1134
-     * @throws InvalidArgumentException
1135
-     */
1136
-    public function wp_loaded()
1137
-    {
1138
-        if ($this->request->requestParamIsSet('clear_session')) {
1139
-            $this->clear_session(__CLASS__, __FUNCTION__);
1140
-        }
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * Used to reset the entire object (for tests).
1146
-     *
1147
-     * @since 4.3.0
1148
-     * @throws EE_Error
1149
-     * @throws InvalidDataTypeException
1150
-     * @throws InvalidInterfaceException
1151
-     * @throws InvalidArgumentException
1152
-     */
1153
-    public function reset_instance()
1154
-    {
1155
-        $this->clear_session();
1156
-        self::$_instance = null;
1157
-    }
1158
-
1159
-
1160
-    public function configure_garbage_collection_filters()
1161
-    {
1162
-        // run old filter we had for controlling session cleanup
1163
-        $expired_session_transient_delete_query_limit = absint(
1164
-            apply_filters(
1165
-                'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1166
-                50
1167
-            )
1168
-        );
1169
-        // is there a value? or one that is different than the default 50 records?
1170
-        if ($expired_session_transient_delete_query_limit === 0) {
1171
-            // hook into TransientCacheStorage in case Session cleanup was turned off
1172
-            add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1173
-        } elseif ($expired_session_transient_delete_query_limit !== 50) {
1174
-            // or use that for the new transient cleanup query limit
1175
-            add_filter(
1176
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1177
-                function () use ($expired_session_transient_delete_query_limit) {
1178
-                    return $expired_session_transient_delete_query_limit;
1179
-                }
1180
-            );
1181
-        }
1182
-    }
1183
-
1184
-
1185
-    /**
1186
-     * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1187
-     * @param $data1
1188
-     * @return string
1189
-     */
1190
-    private function find_serialize_error($data1)
1191
-    {
1192
-        $error = '<pre>';
1193
-        $data2 = preg_replace_callback(
1194
-            '!s:(\d+):"(.*?)";!',
1195
-            function ($match) {
1196
-                return ($match[1] === strlen($match[2]))
1197
-                    ? $match[0]
1198
-                    : 's:'
1199
-                      . strlen($match[2])
1200
-                      . ':"'
1201
-                      . $match[2]
1202
-                      . '";';
1203
-            },
1204
-            $data1
1205
-        );
1206
-        $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1207
-        $error .= $data1 . PHP_EOL;
1208
-        $error .= $data2 . PHP_EOL;
1209
-        for ($i = 0; $i < $max; $i++) {
1210
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1211
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1212
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1213
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1214
-                $start = ($i - 20);
1215
-                $start = ($start < 0) ? 0 : $start;
1216
-                $length = 40;
1217
-                $point = $max - $i;
1218
-                if ($point < 20) {
1219
-                    $rlength = 1;
1220
-                    $rpoint = -$point;
1221
-                } else {
1222
-                    $rpoint = $length - 20;
1223
-                    $rlength = 1;
1224
-                }
1225
-                $error .= "\t-> Section Data1  = ";
1226
-                $error .= substr_replace(
1227
-                    substr($data1, $start, $length),
1228
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1229
-                    $rpoint,
1230
-                    $rlength
1231
-                );
1232
-                $error .= PHP_EOL;
1233
-                $error .= "\t-> Section Data2  = ";
1234
-                $error .= substr_replace(
1235
-                    substr($data2, $start, $length),
1236
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1237
-                    $rpoint,
1238
-                    $rlength
1239
-                );
1240
-                $error .= PHP_EOL;
1241
-            }
1242
-        }
1243
-        $error .= '</pre>';
1244
-        return $error;
1245
-    }
1246
-
1247
-
1248
-    /**
1249
-     * Saves an  array of settings used for configuring aspects of session behaviour
1250
-     *
1251
-     * @param array $updated_settings
1252
-     */
1253
-    private function updateSessionSettings(array $updated_settings = array())
1254
-    {
1255
-        // add existing settings, but only if not included in incoming $updated_settings array
1256
-        $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1257
-        update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * garbage_collection
1263
-     */
1264
-    public function garbageCollection()
1265
-    {
1266
-        // only perform during regular requests if last garbage collection was over an hour ago
1267
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1268
-            $this->_last_gc = time();
1269
-            $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1270
-            /** @type WPDB $wpdb */
1271
-            global $wpdb;
1272
-            // filter the query limit. Set to 0 to turn off garbage collection
1273
-            $expired_session_transient_delete_query_limit = absint(
1274
-                apply_filters(
1275
-                    'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1276
-                    50
1277
-                )
1278
-            );
1279
-            // non-zero LIMIT means take out the trash
1280
-            if ($expired_session_transient_delete_query_limit) {
1281
-                $session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1282
-                $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1283
-                // since transient expiration timestamps are set in the future, we can compare against NOW
1284
-                // but we only want to pick up any trash that's been around for more than a day
1285
-                $expiration = time() - DAY_IN_SECONDS;
1286
-                $SQL = "
1030
+		do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1031
+		$this->reset_cart();
1032
+		$this->reset_checkout();
1033
+		$this->reset_transaction();
1034
+		// wipe out everything that isn't a default session datum
1035
+		$this->reset_data(array_keys($this->_session_data));
1036
+		// reset initial site access time and the session expiration
1037
+		$this->_set_init_access_and_expiration();
1038
+		$this->_save_session_to_db(true);
1039
+	}
1040
+
1041
+
1042
+	/**
1043
+	 * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1044
+	 *
1045
+	 * @param array|mixed $data_to_reset
1046
+	 * @param bool        $show_all_notices
1047
+	 * @return bool
1048
+	 */
1049
+	public function reset_data($data_to_reset = array(), $show_all_notices = false)
1050
+	{
1051
+		// if $data_to_reset is not in an array, then put it in one
1052
+		if (! is_array($data_to_reset)) {
1053
+			$data_to_reset = array($data_to_reset);
1054
+		}
1055
+		// nothing ??? go home!
1056
+		if (empty($data_to_reset)) {
1057
+			EE_Error::add_error(
1058
+				__(
1059
+					'No session data could be reset, because no session var name was provided.',
1060
+					'event_espresso'
1061
+				),
1062
+				__FILE__,
1063
+				__FUNCTION__,
1064
+				__LINE__
1065
+			);
1066
+			return false;
1067
+		}
1068
+		$return_value = true;
1069
+		// since $data_to_reset is an array, cycle through the values
1070
+		foreach ($data_to_reset as $reset) {
1071
+			// first check to make sure it is a valid session var
1072
+			if (isset($this->_session_data[ $reset ])) {
1073
+				// then check to make sure it is not a default var
1074
+				if (! array_key_exists($reset, $this->_default_session_vars)) {
1075
+					// remove session var
1076
+					unset($this->_session_data[ $reset ]);
1077
+					if ($show_all_notices) {
1078
+						EE_Error::add_success(
1079
+							sprintf(
1080
+								__('The session variable %s was removed.', 'event_espresso'),
1081
+								$reset
1082
+							),
1083
+							__FILE__,
1084
+							__FUNCTION__,
1085
+							__LINE__
1086
+						);
1087
+					}
1088
+				} else {
1089
+					// yeeeeeeeeerrrrrrrrrrr OUT !!!!
1090
+					if ($show_all_notices) {
1091
+						EE_Error::add_error(
1092
+							sprintf(
1093
+								__(
1094
+									'Sorry! %s is a default session datum and can not be reset.',
1095
+									'event_espresso'
1096
+								),
1097
+								$reset
1098
+							),
1099
+							__FILE__,
1100
+							__FUNCTION__,
1101
+							__LINE__
1102
+						);
1103
+					}
1104
+					$return_value = false;
1105
+				}
1106
+			} elseif ($show_all_notices) {
1107
+				// oops! that session var does not exist!
1108
+				EE_Error::add_error(
1109
+					sprintf(
1110
+						__(
1111
+							'The session item provided, %s, is invalid or does not exist.',
1112
+							'event_espresso'
1113
+						),
1114
+						$reset
1115
+					),
1116
+					__FILE__,
1117
+					__FUNCTION__,
1118
+					__LINE__
1119
+				);
1120
+				$return_value = false;
1121
+			}
1122
+		} // end of foreach
1123
+		return $return_value;
1124
+	}
1125
+
1126
+
1127
+	/**
1128
+	 *   wp_loaded
1129
+	 *
1130
+	 * @access public
1131
+	 * @throws EE_Error
1132
+	 * @throws InvalidDataTypeException
1133
+	 * @throws InvalidInterfaceException
1134
+	 * @throws InvalidArgumentException
1135
+	 */
1136
+	public function wp_loaded()
1137
+	{
1138
+		if ($this->request->requestParamIsSet('clear_session')) {
1139
+			$this->clear_session(__CLASS__, __FUNCTION__);
1140
+		}
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * Used to reset the entire object (for tests).
1146
+	 *
1147
+	 * @since 4.3.0
1148
+	 * @throws EE_Error
1149
+	 * @throws InvalidDataTypeException
1150
+	 * @throws InvalidInterfaceException
1151
+	 * @throws InvalidArgumentException
1152
+	 */
1153
+	public function reset_instance()
1154
+	{
1155
+		$this->clear_session();
1156
+		self::$_instance = null;
1157
+	}
1158
+
1159
+
1160
+	public function configure_garbage_collection_filters()
1161
+	{
1162
+		// run old filter we had for controlling session cleanup
1163
+		$expired_session_transient_delete_query_limit = absint(
1164
+			apply_filters(
1165
+				'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1166
+				50
1167
+			)
1168
+		);
1169
+		// is there a value? or one that is different than the default 50 records?
1170
+		if ($expired_session_transient_delete_query_limit === 0) {
1171
+			// hook into TransientCacheStorage in case Session cleanup was turned off
1172
+			add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1173
+		} elseif ($expired_session_transient_delete_query_limit !== 50) {
1174
+			// or use that for the new transient cleanup query limit
1175
+			add_filter(
1176
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1177
+				function () use ($expired_session_transient_delete_query_limit) {
1178
+					return $expired_session_transient_delete_query_limit;
1179
+				}
1180
+			);
1181
+		}
1182
+	}
1183
+
1184
+
1185
+	/**
1186
+	 * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1187
+	 * @param $data1
1188
+	 * @return string
1189
+	 */
1190
+	private function find_serialize_error($data1)
1191
+	{
1192
+		$error = '<pre>';
1193
+		$data2 = preg_replace_callback(
1194
+			'!s:(\d+):"(.*?)";!',
1195
+			function ($match) {
1196
+				return ($match[1] === strlen($match[2]))
1197
+					? $match[0]
1198
+					: 's:'
1199
+					  . strlen($match[2])
1200
+					  . ':"'
1201
+					  . $match[2]
1202
+					  . '";';
1203
+			},
1204
+			$data1
1205
+		);
1206
+		$max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1207
+		$error .= $data1 . PHP_EOL;
1208
+		$error .= $data2 . PHP_EOL;
1209
+		for ($i = 0; $i < $max; $i++) {
1210
+			if (@$data1[ $i ] !== @$data2[ $i ]) {
1211
+				$error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1212
+				$error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1213
+				$error .= "\t-> Line Number = $i" . PHP_EOL;
1214
+				$start = ($i - 20);
1215
+				$start = ($start < 0) ? 0 : $start;
1216
+				$length = 40;
1217
+				$point = $max - $i;
1218
+				if ($point < 20) {
1219
+					$rlength = 1;
1220
+					$rpoint = -$point;
1221
+				} else {
1222
+					$rpoint = $length - 20;
1223
+					$rlength = 1;
1224
+				}
1225
+				$error .= "\t-> Section Data1  = ";
1226
+				$error .= substr_replace(
1227
+					substr($data1, $start, $length),
1228
+					"<b style=\"color:green\">{$data1[ $i ]}</b>",
1229
+					$rpoint,
1230
+					$rlength
1231
+				);
1232
+				$error .= PHP_EOL;
1233
+				$error .= "\t-> Section Data2  = ";
1234
+				$error .= substr_replace(
1235
+					substr($data2, $start, $length),
1236
+					"<b style=\"color:red\">{$data2[ $i ]}</b>",
1237
+					$rpoint,
1238
+					$rlength
1239
+				);
1240
+				$error .= PHP_EOL;
1241
+			}
1242
+		}
1243
+		$error .= '</pre>';
1244
+		return $error;
1245
+	}
1246
+
1247
+
1248
+	/**
1249
+	 * Saves an  array of settings used for configuring aspects of session behaviour
1250
+	 *
1251
+	 * @param array $updated_settings
1252
+	 */
1253
+	private function updateSessionSettings(array $updated_settings = array())
1254
+	{
1255
+		// add existing settings, but only if not included in incoming $updated_settings array
1256
+		$updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1257
+		update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * garbage_collection
1263
+	 */
1264
+	public function garbageCollection()
1265
+	{
1266
+		// only perform during regular requests if last garbage collection was over an hour ago
1267
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1268
+			$this->_last_gc = time();
1269
+			$this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1270
+			/** @type WPDB $wpdb */
1271
+			global $wpdb;
1272
+			// filter the query limit. Set to 0 to turn off garbage collection
1273
+			$expired_session_transient_delete_query_limit = absint(
1274
+				apply_filters(
1275
+					'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1276
+					50
1277
+				)
1278
+			);
1279
+			// non-zero LIMIT means take out the trash
1280
+			if ($expired_session_transient_delete_query_limit) {
1281
+				$session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1282
+				$hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1283
+				// since transient expiration timestamps are set in the future, we can compare against NOW
1284
+				// but we only want to pick up any trash that's been around for more than a day
1285
+				$expiration = time() - DAY_IN_SECONDS;
1286
+				$SQL = "
1287 1287
                     SELECT option_name
1288 1288
                     FROM {$wpdb->options}
1289 1289
                     WHERE
@@ -1292,17 +1292,17 @@  discard block
 block discarded – undo
1292 1292
                     AND option_value < {$expiration}
1293 1293
                     LIMIT {$expired_session_transient_delete_query_limit}
1294 1294
                 ";
1295
-                // produces something like:
1296
-                // SELECT option_name FROM wp_options
1297
-                // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1298
-                // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1299
-                // AND option_value < 1508368198 LIMIT 50
1300
-                $expired_sessions = $wpdb->get_col($SQL);
1301
-                // valid results?
1302
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1303
-                    $this->cache_storage->deleteMany($expired_sessions, true);
1304
-                }
1305
-            }
1306
-        }
1307
-    }
1295
+				// produces something like:
1296
+				// SELECT option_name FROM wp_options
1297
+				// WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1298
+				// OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1299
+				// AND option_value < 1508368198 LIMIT 50
1300
+				$expired_sessions = $wpdb->get_col($SQL);
1301
+				// valid results?
1302
+				if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1303
+					$this->cache_storage->deleteMany($expired_sessions, true);
1304
+				}
1305
+			}
1306
+		}
1307
+	}
1308 1308
 }
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
196
+        if ( ! self::$_instance instanceof EE_Session
197 197
             && apply_filters('FHEE_load_EE_Session', true)
198 198
             && $cache_storage instanceof CacheStorageInterface
199 199
             && $lifespan instanceof SessionLifespan
@@ -235,22 +235,22 @@  discard block
 block discarded – undo
235 235
         // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
236 236
         // (which currently fires on the init hook at priority 9),
237 237
         // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
238
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
238
+        if ( ! apply_filters('FHEE_load_EE_Session', true)) {
239 239
             return;
240 240
         }
241 241
         $this->session_start_handler = $session_start_handler;
242 242
         $this->session_lifespan = $lifespan;
243 243
         $this->request = $request;
244
-        if (! defined('ESPRESSO_SESSION')) {
244
+        if ( ! defined('ESPRESSO_SESSION')) {
245 245
             define('ESPRESSO_SESSION', true);
246 246
         }
247 247
         // retrieve session options from db
248 248
         $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
249
-        if (! empty($session_settings)) {
249
+        if ( ! empty($session_settings)) {
250 250
             // cycle though existing session options
251 251
             foreach ($session_settings as $var_name => $session_setting) {
252 252
                 // set values for class properties
253
-                $var_name = '_' . $var_name;
253
+                $var_name = '_'.$var_name;
254 254
                 $this->{$var_name} = $session_setting;
255 255
             }
256 256
         }
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
     public function open_session()
310 310
     {
311 311
         // check for existing session and retrieve it from db
312
-        if (! $this->_espresso_session()) {
312
+        if ( ! $this->_espresso_session()) {
313 313
             // or just start a new one
314 314
             $this->_create_espresso_session();
315 315
         }
@@ -382,9 +382,9 @@  discard block
 block discarded – undo
382 382
         // set some defaults
383 383
         foreach ($this->_default_session_vars as $key => $default_var) {
384 384
             if (is_array($default_var)) {
385
-                $this->_session_data[ $key ] = array();
385
+                $this->_session_data[$key] = array();
386 386
             } else {
387
-                $this->_session_data[ $key ] = '';
387
+                $this->_session_data[$key] = '';
388 388
             }
389 389
         }
390 390
     }
@@ -515,8 +515,8 @@  discard block
 block discarded – undo
515 515
             $this->reset_checkout();
516 516
             $this->reset_transaction();
517 517
         }
518
-        if (! empty($key)) {
519
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
518
+        if ( ! empty($key)) {
519
+            return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null;
520 520
         }
521 521
         return $this->_session_data;
522 522
     }
@@ -544,7 +544,7 @@  discard block
 block discarded – undo
544 544
             return false;
545 545
         }
546 546
         foreach ($data as $key => $value) {
547
-            if (isset($this->_default_session_vars[ $key ])) {
547
+            if (isset($this->_default_session_vars[$key])) {
548 548
                 EE_Error::add_error(
549 549
                     sprintf(
550 550
                         esc_html__(
@@ -559,7 +559,7 @@  discard block
 block discarded – undo
559 559
                 );
560 560
                 return false;
561 561
             }
562
-            $this->_session_data[ $key ] = $value;
562
+            $this->_session_data[$key] = $value;
563 563
         }
564 564
         return true;
565 565
     }
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
         $this->_user_agent = $this->request->userAgent();
589 589
         // now let's retrieve what's in the db
590 590
         $session_data = $this->_retrieve_session_data();
591
-        if (! empty($session_data)) {
591
+        if ( ! empty($session_data)) {
592 592
             // get the current time in UTC
593 593
             $this->_time = $this->_time !== null ? $this->_time : time();
594 594
             // and reset the session expiration
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
             // set initial site access time and the session expiration
600 600
             $this->_set_init_access_and_expiration();
601 601
             // set referer
602
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
602
+            $this->_session_data['pages_visited'][$this->_session_data['init_access']] = isset($_SERVER['HTTP_REFERER'])
603 603
                 ? esc_attr($_SERVER['HTTP_REFERER'])
604 604
                 : '';
605 605
             // no previous session = go back and create one (on top of the data above)
@@ -636,7 +636,7 @@  discard block
 block discarded – undo
636 636
      */
637 637
     protected function _retrieve_session_data()
638 638
     {
639
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
639
+        $ssn_key = EE_Session::session_id_prefix.$this->_sid;
640 640
         try {
641 641
             // we're using WP's Transient API to store session data using the PHP session ID as the option name
642 642
             $session_data = $this->cache_storage->get($ssn_key, false);
@@ -645,7 +645,7 @@  discard block
 block discarded – undo
645 645
             }
646 646
             if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
647 647
                 $hash_check = $this->cache_storage->get(
648
-                    EE_Session::hash_check_prefix . $this->_sid,
648
+                    EE_Session::hash_check_prefix.$this->_sid,
649 649
                     false
650 650
                 );
651 651
                 if ($hash_check && $hash_check !== md5($session_data)) {
@@ -655,7 +655,7 @@  discard block
 block discarded – undo
655 655
                                 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
656 656
                                 'event_espresso'
657 657
                             ),
658
-                            EE_Session::session_id_prefix . $this->_sid
658
+                            EE_Session::session_id_prefix.$this->_sid
659 659
                         ),
660 660
                         __FILE__,
661 661
                         __FUNCTION__,
@@ -669,17 +669,17 @@  discard block
 block discarded – undo
669 669
             $row = $wpdb->get_row(
670 670
                 $wpdb->prepare(
671 671
                     "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
672
-                    '_transient_' . $ssn_key
672
+                    '_transient_'.$ssn_key
673 673
                 )
674 674
             );
675 675
             $session_data = is_object($row) ? $row->option_value : null;
676 676
             if ($session_data) {
677 677
                 $session_data = preg_replace_callback(
678 678
                     '!s:(d+):"(.*?)";!',
679
-                    function ($match) {
679
+                    function($match) {
680 680
                         return $match[1] === strlen($match[2])
681 681
                             ? $match[0]
682
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
682
+                            : 's:'.strlen($match[2]).':"'.$match[2].'";';
683 683
                     },
684 684
                     $session_data
685 685
                 );
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
         $session_data = $this->encryption instanceof EE_Encryption
691 691
             ? $this->encryption->base64_string_decode($session_data)
692 692
             : $session_data;
693
-        if (! is_array($session_data)) {
693
+        if ( ! is_array($session_data)) {
694 694
             try {
695 695
                 $session_data = maybe_unserialize($session_data);
696 696
             } catch (Exception $e) {
@@ -704,21 +704,21 @@  discard block
 block discarded – undo
704 704
                       . '</pre><br>'
705 705
                       . $this->find_serialize_error($session_data)
706 706
                     : '';
707
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
707
+                $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
708 708
                 throw new InvalidSessionDataException($msg, 0, $e);
709 709
             }
710 710
         }
711 711
         // just a check to make sure the session array is indeed an array
712
-        if (! is_array($session_data)) {
712
+        if ( ! is_array($session_data)) {
713 713
             // no?!?! then something is wrong
714 714
             $msg = esc_html__(
715 715
                 'The session data is missing, invalid, or corrupted.',
716 716
                 'event_espresso'
717 717
             );
718 718
             $msg .= WP_DEBUG
719
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
719
+                ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data)
720 720
                 : '';
721
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
721
+            $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
722 722
             throw new InvalidSessionDataException($msg);
723 723
         }
724 724
         if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
@@ -745,7 +745,7 @@  discard block
 block discarded – undo
745 745
         if (isset($_REQUEST['EESID'])) {
746 746
             $session_id = sanitize_text_field($_REQUEST['EESID']);
747 747
         } else {
748
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
748
+            $session_id = md5(session_id().get_current_blog_id().$this->_get_sid_salt());
749 749
         }
750 750
         return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
751 751
     }
@@ -848,19 +848,19 @@  discard block
 block discarded – undo
848 848
                     $page_visit = $this->_get_page_visit();
849 849
                     if ($page_visit) {
850 850
                         // set pages visited where the first will be the http referrer
851
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
851
+                        $this->_session_data['pages_visited'][$this->_time] = $page_visit;
852 852
                         // we'll only save the last 10 page visits.
853 853
                         $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
854 854
                     }
855 855
                     break;
856 856
                 default:
857 857
                     // carry any other data over
858
-                    $session_data[ $key ] = $this->_session_data[ $key ];
858
+                    $session_data[$key] = $this->_session_data[$key];
859 859
             }
860 860
         }
861 861
         $this->_session_data = $session_data;
862 862
         // creating a new session does not require saving to the db just yet
863
-        if (! $new_session) {
863
+        if ( ! $new_session) {
864 864
             // ready? let's save
865 865
             if ($this->_save_session_to_db()) {
866 866
                 return true;
@@ -901,8 +901,8 @@  discard block
 block discarded – undo
901 901
                 isset($this->_session_data['ee_notices'])
902 902
                 && (
903 903
                     ! empty($this->_session_data['ee_notices']['attention'])
904
-                    || !empty($this->_session_data['ee_notices']['errors'])
905
-                    || !empty($this->_session_data['ee_notices']['success'])
904
+                    || ! empty($this->_session_data['ee_notices']['errors'])
905
+                    || ! empty($this->_session_data['ee_notices']['success'])
906 906
                 )
907 907
             );
908 908
     }
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
         }
932 932
         $transaction = $this->transaction();
933 933
         if ($transaction instanceof EE_Transaction) {
934
-            if (! $transaction->ID()) {
934
+            if ( ! $transaction->ID()) {
935 935
                 $transaction->save();
936 936
             }
937 937
             $this->_session_data['transaction'] = $transaction->ID();
@@ -945,14 +945,14 @@  discard block
 block discarded – undo
945 945
         // maybe save hash check
946 946
         if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
947 947
             $this->cache_storage->add(
948
-                EE_Session::hash_check_prefix . $this->_sid,
948
+                EE_Session::hash_check_prefix.$this->_sid,
949 949
                 md5($session_data),
950 950
                 $this->session_lifespan->inSeconds()
951 951
             );
952 952
         }
953 953
         // we're using the Transient API for storing session data,
954 954
         return $this->cache_storage->add(
955
-            EE_Session::session_id_prefix . $this->_sid,
955
+            EE_Session::session_id_prefix.$this->_sid,
956 956
             $session_data,
957 957
             $this->session_lifespan->inSeconds()
958 958
         );
@@ -966,7 +966,7 @@  discard block
 block discarded – undo
966 966
      */
967 967
     public function _get_page_visit()
968 968
     {
969
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
969
+        $page_visit = home_url('/').'wp-admin/admin-ajax.php';
970 970
         // check for request url
971 971
         if (isset($_SERVER['REQUEST_URI'])) {
972 972
             $http_host = '';
@@ -982,14 +982,14 @@  discard block
 block discarded – undo
982 982
             // check for page_id in SERVER REQUEST
983 983
             if (isset($_REQUEST['page_id'])) {
984 984
                 // rebuild $e_reg without any of the extra parameters
985
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
985
+                $page_id = '?page_id='.esc_attr($_REQUEST['page_id']).'&amp;';
986 986
             }
987 987
             // check for $e_reg in SERVER REQUEST
988 988
             if (isset($_REQUEST['ee'])) {
989 989
                 // rebuild $e_reg without any of the extra parameters
990
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
990
+                $e_reg = 'ee='.esc_attr($_REQUEST['ee']);
991 991
             }
992
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
992
+            $page_visit = rtrim($http_host.$request_uri.$page_id.$e_reg, '?');
993 993
         }
994 994
         return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
995 995
     }
@@ -1027,7 +1027,7 @@  discard block
 block discarded – undo
1027 1027
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1028 1028
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1029 1029
 // </h3>';
1030
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1030
+        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()');
1031 1031
         $this->reset_cart();
1032 1032
         $this->reset_checkout();
1033 1033
         $this->reset_transaction();
@@ -1049,7 +1049,7 @@  discard block
 block discarded – undo
1049 1049
     public function reset_data($data_to_reset = array(), $show_all_notices = false)
1050 1050
     {
1051 1051
         // if $data_to_reset is not in an array, then put it in one
1052
-        if (! is_array($data_to_reset)) {
1052
+        if ( ! is_array($data_to_reset)) {
1053 1053
             $data_to_reset = array($data_to_reset);
1054 1054
         }
1055 1055
         // nothing ??? go home!
@@ -1069,11 +1069,11 @@  discard block
 block discarded – undo
1069 1069
         // since $data_to_reset is an array, cycle through the values
1070 1070
         foreach ($data_to_reset as $reset) {
1071 1071
             // first check to make sure it is a valid session var
1072
-            if (isset($this->_session_data[ $reset ])) {
1072
+            if (isset($this->_session_data[$reset])) {
1073 1073
                 // then check to make sure it is not a default var
1074
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1074
+                if ( ! array_key_exists($reset, $this->_default_session_vars)) {
1075 1075
                     // remove session var
1076
-                    unset($this->_session_data[ $reset ]);
1076
+                    unset($this->_session_data[$reset]);
1077 1077
                     if ($show_all_notices) {
1078 1078
                         EE_Error::add_success(
1079 1079
                             sprintf(
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
             // or use that for the new transient cleanup query limit
1175 1175
             add_filter(
1176 1176
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1177
-                function () use ($expired_session_transient_delete_query_limit) {
1177
+                function() use ($expired_session_transient_delete_query_limit) {
1178 1178
                     return $expired_session_transient_delete_query_limit;
1179 1179
                 }
1180 1180
             );
@@ -1192,7 +1192,7 @@  discard block
 block discarded – undo
1192 1192
         $error = '<pre>';
1193 1193
         $data2 = preg_replace_callback(
1194 1194
             '!s:(\d+):"(.*?)";!',
1195
-            function ($match) {
1195
+            function($match) {
1196 1196
                 return ($match[1] === strlen($match[2]))
1197 1197
                     ? $match[0]
1198 1198
                     : 's:'
@@ -1204,13 +1204,13 @@  discard block
 block discarded – undo
1204 1204
             $data1
1205 1205
         );
1206 1206
         $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1207
-        $error .= $data1 . PHP_EOL;
1208
-        $error .= $data2 . PHP_EOL;
1207
+        $error .= $data1.PHP_EOL;
1208
+        $error .= $data2.PHP_EOL;
1209 1209
         for ($i = 0; $i < $max; $i++) {
1210
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1211
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1212
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1213
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1210
+            if (@$data1[$i] !== @$data2[$i]) {
1211
+                $error .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL;
1212
+                $error .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL;
1213
+                $error .= "\t-> Line Number = $i".PHP_EOL;
1214 1214
                 $start = ($i - 20);
1215 1215
                 $start = ($start < 0) ? 0 : $start;
1216 1216
                 $length = 40;
@@ -1225,7 +1225,7 @@  discard block
 block discarded – undo
1225 1225
                 $error .= "\t-> Section Data1  = ";
1226 1226
                 $error .= substr_replace(
1227 1227
                     substr($data1, $start, $length),
1228
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1228
+                    "<b style=\"color:green\">{$data1[$i]}</b>",
1229 1229
                     $rpoint,
1230 1230
                     $rlength
1231 1231
                 );
@@ -1233,7 +1233,7 @@  discard block
 block discarded – undo
1233 1233
                 $error .= "\t-> Section Data2  = ";
1234 1234
                 $error .= substr_replace(
1235 1235
                     substr($data2, $start, $length),
1236
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1236
+                    "<b style=\"color:red\">{$data2[$i]}</b>",
1237 1237
                     $rpoint,
1238 1238
                     $rlength
1239 1239
                 );
@@ -1264,7 +1264,7 @@  discard block
 block discarded – undo
1264 1264
     public function garbageCollection()
1265 1265
     {
1266 1266
         // only perform during regular requests if last garbage collection was over an hour ago
1267
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1267
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1268 1268
             $this->_last_gc = time();
1269 1269
             $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1270 1270
             /** @type WPDB $wpdb */
@@ -1299,7 +1299,7 @@  discard block
 block discarded – undo
1299 1299
                 // AND option_value < 1508368198 LIMIT 50
1300 1300
                 $expired_sessions = $wpdb->get_col($SQL);
1301 1301
                 // valid results?
1302
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1302
+                if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1303 1303
                     $this->cache_storage->deleteMany($expired_sessions, true);
1304 1304
                 }
1305 1305
             }
Please login to merge, or discard this patch.
core/services/session/SessionStartHandler.php 1 patch
Indentation   +216 added lines, -216 removed lines patch added patch discarded remove patch
@@ -27,234 +27,234 @@
 block discarded – undo
27 27
  */
28 28
 class SessionStartHandler
29 29
 {
30
-    const OPTION_NAME_SESSION_SAVE_HANDLER_STATUS = 'ee_session_save_handler_status';
31
-    const REQUEST_PARAM_RETRY_SESSION = 'ee_retry_session';
32
-    const SESSION_SAVE_HANDLER_STATUS_FAILED = 'session_save_handler_failed';
33
-    const SESSION_SAVE_HANDLER_STATUS_SUCCESS = 'session_save_handler_success';
34
-    const SESSION_SAVE_HANDLER_STATUS_UNKNOWN = 'session_save_handler_untested';
30
+	const OPTION_NAME_SESSION_SAVE_HANDLER_STATUS = 'ee_session_save_handler_status';
31
+	const REQUEST_PARAM_RETRY_SESSION = 'ee_retry_session';
32
+	const SESSION_SAVE_HANDLER_STATUS_FAILED = 'session_save_handler_failed';
33
+	const SESSION_SAVE_HANDLER_STATUS_SUCCESS = 'session_save_handler_success';
34
+	const SESSION_SAVE_HANDLER_STATUS_UNKNOWN = 'session_save_handler_untested';
35 35
 
36
-    /**
37
-     * @var RequestInterface $request
38
-     */
39
-    protected $request;
36
+	/**
37
+	 * @var RequestInterface $request
38
+	 */
39
+	protected $request;
40 40
 
41
-    /**
42
-     * StartSession constructor.
43
-     *
44
-     * @param RequestInterface $request
45
-     */
46
-    public function __construct(RequestInterface $request)
47
-    {
48
-        $this->request = $request;
49
-    }
41
+	/**
42
+	 * StartSession constructor.
43
+	 *
44
+	 * @param RequestInterface $request
45
+	 */
46
+	public function __construct(RequestInterface $request)
47
+	{
48
+		$this->request = $request;
49
+	}
50 50
 
51
-    /**
52
-     * Check if a custom session save handler is in play
53
-     * and attempt to start the PHP session
54
-     *
55
-     * @since 4.9.68.p
56
-     */
57
-    public function startSession()
58
-    {
59
-        // check that session has started
60
-        if (session_id() === '') {
61
-            // starts a new session if one doesn't already exist, or re-initiates an existing one
62
-            if ($this->hasKnownCustomSessionSaveHandler()) {
63
-                $this->checkCustomSessionSaveHandler();
64
-            } else {
65
-                session_start();
66
-            }
67
-        }
68
-    }
51
+	/**
52
+	 * Check if a custom session save handler is in play
53
+	 * and attempt to start the PHP session
54
+	 *
55
+	 * @since 4.9.68.p
56
+	 */
57
+	public function startSession()
58
+	{
59
+		// check that session has started
60
+		if (session_id() === '') {
61
+			// starts a new session if one doesn't already exist, or re-initiates an existing one
62
+			if ($this->hasKnownCustomSessionSaveHandler()) {
63
+				$this->checkCustomSessionSaveHandler();
64
+			} else {
65
+				session_start();
66
+			}
67
+		}
68
+	}
69 69
 
70
-    /**
71
-     * Returns `true` if the 'session.save_handler' ini setting matches a known custom handler
72
-     *
73
-     * @since 4.9.68.p
74
-     * @return bool
75
-     */
76
-    private function hasKnownCustomSessionSaveHandler()
77
-    {
78
-        return in_array(
79
-            ini_get('session.save_handler'),
80
-            array(
81
-                'user',
82
-            ),
83
-            true
84
-        );
85
-    }
70
+	/**
71
+	 * Returns `true` if the 'session.save_handler' ini setting matches a known custom handler
72
+	 *
73
+	 * @since 4.9.68.p
74
+	 * @return bool
75
+	 */
76
+	private function hasKnownCustomSessionSaveHandler()
77
+	{
78
+		return in_array(
79
+			ini_get('session.save_handler'),
80
+			array(
81
+				'user',
82
+			),
83
+			true
84
+		);
85
+	}
86 86
 
87
-    /**
88
-     * Attempt to start the PHP session when a custom Session Save Handler is known to be set.
89
-     *
90
-     * @since 4.9.68.p
91
-     */
92
-    private function checkCustomSessionSaveHandler()
93
-    {
94
-        // If we've already successfully tested the session save handler
95
-        // on a previous request then just start the session
96
-        if ($this->sessionSaveHandlerIsValid()) {
97
-            session_start();
98
-            return;
99
-        }
100
-        // If not, then attempt to deal with any errors,
101
-        // otherwise, try to hobble along without the session
102
-        if (! $this->handleSessionSaveHandlerErrors()) {
103
-            return;
104
-        }
105
-        // there is no record of a fatal error while trying to start the session
106
-        // so let's see if there's a custom session save handler. Proceed with caution
107
-        $this->initializeSessionSaveHandlerStatus();
108
-        // hold your breath, the custom session save handler might cause a fatal here...
109
-        session_start();
110
-        // phew! we made it! the custom session handler is a-ok
111
-        $this->setSessionSaveHandlerStatusToValid();
112
-    }
87
+	/**
88
+	 * Attempt to start the PHP session when a custom Session Save Handler is known to be set.
89
+	 *
90
+	 * @since 4.9.68.p
91
+	 */
92
+	private function checkCustomSessionSaveHandler()
93
+	{
94
+		// If we've already successfully tested the session save handler
95
+		// on a previous request then just start the session
96
+		if ($this->sessionSaveHandlerIsValid()) {
97
+			session_start();
98
+			return;
99
+		}
100
+		// If not, then attempt to deal with any errors,
101
+		// otherwise, try to hobble along without the session
102
+		if (! $this->handleSessionSaveHandlerErrors()) {
103
+			return;
104
+		}
105
+		// there is no record of a fatal error while trying to start the session
106
+		// so let's see if there's a custom session save handler. Proceed with caution
107
+		$this->initializeSessionSaveHandlerStatus();
108
+		// hold your breath, the custom session save handler might cause a fatal here...
109
+		session_start();
110
+		// phew! we made it! the custom session handler is a-ok
111
+		$this->setSessionSaveHandlerStatusToValid();
112
+	}
113 113
 
114 114
 
115
-    /**
116
-     * retrieves the value for the 'ee_session_save_handler_status' WP option.
117
-     * default value = 'session_save_handler_untested'
118
-     *
119
-     * @since 4.9.68.p
120
-     * @return string
121
-     */
122
-    private function getSessionSaveHandlerStatus()
123
-    {
124
-        return get_option(
125
-            SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
126
-            SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_UNKNOWN
127
-        );
128
-    }
115
+	/**
116
+	 * retrieves the value for the 'ee_session_save_handler_status' WP option.
117
+	 * default value = 'session_save_handler_untested'
118
+	 *
119
+	 * @since 4.9.68.p
120
+	 * @return string
121
+	 */
122
+	private function getSessionSaveHandlerStatus()
123
+	{
124
+		return get_option(
125
+			SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
126
+			SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_UNKNOWN
127
+		);
128
+	}
129 129
 
130
-    /**
131
-     * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_failed'
132
-     * which can then be upgraded is everything works correctly
133
-     *
134
-     * @since 4.9.68.p
135
-     * @return bool
136
-     */
137
-    private function initializeSessionSaveHandlerStatus()
138
-    {
139
-        return update_option(
140
-            SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
141
-            SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_FAILED
142
-        );
143
-    }
130
+	/**
131
+	 * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_failed'
132
+	 * which can then be upgraded is everything works correctly
133
+	 *
134
+	 * @since 4.9.68.p
135
+	 * @return bool
136
+	 */
137
+	private function initializeSessionSaveHandlerStatus()
138
+	{
139
+		return update_option(
140
+			SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
141
+			SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_FAILED
142
+		);
143
+	}
144 144
 
145
-    /**
146
-     * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_success'
147
-     *
148
-     * @since 4.9.68.p
149
-     * @return bool
150
-     */
151
-    private function setSessionSaveHandlerStatusToValid()
152
-    {
153
-        return update_option(
154
-            SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
155
-            SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_SUCCESS
156
-        );
157
-    }
145
+	/**
146
+	 * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_success'
147
+	 *
148
+	 * @since 4.9.68.p
149
+	 * @return bool
150
+	 */
151
+	private function setSessionSaveHandlerStatusToValid()
152
+	{
153
+		return update_option(
154
+			SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
155
+			SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_SUCCESS
156
+		);
157
+	}
158 158
 
159
-    /**
160
-     * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_untested'
161
-     *
162
-     * @since 4.9.68.p
163
-     * @return bool
164
-     */
165
-    private function resetSessionSaveHandlerStatus()
166
-    {
167
-        return update_option(
168
-            SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
169
-            SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_UNKNOWN
170
-        );
171
-    }
159
+	/**
160
+	 * Sets the 'ee_session_save_handler_status' WP option value to 'session_save_handler_untested'
161
+	 *
162
+	 * @since 4.9.68.p
163
+	 * @return bool
164
+	 */
165
+	private function resetSessionSaveHandlerStatus()
166
+	{
167
+		return update_option(
168
+			SessionStartHandler::OPTION_NAME_SESSION_SAVE_HANDLER_STATUS,
169
+			SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_UNKNOWN
170
+		);
171
+	}
172 172
 
173
-    /**
174
-     * Returns `true` if the 'ee_session_save_handler_status' WP option value
175
-     * is equal to 'session_save_handler_success'
176
-     *
177
-     * @since 4.9.68.p
178
-     * @return bool
179
-     */
180
-    private function sessionSaveHandlerIsValid()
181
-    {
182
-        return $this->getSessionSaveHandlerStatus() === SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_SUCCESS;
183
-    }
173
+	/**
174
+	 * Returns `true` if the 'ee_session_save_handler_status' WP option value
175
+	 * is equal to 'session_save_handler_success'
176
+	 *
177
+	 * @since 4.9.68.p
178
+	 * @return bool
179
+	 */
180
+	private function sessionSaveHandlerIsValid()
181
+	{
182
+		return $this->getSessionSaveHandlerStatus() === SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_SUCCESS;
183
+	}
184 184
 
185
-    /**
186
-     * Returns `true` if the 'ee_session_save_handler_status' WP option value
187
-     * is equal to 'session_save_handler_failed'
188
-     *
189
-     * @since 4.9.68.p
190
-     * @return bool
191
-     */
192
-    private function sessionSaveHandlerFailed()
193
-    {
194
-        return $this->getSessionSaveHandlerStatus() === SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_FAILED;
195
-    }
185
+	/**
186
+	 * Returns `true` if the 'ee_session_save_handler_status' WP option value
187
+	 * is equal to 'session_save_handler_failed'
188
+	 *
189
+	 * @since 4.9.68.p
190
+	 * @return bool
191
+	 */
192
+	private function sessionSaveHandlerFailed()
193
+	{
194
+		return $this->getSessionSaveHandlerStatus() === SessionStartHandler::SESSION_SAVE_HANDLER_STATUS_FAILED;
195
+	}
196 196
 
197
-    /**
198
-     * Returns `true` if no errors were detected with the session save handler,
199
-     * otherwise attempts to work notify the appropriate authorities
200
-     * with a suggestion for how to fix the issue, and returns `false`.
201
-     *
202
-     *
203
-     * @since 4.9.68.p
204
-     * @return bool
205
-     */
206
-    private function handleSessionSaveHandlerErrors()
207
-    {
208
-        // Check if we had a fatal error last time while trying to start the session
209
-        if ($this->sessionSaveHandlerFailed()) {
210
-            // apparently, last time we tried using the custom session save handler there was a fatal
211
-            if ($this->request->requestParamIsSet(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION)) {
212
-                $this->resetSessionSaveHandlerStatus();
213
-                // remove "ee_retry_session", otherwise if the problem still isn't fixed,
214
-                // we'll just keep getting the fatal error over and over.
215
-                // Better to remove it and redirect, and try on the next request
216
-                EEH_URL::safeRedirectAndExit(
217
-                    remove_query_arg(
218
-                        array(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION),
219
-                        EEH_URL::current_url()
220
-                    )
221
-                );
222
-            }
223
-            // so the session is broken, don't try it again,
224
-            // just show a message to users that can fix it
225
-            $this->displaySessionSaveHandlerErrorNotice();
226
-            return false;
227
-        }
228
-        return true;
229
-    }
197
+	/**
198
+	 * Returns `true` if no errors were detected with the session save handler,
199
+	 * otherwise attempts to work notify the appropriate authorities
200
+	 * with a suggestion for how to fix the issue, and returns `false`.
201
+	 *
202
+	 *
203
+	 * @since 4.9.68.p
204
+	 * @return bool
205
+	 */
206
+	private function handleSessionSaveHandlerErrors()
207
+	{
208
+		// Check if we had a fatal error last time while trying to start the session
209
+		if ($this->sessionSaveHandlerFailed()) {
210
+			// apparently, last time we tried using the custom session save handler there was a fatal
211
+			if ($this->request->requestParamIsSet(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION)) {
212
+				$this->resetSessionSaveHandlerStatus();
213
+				// remove "ee_retry_session", otherwise if the problem still isn't fixed,
214
+				// we'll just keep getting the fatal error over and over.
215
+				// Better to remove it and redirect, and try on the next request
216
+				EEH_URL::safeRedirectAndExit(
217
+					remove_query_arg(
218
+						array(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION),
219
+						EEH_URL::current_url()
220
+					)
221
+				);
222
+			}
223
+			// so the session is broken, don't try it again,
224
+			// just show a message to users that can fix it
225
+			$this->displaySessionSaveHandlerErrorNotice();
226
+			return false;
227
+		}
228
+		return true;
229
+	}
230 230
 
231
-    /**
232
-     * Generates an EE_Error notice regarding the current session woes
233
-     * but only if the current user is an admin with permission to 'install_plugins'.
234
-     *
235
-     * @since 4.9.68.p
236
-     */
237
-    private function displaySessionSaveHandlerErrorNotice()
238
-    {
239
-        if (current_user_can('install_plugins')) {
240
-            $retry_session_url = add_query_arg(
241
-                array(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION => true),
242
-                EEH_URL::current_url()
243
-            );
244
-            EE_Error::add_error(
245
-                sprintf(
246
-                    esc_html__(
247
-                        'It appears there was a fatal error while starting the session, so Event Espresso is not able to process registrations normally. Some hosting companies, like Pantheon, require an extra plugin for Event Espresso to work. Please install the %1$sWordPress Native PHP Sessions plugin%2$s, then %3$sclick here to check if the problem is resolved.%2$s',
248
-                        'event_espresso'
249
-                    ),
250
-                    '<a href="https://wordpress.org/plugins/wp-native-php-sessions/">',
251
-                    '</a>',
252
-                    '<a href="' . $retry_session_url . '">'
253
-                ),
254
-                __FILE__,
255
-                __FUNCTION__,
256
-                __LINE__
257
-            );
258
-        }
259
-    }
231
+	/**
232
+	 * Generates an EE_Error notice regarding the current session woes
233
+	 * but only if the current user is an admin with permission to 'install_plugins'.
234
+	 *
235
+	 * @since 4.9.68.p
236
+	 */
237
+	private function displaySessionSaveHandlerErrorNotice()
238
+	{
239
+		if (current_user_can('install_plugins')) {
240
+			$retry_session_url = add_query_arg(
241
+				array(SessionStartHandler::REQUEST_PARAM_RETRY_SESSION => true),
242
+				EEH_URL::current_url()
243
+			);
244
+			EE_Error::add_error(
245
+				sprintf(
246
+					esc_html__(
247
+						'It appears there was a fatal error while starting the session, so Event Espresso is not able to process registrations normally. Some hosting companies, like Pantheon, require an extra plugin for Event Espresso to work. Please install the %1$sWordPress Native PHP Sessions plugin%2$s, then %3$sclick here to check if the problem is resolved.%2$s',
248
+						'event_espresso'
249
+					),
250
+					'<a href="https://wordpress.org/plugins/wp-native-php-sessions/">',
251
+					'</a>',
252
+					'<a href="' . $retry_session_url . '">'
253
+				),
254
+				__FILE__,
255
+				__FUNCTION__,
256
+				__LINE__
257
+			);
258
+		}
259
+	}
260 260
 }
Please login to merge, or discard this patch.
core/services/validators/URLValidator.php 1 patch
Indentation   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -16,16 +16,16 @@
 block discarded – undo
16 16
  */
17 17
 class URLValidator
18 18
 {
19
-    /**
20
-     * Returns whether or not the URL is valid
21
-     * @since 4.9.68.p
22
-     * @param $url
23
-     * @return boolean
24
-     */
25
-    public function isValid($url)
26
-    {
27
-        return  esc_url_raw($url) === $url;
28
-    }
19
+	/**
20
+	 * Returns whether or not the URL is valid
21
+	 * @since 4.9.68.p
22
+	 * @param $url
23
+	 * @return boolean
24
+	 */
25
+	public function isValid($url)
26
+	{
27
+		return  esc_url_raw($url) === $url;
28
+	}
29 29
 }
30 30
 // End of file URLValidator.php
31 31
 // Location: ${NAMESPACE}/URLValidator.php
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Registration.php 1 patch
Indentation   +100 added lines, -100 removed lines patch added patch discarded remove patch
@@ -24,108 +24,108 @@
 block discarded – undo
24 24
  */
25 25
 class Registration extends RegistrationCalculationBase
26 26
 {
27
-    /**
28
-     * @var EEM_Registration
29
-     */
30
-    protected $registration_model;
27
+	/**
28
+	 * @var EEM_Registration
29
+	 */
30
+	protected $registration_model;
31 31
 
32
-    /**
33
-     * Registration constructor.
34
-     * @param EEM_Registration $registration_model
35
-     */
36
-    public function __construct(EEM_Registration $registration_model)
37
-    {
38
-        $this->registration_model = $registration_model;
39
-    }
32
+	/**
33
+	 * Registration constructor.
34
+	 * @param EEM_Registration $registration_model
35
+	 */
36
+	public function __construct(EEM_Registration $registration_model)
37
+	{
38
+		$this->registration_model = $registration_model;
39
+	}
40 40
 
41
-    /**
42
-     * Calculates the checkin status for each datetime this registration has access to
43
-     *
44
-     * @param array            $wpdb_row
45
-     * @param WP_REST_Request $request
46
-     * @param RegistrationControllerBase $controller
47
-     * @return array
48
-     * @throws EE_Error
49
-     * @throws InvalidDataTypeException
50
-     * @throws InvalidInterfaceException
51
-     * @throws InvalidArgumentException
52
-     */
53
-    public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
-    {
55
-        if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
-            $reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
-        } else {
58
-            $reg = null;
59
-        }
60
-        if (! $reg instanceof EE_Registration
61
-        ) {
62
-            throw new EE_Error(
63
-                sprintf(
64
-                    __(
65
-                    // @codingStandardsIgnoreStart
66
-                        'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
67
-                        // @codingStandardsIgnoreEnd
68
-                        'event_espresso'
69
-                    ),
70
-                    $wpdb_row['Registration.REG_ID'],
71
-                    print_r($wpdb_row, true)
72
-                )
73
-            );
74
-        }
75
-        $datetime_ids = EEM_Datetime::instance()->get_col(
76
-            [
77
-                [
78
-                    'Ticket.TKT_ID' => $reg->ticket_ID(),
79
-                ],
80
-                'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
81
-            ]
82
-        );
83
-        $checkin_stati = array();
84
-        foreach ($datetime_ids as $datetime_id) {
85
-            $status = $reg->check_in_status_for_datetime($datetime_id);
86
-            switch ($status) {
87
-                case EE_Checkin::status_checked_out:
88
-                    $status_pretty = 'OUT';
89
-                    break;
90
-                case EE_Checkin::status_checked_in:
91
-                    $status_pretty = 'IN';
92
-                    break;
93
-                case EE_Checkin::status_checked_never:
94
-                default:
95
-                    $status_pretty = 'NEVER';
96
-                    break;
97
-            }
98
-            $checkin_stati[ $datetime_id ] = $status_pretty;
99
-        }
100
-        return $checkin_stati;
101
-    }
41
+	/**
42
+	 * Calculates the checkin status for each datetime this registration has access to
43
+	 *
44
+	 * @param array            $wpdb_row
45
+	 * @param WP_REST_Request $request
46
+	 * @param RegistrationControllerBase $controller
47
+	 * @return array
48
+	 * @throws EE_Error
49
+	 * @throws InvalidDataTypeException
50
+	 * @throws InvalidInterfaceException
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
+	{
55
+		if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
+			$reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
+		} else {
58
+			$reg = null;
59
+		}
60
+		if (! $reg instanceof EE_Registration
61
+		) {
62
+			throw new EE_Error(
63
+				sprintf(
64
+					__(
65
+					// @codingStandardsIgnoreStart
66
+						'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
67
+						// @codingStandardsIgnoreEnd
68
+						'event_espresso'
69
+					),
70
+					$wpdb_row['Registration.REG_ID'],
71
+					print_r($wpdb_row, true)
72
+				)
73
+			);
74
+		}
75
+		$datetime_ids = EEM_Datetime::instance()->get_col(
76
+			[
77
+				[
78
+					'Ticket.TKT_ID' => $reg->ticket_ID(),
79
+				],
80
+				'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
81
+			]
82
+		);
83
+		$checkin_stati = array();
84
+		foreach ($datetime_ids as $datetime_id) {
85
+			$status = $reg->check_in_status_for_datetime($datetime_id);
86
+			switch ($status) {
87
+				case EE_Checkin::status_checked_out:
88
+					$status_pretty = 'OUT';
89
+					break;
90
+				case EE_Checkin::status_checked_in:
91
+					$status_pretty = 'IN';
92
+					break;
93
+				case EE_Checkin::status_checked_never:
94
+				default:
95
+					$status_pretty = 'NEVER';
96
+					break;
97
+			}
98
+			$checkin_stati[ $datetime_id ] = $status_pretty;
99
+		}
100
+		return $checkin_stati;
101
+	}
102 102
 
103 103
 
104
-    /**
105
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
106
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
107
-     *
108
-     * @since 4.9.68.p
109
-     * @return array
110
-     */
111
-    public function schemaForCalculations()
112
-    {
113
-        return array(
114
-            'datetime_checkin_stati' => array(
115
-                'description' => esc_html__(
116
-                    'Returns the checkin status for each datetime this registration has access to.',
117
-                    'event_espresso'
118
-                ),
119
-                'type' => 'object',
120
-                'properties' => array(),
121
-                'additionalProperties' => array(
122
-                    'description' => esc_html(
123
-                        'Keys are date-time ids and values are the check-in status',
124
-                        'event_espresso'
125
-                    ),
126
-                    'type' => 'string'
127
-                ),
128
-            ),
129
-        );
130
-    }
104
+	/**
105
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
106
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
107
+	 *
108
+	 * @since 4.9.68.p
109
+	 * @return array
110
+	 */
111
+	public function schemaForCalculations()
112
+	{
113
+		return array(
114
+			'datetime_checkin_stati' => array(
115
+				'description' => esc_html__(
116
+					'Returns the checkin status for each datetime this registration has access to.',
117
+					'event_espresso'
118
+				),
119
+				'type' => 'object',
120
+				'properties' => array(),
121
+				'additionalProperties' => array(
122
+					'description' => esc_html(
123
+						'Keys are date-time ids and values are the check-in status',
124
+						'event_espresso'
125
+					),
126
+					'type' => 'string'
127
+				),
128
+			),
129
+		);
130
+	}
131 131
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Base.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -16,65 +16,65 @@
 block discarded – undo
16 16
 class Base
17 17
 {
18 18
 
19
-    /**
20
-     * @param $required_permission
21
-     * @param $attempted_calculation
22
-     * @throws RestException
23
-     */
24
-    protected function verifyCurrentUserCan($required_permission, $attempted_calculation)
25
-    {
26
-        if (! current_user_can($required_permission)) {
27
-            throw new RestException(
28
-                'permission_denied',
29
-                sprintf(
30
-                    __(
31
-                    // @codingStandardsIgnoreStart
32
-                        'Permission denied, you cannot calculate %1$s on %2$s because you do not have the capability "%3$s"',
33
-                        // @codingStandardsIgnoreEnd
34
-                        'event_espresso'
35
-                    ),
36
-                    $attempted_calculation,
37
-                    EEH_Inflector::pluralize_and_lower($this->getResourceName()),
38
-                    $required_permission
39
-                )
40
-            );
41
-        }
42
-    }
19
+	/**
20
+	 * @param $required_permission
21
+	 * @param $attempted_calculation
22
+	 * @throws RestException
23
+	 */
24
+	protected function verifyCurrentUserCan($required_permission, $attempted_calculation)
25
+	{
26
+		if (! current_user_can($required_permission)) {
27
+			throw new RestException(
28
+				'permission_denied',
29
+				sprintf(
30
+					__(
31
+					// @codingStandardsIgnoreStart
32
+						'Permission denied, you cannot calculate %1$s on %2$s because you do not have the capability "%3$s"',
33
+						// @codingStandardsIgnoreEnd
34
+						'event_espresso'
35
+					),
36
+					$attempted_calculation,
37
+					EEH_Inflector::pluralize_and_lower($this->getResourceName()),
38
+					$required_permission
39
+				)
40
+			);
41
+		}
42
+	}
43 43
 
44 44
 
45
-    /**
46
-     * Gets the name of the resource of the called class
47
-     *
48
-     * @return string
49
-     */
50
-    public function getResourceName()
51
-    {
52
-        return substr(__CLASS__, strrpos(__CLASS__, '\\') + 1);
53
-    }
45
+	/**
46
+	 * Gets the name of the resource of the called class
47
+	 *
48
+	 * @return string
49
+	 */
50
+	public function getResourceName()
51
+	{
52
+		return substr(__CLASS__, strrpos(__CLASS__, '\\') + 1);
53
+	}
54 54
 
55
-    /**
56
-     * Returns an array to be used for the schema for the calculated fields.
57
-     * @since 4.9.68.p
58
-     * @return array keys are calculated field names (eg "optimum_sales_at_start") values are arrays {
59
-     * @type string $description
60
-     * @type string $type, eg "string", "int", "boolean", "object", "array", etc
61
-     * }
62
-     */
63
-    public function schemaForCalculations()
64
-    {
65
-        return array();
66
-    }
55
+	/**
56
+	 * Returns an array to be used for the schema for the calculated fields.
57
+	 * @since 4.9.68.p
58
+	 * @return array keys are calculated field names (eg "optimum_sales_at_start") values are arrays {
59
+	 * @type string $description
60
+	 * @type string $type, eg "string", "int", "boolean", "object", "array", etc
61
+	 * }
62
+	 */
63
+	public function schemaForCalculations()
64
+	{
65
+		return array();
66
+	}
67 67
 
68
-    /**
69
-     * Returns the json schema for the given calculation index.
70
-     *
71
-     * @since 4.9.68.p
72
-     * @param $calculation_index
73
-     * @return array
74
-     */
75
-    public function schemaForCalculation($calculation_index)
76
-    {
77
-        $schema_map = $this->schemaForCalculations();
78
-        return isset($schema_map[ $calculation_index ]) ? $schema_map[ $calculation_index ] : array();
79
-    }
68
+	/**
69
+	 * Returns the json schema for the given calculation index.
70
+	 *
71
+	 * @since 4.9.68.p
72
+	 * @param $calculation_index
73
+	 * @return array
74
+	 */
75
+	public function schemaForCalculation($calculation_index)
76
+	{
77
+		$schema_map = $this->schemaForCalculations();
78
+		return isset($schema_map[ $calculation_index ]) ? $schema_map[ $calculation_index ] : array();
79
+	}
80 80
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Event.php 1 patch
Indentation   +560 added lines, -560 removed lines patch added patch discarded remove patch
@@ -26,564 +26,564 @@
 block discarded – undo
26 26
  */
27 27
 class Event extends EventCalculationBase
28 28
 {
29
-    /**
30
-     * @var EEM_Event
31
-     */
32
-    protected $event_model;
33
-
34
-    /**
35
-     * @var EEM_Registration
36
-     */
37
-    protected $registration_model;
38
-    public function __construct(EEM_Event $event_model, EEM_Registration $registration_model)
39
-    {
40
-        $this->event_model = $event_model;
41
-        $this->registration_model = $registration_model;
42
-    }
43
-
44
-    /**
45
-     * Calculates the total spaces on the event (not subtracting sales, but taking
46
-     * sales into account; so this is the optimum sales that CAN still be achieved)
47
-     * See EE_Event::total_available_spaces( true );
48
-     *
49
-     * @param array               $wpdb_row
50
-     * @param WP_REST_Request     $request
51
-     * @param EventControllerBase $controller
52
-     * @return int
53
-     * @throws EE_Error
54
-     * @throws DomainException
55
-     * @throws InvalidDataTypeException
56
-     * @throws InvalidInterfaceException
57
-     * @throws UnexpectedEntityException
58
-     * @throws InvalidArgumentException
59
-     */
60
-    public function optimumSalesAtStart($wpdb_row, $request, $controller)
61
-    {
62
-        $event_obj = null;
63
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
64
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
65
-        }
66
-        if ($event_obj instanceof EE_Event) {
67
-            return $event_obj->total_available_spaces();
68
-        }
69
-        throw new EE_Error(
70
-            sprintf(
71
-                __(
72
-                // @codingStandardsIgnoreStart
73
-                    'Cannot calculate optimum_sales_at_start because the event with ID %1$s (from database row %2$s) was not found',
74
-                    // @codingStandardsIgnoreEnd
75
-                    'event_espresso'
76
-                ),
77
-                $wpdb_row['Event_CPT.ID'],
78
-                print_r($wpdb_row, true)
79
-            )
80
-        );
81
-    }
82
-
83
-
84
-    /**
85
-     * Calculates the total spaces on the event (ignoring all sales; so this is the optimum
86
-     * sales that COULD have been achieved)
87
-     * See EE_Event::total_available_spaces( true );
88
-     *
89
-     * @param array               $wpdb_row
90
-     * @param WP_REST_Request     $request
91
-     * @param EventControllerBase $controller
92
-     * @return int
93
-     * @throws DomainException
94
-     * @throws EE_Error
95
-     * @throws InvalidArgumentException
96
-     * @throws InvalidDataTypeException
97
-     * @throws InvalidInterfaceException
98
-     * @throws UnexpectedEntityException
99
-     */
100
-    public function optimumSalesNow($wpdb_row, $request, $controller)
101
-    {
102
-        $event_obj = null;
103
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
104
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
105
-        }
106
-        if ($event_obj instanceof EE_Event) {
107
-            return $event_obj->total_available_spaces(true);
108
-        }
109
-        throw new EE_Error(
110
-            sprintf(
111
-                __(
112
-                // @codingStandardsIgnoreStart
113
-                    'Cannot calculate optimum_sales_now because the event with ID %1$s (from database row %2$s) was not found',
114
-                    // @codingStandardsIgnoreEnd
115
-                    'event_espresso'
116
-                ),
117
-                $wpdb_row['Event_CPT.ID'],
118
-                print_r($wpdb_row, true)
119
-            )
120
-        );
121
-    }
122
-
123
-
124
-    /**
125
-     * Like optimum_sales_now, but minus total sales so far.
126
-     * See EE_Event::spaces_remaining_for_sale( true );
127
-     *
128
-     * @param array               $wpdb_row
129
-     * @param WP_REST_Request     $request
130
-     * @param EventControllerBase $controller
131
-     * @return int
132
-     * @throws DomainException
133
-     * @throws EE_Error
134
-     * @throws InvalidArgumentException
135
-     * @throws InvalidDataTypeException
136
-     * @throws InvalidInterfaceException
137
-     * @throws UnexpectedEntityException
138
-     */
139
-    public function spacesRemaining($wpdb_row, $request, $controller)
140
-    {
141
-        $event_obj = null;
142
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
143
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
144
-        }
145
-        if ($event_obj instanceof EE_Event) {
146
-            return $event_obj->spaces_remaining_for_sale();
147
-        }
148
-        throw new EE_Error(
149
-            sprintf(
150
-                __(
151
-                // @codingStandardsIgnoreStart
152
-                    'Cannot calculate spaces_remaining because the event with ID %1$s (from database row %2$s) was not found',
153
-                    // @codingStandardsIgnoreEnd
154
-                    'event_espresso'
155
-                ),
156
-                $wpdb_row['Event_CPT.ID'],
157
-                print_r($wpdb_row, true)
158
-            )
159
-        );
160
-    }
161
-
162
-
163
-    /**
164
-     * Counts the number of approved registrations for this event (regardless
165
-     * of how many datetimes each registrations' ticket purchase is for)
166
-     *
167
-     * @param array               $wpdb_row
168
-     * @param WP_REST_Request     $request
169
-     * @param EventControllerBase $controller
170
-     * @return int
171
-     * @throws EE_Error
172
-     * @throws InvalidArgumentException
173
-     * @throws InvalidDataTypeException
174
-     * @throws InvalidInterfaceException
175
-     */
176
-    public function spotsTaken($wpdb_row, $request, $controller)
177
-    {
178
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
179
-            throw new EE_Error(
180
-                sprintf(
181
-                    __(
182
-                    // @codingStandardsIgnoreStart
183
-                        'Cannot calculate spots_taken because the database row %1$s does not have a valid entry for "Event_CPT.ID"',
184
-                        // @codingStandardsIgnoreEnd
185
-                        'event_espresso'
186
-                    ),
187
-                    print_r($wpdb_row, true)
188
-                )
189
-            );
190
-        }
191
-        return $this->registration_model->count(
192
-            array(
193
-                array(
194
-                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
195
-                    'STS_ID' => EEM_Registration::status_id_approved,
196
-                ),
197
-            ),
198
-            'REG_ID',
199
-            true
200
-        );
201
-    }
202
-
203
-
204
-    /**
205
-     * Counts the number of pending-payment registrations for this event (regardless
206
-     * of how many datetimes each registrations' ticket purchase is for)
207
-     *
208
-     * @param array               $wpdb_row
209
-     * @param WP_REST_Request     $request
210
-     * @param EventControllerBase $controller
211
-     * @return int
212
-     * @throws EE_Error
213
-     * @throws InvalidArgumentException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidInterfaceException
216
-     * @throws RestException
217
-     */
218
-    public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219
-    {
220
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
221
-            throw new EE_Error(
222
-                sprintf(
223
-                    __(
224
-                    // @codingStandardsIgnoreStart
225
-                        'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Event_CPT.ID"',
226
-                        // @codingStandardsIgnoreEnd
227
-                        'event_espresso'
228
-                    ),
229
-                    print_r($wpdb_row, true)
230
-                )
231
-            );
232
-        }
233
-        $this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
234
-        return $this->registration_model->count(
235
-            array(
236
-                array(
237
-                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
238
-                    'STS_ID' => EEM_Registration::status_id_pending_payment,
239
-                ),
240
-            ),
241
-            'REG_ID',
242
-            true
243
-        );
244
-    }
245
-
246
-
247
-    /**
248
-     * Counts all the registrations who have checked into one of this events' datetimes
249
-     * See EE_Event::total_available_spaces( false );
250
-     *
251
-     * @param array               $wpdb_row
252
-     * @param WP_REST_Request     $request
253
-     * @param EventControllerBase $controller
254
-     * @return int|null if permission denied
255
-     * @throws EE_Error
256
-     * @throws InvalidArgumentException
257
-     * @throws InvalidDataTypeException
258
-     * @throws InvalidInterfaceException
259
-     * @throws RestException
260
-     */
261
-    public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262
-    {
263
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
264
-            throw new EE_Error(
265
-                sprintf(
266
-                    __(
267
-                    // @codingStandardsIgnoreStart
268
-                        'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
269
-                        // @codingStandardsIgnoreEnd
270
-                        'event_espresso'
271
-                    ),
272
-                    print_r($wpdb_row, true)
273
-                )
274
-            );
275
-        }
276
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
277
-        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], true);
278
-    }
279
-
280
-
281
-    /**
282
-     * Counts all the registrations who have checked out of one of this events' datetimes
283
-     * See EE_Event::total_available_spaces( false );
284
-     *
285
-     * @param array               $wpdb_row
286
-     * @param WP_REST_Request     $request
287
-     * @param EventControllerBase $controller
288
-     * @return int
289
-     * @throws EE_Error
290
-     * @throws InvalidArgumentException
291
-     * @throws InvalidDataTypeException
292
-     * @throws InvalidInterfaceException
293
-     * @throws RestException
294
-     */
295
-    public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296
-    {
297
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
298
-            throw new EE_Error(
299
-                sprintf(
300
-                    __(
301
-                    // @codingStandardsIgnoreStart
302
-                        'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
303
-                        // @codingStandardsIgnoreEnd
304
-                        'event_espresso'
305
-                    ),
306
-                    print_r($wpdb_row, true)
307
-                )
308
-            );
309
-        }
310
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
311
-        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], false);
312
-    }
313
-
314
-
315
-    /**
316
-     * Gets the thumbnail image
317
-     *
318
-     * @param array               $wpdb_row
319
-     * @param WP_REST_Request     $request
320
-     * @param EventControllerBase $controller
321
-     * @return array
322
-     * @throws EE_Error
323
-     */
324
-    public function imageThumbnail($wpdb_row, $request, $controller)
325
-    {
326
-        return self::calculateImageData($wpdb_row, 'thumbnail');
327
-    }
328
-
329
-
330
-    /**
331
-     * Gets the medium image
332
-     *
333
-     * @param array               $wpdb_row
334
-     * @param WP_REST_Request     $request
335
-     * @param EventControllerBase $controller
336
-     * @return array
337
-     * @throws EE_Error
338
-     */
339
-    public function imageMedium($wpdb_row, $request, $controller)
340
-    {
341
-        return self::calculateImageData($wpdb_row, 'medium');
342
-    }
343
-
344
-
345
-    /**
346
-     * Gets the medium-large image
347
-     *
348
-     * @param array               $wpdb_row
349
-     * @param WP_REST_Request     $request
350
-     * @param EventControllerBase $controller
351
-     * @return array
352
-     * @throws EE_Error
353
-     */
354
-    public function imageMediumLarge($wpdb_row, $request, $controller)
355
-    {
356
-        return self::calculateImageData($wpdb_row, 'medium_large');
357
-    }
358
-
359
-
360
-    /**
361
-     * Gets the large image
362
-     *
363
-     * @param array               $wpdb_row
364
-     * @param WP_REST_Request     $request
365
-     * @param EventControllerBase $controller
366
-     * @return array
367
-     * @throws EE_Error
368
-     */
369
-    public function imageLarge($wpdb_row, $request, $controller)
370
-    {
371
-        return self::calculateImageData($wpdb_row, 'large');
372
-    }
373
-
374
-
375
-    /**
376
-     * Gets the post-thumbnail image
377
-     *
378
-     * @param array               $wpdb_row
379
-     * @param WP_REST_Request     $request
380
-     * @param EventControllerBase $controller
381
-     * @return array
382
-     * @throws EE_Error
383
-     */
384
-    public function imagePostThumbnail($wpdb_row, $request, $controller)
385
-    {
386
-        return self::calculateImageData($wpdb_row, 'post-thumbnail');
387
-    }
388
-
389
-
390
-    /**
391
-     * Gets the full size image
392
-     *
393
-     * @param array               $wpdb_row
394
-     * @param WP_REST_Request     $request
395
-     * @param EventControllerBase $controller
396
-     * @return array
397
-     * @throws EE_Error
398
-     */
399
-    public function imageFull($wpdb_row, $request, $controller)
400
-    {
401
-        return self::calculateImageData($wpdb_row, 'full');
402
-    }
403
-
404
-
405
-    /**
406
-     * Gets image specs and formats them for the display in the API,
407
-     * according to the image size requested
408
-     *
409
-     * @param array  $wpdb_row
410
-     * @param string $image_size one of these: thumbnail, medium, medium_large, large, post-thumbnail, full
411
-     * @return array|false if no such image exists. If array it will have keys 'url', 'width', 'height' and 'original'
412
-     * @throws EE_Error
413
-     */
414
-    protected function calculateImageData($wpdb_row, $image_size)
415
-    {
416
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
417
-            throw new EE_Error(
418
-                sprintf(
419
-                    __(
420
-                    // @codingStandardsIgnoreStart
421
-                        'Cannot calculate image because the database row %1$s does not have an entry for "Event_CPT.ID"',
422
-                        // @codingStandardsIgnoreEnd
423
-                        'event_espresso'
424
-                    ),
425
-                    print_r($wpdb_row, true)
426
-                )
427
-            );
428
-        }
429
-        $EVT_ID = $wpdb_row['Event_CPT.ID'];
430
-        $attachment_id = get_post_thumbnail_id($EVT_ID);
431
-        $data = wp_get_attachment_image_src($attachment_id, $image_size);
432
-        if (! $data) {
433
-            return null;
434
-        }
435
-        $generated = true;
436
-        if (isset($data[3])) {
437
-            $generated = $data[3];
438
-        }
439
-        return array(
440
-            'url'       => $data[0],
441
-            'width'     => $data[1],
442
-            'height'    => $data[2],
443
-            'generated' => $generated,
444
-        );
445
-    }
446
-
447
-
448
-    /**
449
-     * Returns true if the array of data contains 'Event_CPT.ID'. False otherwise
450
-     *
451
-     * @param array $wpdb_row
452
-     * @return bool
453
-     */
454
-    protected function wpdbRowHasEventId($wpdb_row)
455
-    {
456
-        return (is_array($wpdb_row) && isset($wpdb_row['Event_CPT.ID']) && absint($wpdb_row['Event_CPT.ID']));
457
-    }
458
-
459
-
460
-    /**
461
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
462
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
463
-     *
464
-     * @since 4.9.68.p
465
-     * @return array
466
-     */
467
-    public function schemaForCalculations()
468
-    {
469
-        $image_object_properties = array(
470
-            'url'       => array(
471
-                'type' => 'string',
472
-            ),
473
-            'width'     => array(
474
-                'type' => 'number',
475
-            ),
476
-            'height'    => array(
477
-                'type' => 'number',
478
-            ),
479
-            'generated' => array(
480
-                'type' => 'boolean',
481
-            ),
482
-        );
483
-        return array(
484
-            'optimum_sales_at_start'          => array(
485
-                'description' => esc_html__(
486
-                    'The total spaces on the event (not subtracting sales, but taking sales into account; so this is the optimum sales that CAN still be achieved.',
487
-                    'event_espresso'
488
-                ),
489
-                'type'        => 'number',
490
-            ),
491
-            'optimum_sales_now'               => array(
492
-                'description' => esc_html__(
493
-                    'The total spaces on the event (ignoring all sales; so this is the optimum sales that could have been achieved.',
494
-                    'event_espresso'
495
-                ),
496
-                'type'        => 'number',
497
-            ),
498
-            'spaces_remaining'                => array(
499
-                'description' => esc_html__(
500
-                    'The optimum_sales_number result, minus total sales so far.',
501
-                    'event_espresso'
502
-                ),
503
-                'type'        => 'number',
504
-            ),
505
-            'spots_taken'                     => array(
506
-                'description' => esc_html__(
507
-                    'The number of approved registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
508
-                    'event_espresso'
509
-                ),
510
-                'type'        => 'number',
511
-            ),
512
-            'spots_taken_pending_payment'     => array(
513
-                'description' => esc_html__(
514
-                    'The number of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
515
-                    'event_espresso'
516
-                ),
517
-                'type'        => 'number',
518
-            ),
519
-            'registrations_checked_in_count'  => array(
520
-                'description' => esc_html__(
521
-                    'The count of all the registrations who have checked into one of this event\'s datetimes.',
522
-                    'event_espresso'
523
-                ),
524
-                'type'        => 'number',
525
-            ),
526
-            'registrations_checked_out_count' => array(
527
-                'description' => esc_html__(
528
-                    'The count of all registrations who have checked out of one of this event\'s datetimes.',
529
-                    'event_espresso'
530
-                ),
531
-                'type'        => 'number',
532
-            ),
533
-            'image_thumbnail'                 => array(
534
-                'description'          => esc_html__(
535
-                    'The thumbnail image data.',
536
-                    'event_espresso'
537
-                ),
538
-                'type'                 => 'object',
539
-                'properties'           => $image_object_properties,
540
-                'additionalProperties' => false,
541
-            ),
542
-            'image_medium'                    => array(
543
-                'description'          => esc_html__(
544
-                    'The medium image data.',
545
-                    'event_espresso'
546
-                ),
547
-                'type'                 => 'object',
548
-                'properties'           => $image_object_properties,
549
-                'additionalProperties' => false,
550
-            ),
551
-            'image_medium_large'              => array(
552
-                'description'          => esc_html__(
553
-                    'The medium-large image data.',
554
-                    'event_espresso'
555
-                ),
556
-                'type'                 => 'object',
557
-                'properties'           => $image_object_properties,
558
-                'additionalProperties' => false,
559
-            ),
560
-            'image_large'                     => array(
561
-                'description'          => esc_html__(
562
-                    'The large image data.',
563
-                    'event_espresso'
564
-                ),
565
-                'type'                 => 'object',
566
-                'properties'           => $image_object_properties,
567
-                'additionalProperties' => false,
568
-            ),
569
-            'image_post_thumbnail'            => array(
570
-                'description'          => esc_html__(
571
-                    'The post-thumbnail image data.',
572
-                    'event_espresso'
573
-                ),
574
-                'type'                 => 'object',
575
-                'properties'           => $image_object_properties,
576
-                'additionalProperties' => false,
577
-            ),
578
-            'image_full'                      => array(
579
-                'description'          => esc_html__(
580
-                    'The full size image data',
581
-                    'event_espresso'
582
-                ),
583
-                'type'                 => 'object',
584
-                'properties'           => $image_object_properties,
585
-                'additionalProperties' => false,
586
-            ),
587
-        );
588
-    }
29
+	/**
30
+	 * @var EEM_Event
31
+	 */
32
+	protected $event_model;
33
+
34
+	/**
35
+	 * @var EEM_Registration
36
+	 */
37
+	protected $registration_model;
38
+	public function __construct(EEM_Event $event_model, EEM_Registration $registration_model)
39
+	{
40
+		$this->event_model = $event_model;
41
+		$this->registration_model = $registration_model;
42
+	}
43
+
44
+	/**
45
+	 * Calculates the total spaces on the event (not subtracting sales, but taking
46
+	 * sales into account; so this is the optimum sales that CAN still be achieved)
47
+	 * See EE_Event::total_available_spaces( true );
48
+	 *
49
+	 * @param array               $wpdb_row
50
+	 * @param WP_REST_Request     $request
51
+	 * @param EventControllerBase $controller
52
+	 * @return int
53
+	 * @throws EE_Error
54
+	 * @throws DomainException
55
+	 * @throws InvalidDataTypeException
56
+	 * @throws InvalidInterfaceException
57
+	 * @throws UnexpectedEntityException
58
+	 * @throws InvalidArgumentException
59
+	 */
60
+	public function optimumSalesAtStart($wpdb_row, $request, $controller)
61
+	{
62
+		$event_obj = null;
63
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
64
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
65
+		}
66
+		if ($event_obj instanceof EE_Event) {
67
+			return $event_obj->total_available_spaces();
68
+		}
69
+		throw new EE_Error(
70
+			sprintf(
71
+				__(
72
+				// @codingStandardsIgnoreStart
73
+					'Cannot calculate optimum_sales_at_start because the event with ID %1$s (from database row %2$s) was not found',
74
+					// @codingStandardsIgnoreEnd
75
+					'event_espresso'
76
+				),
77
+				$wpdb_row['Event_CPT.ID'],
78
+				print_r($wpdb_row, true)
79
+			)
80
+		);
81
+	}
82
+
83
+
84
+	/**
85
+	 * Calculates the total spaces on the event (ignoring all sales; so this is the optimum
86
+	 * sales that COULD have been achieved)
87
+	 * See EE_Event::total_available_spaces( true );
88
+	 *
89
+	 * @param array               $wpdb_row
90
+	 * @param WP_REST_Request     $request
91
+	 * @param EventControllerBase $controller
92
+	 * @return int
93
+	 * @throws DomainException
94
+	 * @throws EE_Error
95
+	 * @throws InvalidArgumentException
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws InvalidInterfaceException
98
+	 * @throws UnexpectedEntityException
99
+	 */
100
+	public function optimumSalesNow($wpdb_row, $request, $controller)
101
+	{
102
+		$event_obj = null;
103
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
104
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
105
+		}
106
+		if ($event_obj instanceof EE_Event) {
107
+			return $event_obj->total_available_spaces(true);
108
+		}
109
+		throw new EE_Error(
110
+			sprintf(
111
+				__(
112
+				// @codingStandardsIgnoreStart
113
+					'Cannot calculate optimum_sales_now because the event with ID %1$s (from database row %2$s) was not found',
114
+					// @codingStandardsIgnoreEnd
115
+					'event_espresso'
116
+				),
117
+				$wpdb_row['Event_CPT.ID'],
118
+				print_r($wpdb_row, true)
119
+			)
120
+		);
121
+	}
122
+
123
+
124
+	/**
125
+	 * Like optimum_sales_now, but minus total sales so far.
126
+	 * See EE_Event::spaces_remaining_for_sale( true );
127
+	 *
128
+	 * @param array               $wpdb_row
129
+	 * @param WP_REST_Request     $request
130
+	 * @param EventControllerBase $controller
131
+	 * @return int
132
+	 * @throws DomainException
133
+	 * @throws EE_Error
134
+	 * @throws InvalidArgumentException
135
+	 * @throws InvalidDataTypeException
136
+	 * @throws InvalidInterfaceException
137
+	 * @throws UnexpectedEntityException
138
+	 */
139
+	public function spacesRemaining($wpdb_row, $request, $controller)
140
+	{
141
+		$event_obj = null;
142
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
143
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
144
+		}
145
+		if ($event_obj instanceof EE_Event) {
146
+			return $event_obj->spaces_remaining_for_sale();
147
+		}
148
+		throw new EE_Error(
149
+			sprintf(
150
+				__(
151
+				// @codingStandardsIgnoreStart
152
+					'Cannot calculate spaces_remaining because the event with ID %1$s (from database row %2$s) was not found',
153
+					// @codingStandardsIgnoreEnd
154
+					'event_espresso'
155
+				),
156
+				$wpdb_row['Event_CPT.ID'],
157
+				print_r($wpdb_row, true)
158
+			)
159
+		);
160
+	}
161
+
162
+
163
+	/**
164
+	 * Counts the number of approved registrations for this event (regardless
165
+	 * of how many datetimes each registrations' ticket purchase is for)
166
+	 *
167
+	 * @param array               $wpdb_row
168
+	 * @param WP_REST_Request     $request
169
+	 * @param EventControllerBase $controller
170
+	 * @return int
171
+	 * @throws EE_Error
172
+	 * @throws InvalidArgumentException
173
+	 * @throws InvalidDataTypeException
174
+	 * @throws InvalidInterfaceException
175
+	 */
176
+	public function spotsTaken($wpdb_row, $request, $controller)
177
+	{
178
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
179
+			throw new EE_Error(
180
+				sprintf(
181
+					__(
182
+					// @codingStandardsIgnoreStart
183
+						'Cannot calculate spots_taken because the database row %1$s does not have a valid entry for "Event_CPT.ID"',
184
+						// @codingStandardsIgnoreEnd
185
+						'event_espresso'
186
+					),
187
+					print_r($wpdb_row, true)
188
+				)
189
+			);
190
+		}
191
+		return $this->registration_model->count(
192
+			array(
193
+				array(
194
+					'EVT_ID' => $wpdb_row['Event_CPT.ID'],
195
+					'STS_ID' => EEM_Registration::status_id_approved,
196
+				),
197
+			),
198
+			'REG_ID',
199
+			true
200
+		);
201
+	}
202
+
203
+
204
+	/**
205
+	 * Counts the number of pending-payment registrations for this event (regardless
206
+	 * of how many datetimes each registrations' ticket purchase is for)
207
+	 *
208
+	 * @param array               $wpdb_row
209
+	 * @param WP_REST_Request     $request
210
+	 * @param EventControllerBase $controller
211
+	 * @return int
212
+	 * @throws EE_Error
213
+	 * @throws InvalidArgumentException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidInterfaceException
216
+	 * @throws RestException
217
+	 */
218
+	public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219
+	{
220
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
221
+			throw new EE_Error(
222
+				sprintf(
223
+					__(
224
+					// @codingStandardsIgnoreStart
225
+						'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Event_CPT.ID"',
226
+						// @codingStandardsIgnoreEnd
227
+						'event_espresso'
228
+					),
229
+					print_r($wpdb_row, true)
230
+				)
231
+			);
232
+		}
233
+		$this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
234
+		return $this->registration_model->count(
235
+			array(
236
+				array(
237
+					'EVT_ID' => $wpdb_row['Event_CPT.ID'],
238
+					'STS_ID' => EEM_Registration::status_id_pending_payment,
239
+				),
240
+			),
241
+			'REG_ID',
242
+			true
243
+		);
244
+	}
245
+
246
+
247
+	/**
248
+	 * Counts all the registrations who have checked into one of this events' datetimes
249
+	 * See EE_Event::total_available_spaces( false );
250
+	 *
251
+	 * @param array               $wpdb_row
252
+	 * @param WP_REST_Request     $request
253
+	 * @param EventControllerBase $controller
254
+	 * @return int|null if permission denied
255
+	 * @throws EE_Error
256
+	 * @throws InvalidArgumentException
257
+	 * @throws InvalidDataTypeException
258
+	 * @throws InvalidInterfaceException
259
+	 * @throws RestException
260
+	 */
261
+	public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262
+	{
263
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
264
+			throw new EE_Error(
265
+				sprintf(
266
+					__(
267
+					// @codingStandardsIgnoreStart
268
+						'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
269
+						// @codingStandardsIgnoreEnd
270
+						'event_espresso'
271
+					),
272
+					print_r($wpdb_row, true)
273
+				)
274
+			);
275
+		}
276
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
277
+		return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], true);
278
+	}
279
+
280
+
281
+	/**
282
+	 * Counts all the registrations who have checked out of one of this events' datetimes
283
+	 * See EE_Event::total_available_spaces( false );
284
+	 *
285
+	 * @param array               $wpdb_row
286
+	 * @param WP_REST_Request     $request
287
+	 * @param EventControllerBase $controller
288
+	 * @return int
289
+	 * @throws EE_Error
290
+	 * @throws InvalidArgumentException
291
+	 * @throws InvalidDataTypeException
292
+	 * @throws InvalidInterfaceException
293
+	 * @throws RestException
294
+	 */
295
+	public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296
+	{
297
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
298
+			throw new EE_Error(
299
+				sprintf(
300
+					__(
301
+					// @codingStandardsIgnoreStart
302
+						'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
303
+						// @codingStandardsIgnoreEnd
304
+						'event_espresso'
305
+					),
306
+					print_r($wpdb_row, true)
307
+				)
308
+			);
309
+		}
310
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
311
+		return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], false);
312
+	}
313
+
314
+
315
+	/**
316
+	 * Gets the thumbnail image
317
+	 *
318
+	 * @param array               $wpdb_row
319
+	 * @param WP_REST_Request     $request
320
+	 * @param EventControllerBase $controller
321
+	 * @return array
322
+	 * @throws EE_Error
323
+	 */
324
+	public function imageThumbnail($wpdb_row, $request, $controller)
325
+	{
326
+		return self::calculateImageData($wpdb_row, 'thumbnail');
327
+	}
328
+
329
+
330
+	/**
331
+	 * Gets the medium image
332
+	 *
333
+	 * @param array               $wpdb_row
334
+	 * @param WP_REST_Request     $request
335
+	 * @param EventControllerBase $controller
336
+	 * @return array
337
+	 * @throws EE_Error
338
+	 */
339
+	public function imageMedium($wpdb_row, $request, $controller)
340
+	{
341
+		return self::calculateImageData($wpdb_row, 'medium');
342
+	}
343
+
344
+
345
+	/**
346
+	 * Gets the medium-large image
347
+	 *
348
+	 * @param array               $wpdb_row
349
+	 * @param WP_REST_Request     $request
350
+	 * @param EventControllerBase $controller
351
+	 * @return array
352
+	 * @throws EE_Error
353
+	 */
354
+	public function imageMediumLarge($wpdb_row, $request, $controller)
355
+	{
356
+		return self::calculateImageData($wpdb_row, 'medium_large');
357
+	}
358
+
359
+
360
+	/**
361
+	 * Gets the large image
362
+	 *
363
+	 * @param array               $wpdb_row
364
+	 * @param WP_REST_Request     $request
365
+	 * @param EventControllerBase $controller
366
+	 * @return array
367
+	 * @throws EE_Error
368
+	 */
369
+	public function imageLarge($wpdb_row, $request, $controller)
370
+	{
371
+		return self::calculateImageData($wpdb_row, 'large');
372
+	}
373
+
374
+
375
+	/**
376
+	 * Gets the post-thumbnail image
377
+	 *
378
+	 * @param array               $wpdb_row
379
+	 * @param WP_REST_Request     $request
380
+	 * @param EventControllerBase $controller
381
+	 * @return array
382
+	 * @throws EE_Error
383
+	 */
384
+	public function imagePostThumbnail($wpdb_row, $request, $controller)
385
+	{
386
+		return self::calculateImageData($wpdb_row, 'post-thumbnail');
387
+	}
388
+
389
+
390
+	/**
391
+	 * Gets the full size image
392
+	 *
393
+	 * @param array               $wpdb_row
394
+	 * @param WP_REST_Request     $request
395
+	 * @param EventControllerBase $controller
396
+	 * @return array
397
+	 * @throws EE_Error
398
+	 */
399
+	public function imageFull($wpdb_row, $request, $controller)
400
+	{
401
+		return self::calculateImageData($wpdb_row, 'full');
402
+	}
403
+
404
+
405
+	/**
406
+	 * Gets image specs and formats them for the display in the API,
407
+	 * according to the image size requested
408
+	 *
409
+	 * @param array  $wpdb_row
410
+	 * @param string $image_size one of these: thumbnail, medium, medium_large, large, post-thumbnail, full
411
+	 * @return array|false if no such image exists. If array it will have keys 'url', 'width', 'height' and 'original'
412
+	 * @throws EE_Error
413
+	 */
414
+	protected function calculateImageData($wpdb_row, $image_size)
415
+	{
416
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
417
+			throw new EE_Error(
418
+				sprintf(
419
+					__(
420
+					// @codingStandardsIgnoreStart
421
+						'Cannot calculate image because the database row %1$s does not have an entry for "Event_CPT.ID"',
422
+						// @codingStandardsIgnoreEnd
423
+						'event_espresso'
424
+					),
425
+					print_r($wpdb_row, true)
426
+				)
427
+			);
428
+		}
429
+		$EVT_ID = $wpdb_row['Event_CPT.ID'];
430
+		$attachment_id = get_post_thumbnail_id($EVT_ID);
431
+		$data = wp_get_attachment_image_src($attachment_id, $image_size);
432
+		if (! $data) {
433
+			return null;
434
+		}
435
+		$generated = true;
436
+		if (isset($data[3])) {
437
+			$generated = $data[3];
438
+		}
439
+		return array(
440
+			'url'       => $data[0],
441
+			'width'     => $data[1],
442
+			'height'    => $data[2],
443
+			'generated' => $generated,
444
+		);
445
+	}
446
+
447
+
448
+	/**
449
+	 * Returns true if the array of data contains 'Event_CPT.ID'. False otherwise
450
+	 *
451
+	 * @param array $wpdb_row
452
+	 * @return bool
453
+	 */
454
+	protected function wpdbRowHasEventId($wpdb_row)
455
+	{
456
+		return (is_array($wpdb_row) && isset($wpdb_row['Event_CPT.ID']) && absint($wpdb_row['Event_CPT.ID']));
457
+	}
458
+
459
+
460
+	/**
461
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
462
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
463
+	 *
464
+	 * @since 4.9.68.p
465
+	 * @return array
466
+	 */
467
+	public function schemaForCalculations()
468
+	{
469
+		$image_object_properties = array(
470
+			'url'       => array(
471
+				'type' => 'string',
472
+			),
473
+			'width'     => array(
474
+				'type' => 'number',
475
+			),
476
+			'height'    => array(
477
+				'type' => 'number',
478
+			),
479
+			'generated' => array(
480
+				'type' => 'boolean',
481
+			),
482
+		);
483
+		return array(
484
+			'optimum_sales_at_start'          => array(
485
+				'description' => esc_html__(
486
+					'The total spaces on the event (not subtracting sales, but taking sales into account; so this is the optimum sales that CAN still be achieved.',
487
+					'event_espresso'
488
+				),
489
+				'type'        => 'number',
490
+			),
491
+			'optimum_sales_now'               => array(
492
+				'description' => esc_html__(
493
+					'The total spaces on the event (ignoring all sales; so this is the optimum sales that could have been achieved.',
494
+					'event_espresso'
495
+				),
496
+				'type'        => 'number',
497
+			),
498
+			'spaces_remaining'                => array(
499
+				'description' => esc_html__(
500
+					'The optimum_sales_number result, minus total sales so far.',
501
+					'event_espresso'
502
+				),
503
+				'type'        => 'number',
504
+			),
505
+			'spots_taken'                     => array(
506
+				'description' => esc_html__(
507
+					'The number of approved registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
508
+					'event_espresso'
509
+				),
510
+				'type'        => 'number',
511
+			),
512
+			'spots_taken_pending_payment'     => array(
513
+				'description' => esc_html__(
514
+					'The number of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
515
+					'event_espresso'
516
+				),
517
+				'type'        => 'number',
518
+			),
519
+			'registrations_checked_in_count'  => array(
520
+				'description' => esc_html__(
521
+					'The count of all the registrations who have checked into one of this event\'s datetimes.',
522
+					'event_espresso'
523
+				),
524
+				'type'        => 'number',
525
+			),
526
+			'registrations_checked_out_count' => array(
527
+				'description' => esc_html__(
528
+					'The count of all registrations who have checked out of one of this event\'s datetimes.',
529
+					'event_espresso'
530
+				),
531
+				'type'        => 'number',
532
+			),
533
+			'image_thumbnail'                 => array(
534
+				'description'          => esc_html__(
535
+					'The thumbnail image data.',
536
+					'event_espresso'
537
+				),
538
+				'type'                 => 'object',
539
+				'properties'           => $image_object_properties,
540
+				'additionalProperties' => false,
541
+			),
542
+			'image_medium'                    => array(
543
+				'description'          => esc_html__(
544
+					'The medium image data.',
545
+					'event_espresso'
546
+				),
547
+				'type'                 => 'object',
548
+				'properties'           => $image_object_properties,
549
+				'additionalProperties' => false,
550
+			),
551
+			'image_medium_large'              => array(
552
+				'description'          => esc_html__(
553
+					'The medium-large image data.',
554
+					'event_espresso'
555
+				),
556
+				'type'                 => 'object',
557
+				'properties'           => $image_object_properties,
558
+				'additionalProperties' => false,
559
+			),
560
+			'image_large'                     => array(
561
+				'description'          => esc_html__(
562
+					'The large image data.',
563
+					'event_espresso'
564
+				),
565
+				'type'                 => 'object',
566
+				'properties'           => $image_object_properties,
567
+				'additionalProperties' => false,
568
+			),
569
+			'image_post_thumbnail'            => array(
570
+				'description'          => esc_html__(
571
+					'The post-thumbnail image data.',
572
+					'event_espresso'
573
+				),
574
+				'type'                 => 'object',
575
+				'properties'           => $image_object_properties,
576
+				'additionalProperties' => false,
577
+			),
578
+			'image_full'                      => array(
579
+				'description'          => esc_html__(
580
+					'The full size image data',
581
+					'event_espresso'
582
+				),
583
+				'type'                 => 'object',
584
+				'properties'           => $image_object_properties,
585
+				'additionalProperties' => false,
586
+			),
587
+		);
588
+	}
589 589
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Datetime.php 1 patch
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -17,210 +17,210 @@
 block discarded – undo
17 17
 
18 18
 class Datetime extends DatetimeCalculationBase
19 19
 {
20
-    /**
21
-     * @var EEM_Datetime
22
-     */
23
-    protected $datetime_model;
20
+	/**
21
+	 * @var EEM_Datetime
22
+	 */
23
+	protected $datetime_model;
24 24
 
25
-    /**
26
-     * @var EEM_Registration
27
-     */
28
-    protected $registration_model;
29
-    public function __construct(EEM_Datetime $datetime_model, EEM_Registration $registration_model)
30
-    {
31
-        $this->datetime_model = $datetime_model;
32
-        $this->registration_model = $registration_model;
33
-    }
25
+	/**
26
+	 * @var EEM_Registration
27
+	 */
28
+	protected $registration_model;
29
+	public function __construct(EEM_Datetime $datetime_model, EEM_Registration $registration_model)
30
+	{
31
+		$this->datetime_model = $datetime_model;
32
+		$this->registration_model = $registration_model;
33
+	}
34 34
 
35
-    /**
36
-     * Calculates the total spaces available on the datetime, taking into account
37
-     * ticket limits too.
38
-     *
39
-     * @see EE_Datetime::spaces_remaining( true )
40
-     * @param array            $wpdb_row
41
-     * @param WP_REST_Request $request
42
-     * @param DatetimeControllerBase  $controller
43
-     * @return int
44
-     * @throws EE_Error
45
-     * @throws InvalidDataTypeException
46
-     * @throws InvalidInterfaceException
47
-     * @throws InvalidArgumentException
48
-     * @throws ReflectionException
49
-     */
50
-    public function spacesRemainingConsideringTickets($wpdb_row, $request, $controller)
51
-    {
52
-        if (is_array($wpdb_row) && isset($wpdb_row['Datetime.DTT_ID'])) {
53
-            $dtt_obj = $this->datetime_model->get_one_by_ID($wpdb_row['Datetime.DTT_ID']);
54
-        } else {
55
-            $dtt_obj = null;
56
-        }
57
-        if ($dtt_obj instanceof EE_Datetime) {
58
-            return $dtt_obj->spaces_remaining(true);
59
-        }
60
-        throw new EE_Error(
61
-            sprintf(
62
-                __(
63
-                // @codingStandardsIgnoreStart
64
-                    'Cannot calculate spaces_remaining_considering_tickets because the datetime with ID %1$s (from database row %2$s) was not found',
65
-                    // @codingStandardsIgnoreEnd
66
-                    'event_espresso'
67
-                ),
68
-                $wpdb_row['Datetime.DTT_ID'],
69
-                print_r($wpdb_row, true)
70
-            )
71
-        );
72
-    }
35
+	/**
36
+	 * Calculates the total spaces available on the datetime, taking into account
37
+	 * ticket limits too.
38
+	 *
39
+	 * @see EE_Datetime::spaces_remaining( true )
40
+	 * @param array            $wpdb_row
41
+	 * @param WP_REST_Request $request
42
+	 * @param DatetimeControllerBase  $controller
43
+	 * @return int
44
+	 * @throws EE_Error
45
+	 * @throws InvalidDataTypeException
46
+	 * @throws InvalidInterfaceException
47
+	 * @throws InvalidArgumentException
48
+	 * @throws ReflectionException
49
+	 */
50
+	public function spacesRemainingConsideringTickets($wpdb_row, $request, $controller)
51
+	{
52
+		if (is_array($wpdb_row) && isset($wpdb_row['Datetime.DTT_ID'])) {
53
+			$dtt_obj = $this->datetime_model->get_one_by_ID($wpdb_row['Datetime.DTT_ID']);
54
+		} else {
55
+			$dtt_obj = null;
56
+		}
57
+		if ($dtt_obj instanceof EE_Datetime) {
58
+			return $dtt_obj->spaces_remaining(true);
59
+		}
60
+		throw new EE_Error(
61
+			sprintf(
62
+				__(
63
+				// @codingStandardsIgnoreStart
64
+					'Cannot calculate spaces_remaining_considering_tickets because the datetime with ID %1$s (from database row %2$s) was not found',
65
+					// @codingStandardsIgnoreEnd
66
+					'event_espresso'
67
+				),
68
+				$wpdb_row['Datetime.DTT_ID'],
69
+				print_r($wpdb_row, true)
70
+			)
71
+		);
72
+	}
73 73
 
74 74
 
75
-    /**
76
-     * Counts registrations who have checked into this datetime
77
-     *
78
-     * @param array           $wpdb_row
79
-     * @param WP_REST_Request $request
80
-     * @param DatetimeControllerBase $controller
81
-     * @return int
82
-     * @throws EE_Error
83
-     * @throws InvalidArgumentException
84
-     * @throws InvalidDataTypeException
85
-     * @throws InvalidInterfaceException
86
-     * @throws RestException
87
-     */
88
-    public function registrationsCheckedInCount($wpdb_row, $request, $controller)
89
-    {
90
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
91
-            throw new EE_Error(
92
-                sprintf(
93
-                    __(
94
-                    // @codingStandardsIgnoreStart
95
-                        'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
96
-                        // @codingStandardsIgnoreEnd
97
-                        'event_espresso'
98
-                    ),
99
-                    print_r($wpdb_row, true)
100
-                )
101
-            );
102
-        }
103
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
104
-        return $this->registration_model
105
-                               ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], true);
106
-    }
75
+	/**
76
+	 * Counts registrations who have checked into this datetime
77
+	 *
78
+	 * @param array           $wpdb_row
79
+	 * @param WP_REST_Request $request
80
+	 * @param DatetimeControllerBase $controller
81
+	 * @return int
82
+	 * @throws EE_Error
83
+	 * @throws InvalidArgumentException
84
+	 * @throws InvalidDataTypeException
85
+	 * @throws InvalidInterfaceException
86
+	 * @throws RestException
87
+	 */
88
+	public function registrationsCheckedInCount($wpdb_row, $request, $controller)
89
+	{
90
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
91
+			throw new EE_Error(
92
+				sprintf(
93
+					__(
94
+					// @codingStandardsIgnoreStart
95
+						'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
96
+						// @codingStandardsIgnoreEnd
97
+						'event_espresso'
98
+					),
99
+					print_r($wpdb_row, true)
100
+				)
101
+			);
102
+		}
103
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
104
+		return $this->registration_model
105
+							   ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], true);
106
+	}
107 107
 
108 108
 
109
-    /**
110
-     * Counts registrations who have checked out of this datetime
111
-     *
112
-     * @param array           $wpdb_row
113
-     * @param WP_REST_Request $request
114
-     * @param DatetimeControllerBase $controller
115
-     * @return int
116
-     * @throws EE_Error
117
-     * @throws InvalidArgumentException
118
-     * @throws InvalidDataTypeException
119
-     * @throws InvalidInterfaceException
120
-     * @throws RestException
121
-     */
122
-    public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
123
-    {
124
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
125
-            throw new EE_Error(
126
-                sprintf(
127
-                    __(
128
-                    // @codingStandardsIgnoreStart
129
-                        'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
130
-                        // @codingStandardsIgnoreEnd
131
-                        'event_espresso'
132
-                    ),
133
-                    print_r($wpdb_row, true)
134
-                )
135
-            );
136
-        }
137
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
138
-        return $this->registration_model
139
-                               ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], false);
140
-    }
109
+	/**
110
+	 * Counts registrations who have checked out of this datetime
111
+	 *
112
+	 * @param array           $wpdb_row
113
+	 * @param WP_REST_Request $request
114
+	 * @param DatetimeControllerBase $controller
115
+	 * @return int
116
+	 * @throws EE_Error
117
+	 * @throws InvalidArgumentException
118
+	 * @throws InvalidDataTypeException
119
+	 * @throws InvalidInterfaceException
120
+	 * @throws RestException
121
+	 */
122
+	public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
123
+	{
124
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
125
+			throw new EE_Error(
126
+				sprintf(
127
+					__(
128
+					// @codingStandardsIgnoreStart
129
+						'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
130
+						// @codingStandardsIgnoreEnd
131
+						'event_espresso'
132
+					),
133
+					print_r($wpdb_row, true)
134
+				)
135
+			);
136
+		}
137
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
138
+		return $this->registration_model
139
+							   ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], false);
140
+	}
141 141
 
142 142
 
143
-    /**
144
-     * Counts the number of pending-payment registrations for this event (regardless
145
-     * of how many datetimes each registrations' ticket purchase is for)
146
-     *
147
-     * @param array           $wpdb_row
148
-     * @param WP_REST_Request $request
149
-     * @param DatetimeControllerBase $controller
150
-     * @return int
151
-     * @throws EE_Error
152
-     * @throws InvalidArgumentException
153
-     * @throws InvalidDataTypeException
154
-     * @throws InvalidInterfaceException
155
-     * @throws RestException
156
-     */
157
-    public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
158
-    {
159
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
160
-            throw new EE_Error(
161
-                sprintf(
162
-                    __(
163
-                    // @codingStandardsIgnoreStart
164
-                        'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
165
-                        // @codingStandardsIgnoreEnd
166
-                        'event_espresso'
167
-                    ),
168
-                    print_r($wpdb_row, true)
169
-                )
170
-            );
171
-        }
172
-        $this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
173
-        return $this->registration_model->count(
174
-            array(
175
-                array(
176
-                    'Ticket.Datetime.DTT_ID' => $wpdb_row['Datetime.DTT_ID'],
177
-                    'STS_ID'                 => EEM_Registration::status_id_pending_payment,
178
-                ),
179
-            ),
180
-            'REG_ID',
181
-            true
182
-        );
183
-    }
143
+	/**
144
+	 * Counts the number of pending-payment registrations for this event (regardless
145
+	 * of how many datetimes each registrations' ticket purchase is for)
146
+	 *
147
+	 * @param array           $wpdb_row
148
+	 * @param WP_REST_Request $request
149
+	 * @param DatetimeControllerBase $controller
150
+	 * @return int
151
+	 * @throws EE_Error
152
+	 * @throws InvalidArgumentException
153
+	 * @throws InvalidDataTypeException
154
+	 * @throws InvalidInterfaceException
155
+	 * @throws RestException
156
+	 */
157
+	public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
158
+	{
159
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
160
+			throw new EE_Error(
161
+				sprintf(
162
+					__(
163
+					// @codingStandardsIgnoreStart
164
+						'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
165
+						// @codingStandardsIgnoreEnd
166
+						'event_espresso'
167
+					),
168
+					print_r($wpdb_row, true)
169
+				)
170
+			);
171
+		}
172
+		$this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
173
+		return $this->registration_model->count(
174
+			array(
175
+				array(
176
+					'Ticket.Datetime.DTT_ID' => $wpdb_row['Datetime.DTT_ID'],
177
+					'STS_ID'                 => EEM_Registration::status_id_pending_payment,
178
+				),
179
+			),
180
+			'REG_ID',
181
+			true
182
+		);
183
+	}
184 184
 
185 185
 
186
-    /**
187
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
188
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
189
-     *
190
-     * @since 4.9.68.p
191
-     * @return array
192
-     */
193
-    public function schemaForCalculations()
194
-    {
195
-        return array(
196
-            'spaces_remaining_considering_tickets' => array(
197
-                'description' => esc_html__(
198
-                    'Calculates the total spaces available on the datetime, taking into account ticket limits too.',
199
-                    'event_espresso'
200
-                ),
201
-                'type' => 'number'
202
-            ),
203
-            'registrations_checked_in_count' => array(
204
-                'description' => esc_html__(
205
-                    'Counts registrations who have checked into this datetime.',
206
-                    'event_espresso'
207
-                ),
208
-                'type' => 'number'
209
-            ),
210
-            'registrations_checked_out_count' => array(
211
-                'description' => esc_html__(
212
-                    'Counts registrations who have checked out of this datetime.',
213
-                    'event_espresso'
214
-                ),
215
-                'type' => 'number'
216
-            ),
217
-            'spots_taken_pending_payment' => array(
218
-                'description' => esc_html__(
219
-                    'The count of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for',
220
-                    'event_espresso'
221
-                ),
222
-                'type' => 'number'
223
-            ),
224
-        );
225
-    }
186
+	/**
187
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
188
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
189
+	 *
190
+	 * @since 4.9.68.p
191
+	 * @return array
192
+	 */
193
+	public function schemaForCalculations()
194
+	{
195
+		return array(
196
+			'spaces_remaining_considering_tickets' => array(
197
+				'description' => esc_html__(
198
+					'Calculates the total spaces available on the datetime, taking into account ticket limits too.',
199
+					'event_espresso'
200
+				),
201
+				'type' => 'number'
202
+			),
203
+			'registrations_checked_in_count' => array(
204
+				'description' => esc_html__(
205
+					'Counts registrations who have checked into this datetime.',
206
+					'event_espresso'
207
+				),
208
+				'type' => 'number'
209
+			),
210
+			'registrations_checked_out_count' => array(
211
+				'description' => esc_html__(
212
+					'Counts registrations who have checked out of this datetime.',
213
+					'event_espresso'
214
+				),
215
+				'type' => 'number'
216
+			),
217
+			'spots_taken_pending_payment' => array(
218
+				'description' => esc_html__(
219
+					'The count of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for',
220
+					'event_espresso'
221
+				),
222
+				'type' => 'number'
223
+			),
224
+		);
225
+	}
226 226
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/CalculatedModelFieldsFactory.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -18,46 +18,46 @@
 block discarded – undo
18 18
  */
19 19
 class CalculatedModelFieldsFactory
20 20
 {
21
-    private $loader;
21
+	private $loader;
22 22
 
23
-    /**
24
-     * CalculatedModelFieldsFactory constructor.
25
-     * @param LoaderInterface $loader
26
-     */
27
-    public function __construct(LoaderInterface $loader)
28
-    {
29
-        $this->loader = $loader;
30
-    }
23
+	/**
24
+	 * CalculatedModelFieldsFactory constructor.
25
+	 * @param LoaderInterface $loader
26
+	 */
27
+	public function __construct(LoaderInterface $loader)
28
+	{
29
+		$this->loader = $loader;
30
+	}
31 31
 
32
-    /**
33
-     * Creates the calculator class that corresponds to that particular model
34
-     * @since 4.9.68.p
35
-     * @param string $model_name
36
-     * @return Base
37
-     * @throws UnexpectedEntityException
38
-     */
39
-    public function createFromModel($model_name)
40
-    {
41
-        return $this->createFromClassname('EventEspresso\core\libraries\rest_api\calculations\\' . $model_name);
42
-    }
32
+	/**
33
+	 * Creates the calculator class that corresponds to that particular model
34
+	 * @since 4.9.68.p
35
+	 * @param string $model_name
36
+	 * @return Base
37
+	 * @throws UnexpectedEntityException
38
+	 */
39
+	public function createFromModel($model_name)
40
+	{
41
+		return $this->createFromClassname('EventEspresso\core\libraries\rest_api\calculations\\' . $model_name);
42
+	}
43 43
 
44
-    /**
45
-     * Creates the calculator class that corresponds to that classname and verifies it's of the correct type
46
-     * @param string $calculator_classname
47
-     * @return Base
48
-     * @throws UnexpectedEntityException
49
-     */
50
-    public function createFromClassname($calculator_classname)
51
-    {
52
-        $calculator = $this->loader->getShared($calculator_classname);
53
-        if (!$calculator instanceof Base) {
54
-            throw new UnexpectedEntityException(
55
-                $calculator_classname,
56
-                'EventEspresso\core\libraries\rest_api\calculations\Base'
57
-            );
58
-        }
59
-        return $calculator;
60
-    }
44
+	/**
45
+	 * Creates the calculator class that corresponds to that classname and verifies it's of the correct type
46
+	 * @param string $calculator_classname
47
+	 * @return Base
48
+	 * @throws UnexpectedEntityException
49
+	 */
50
+	public function createFromClassname($calculator_classname)
51
+	{
52
+		$calculator = $this->loader->getShared($calculator_classname);
53
+		if (!$calculator instanceof Base) {
54
+			throw new UnexpectedEntityException(
55
+				$calculator_classname,
56
+				'EventEspresso\core\libraries\rest_api\calculations\Base'
57
+			);
58
+		}
59
+		return $calculator;
60
+	}
61 61
 }
62 62
 // End of file CalculationsFactory.php
63 63
 // Location: EventEspresso\core\libraries\rest_api\calculations/CalculationsFactory.php
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Attendee.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -17,43 +17,43 @@
 block discarded – undo
17 17
 class Attendee extends AttendeeCalculationsBase
18 18
 {
19 19
 
20
-    /**
21
-     * @param array                  $wpdb_row
22
-     * @param WP_REST_Request        $request
23
-     * @param AttendeeControllerBase $controller
24
-     * @since 4.9.66.p
25
-     * @return string
26
-     */
27
-    public function userAvatar(array $wpdb_row, WP_REST_Request $request, AttendeeControllerBase $controller)
28
-    {
29
-        if (is_array($wpdb_row) && isset($wpdb_row['Attendee_Meta.ATT_email'])) {
30
-            $email_address = $wpdb_row['Attendee_Meta.ATT_email'];
31
-        }
32
-        if (empty($email_address)) {
33
-            return '';
34
-        }
35
-        $avatar = get_avatar_url($email_address);
36
-        return $avatar ? $avatar : '';
37
-    }
20
+	/**
21
+	 * @param array                  $wpdb_row
22
+	 * @param WP_REST_Request        $request
23
+	 * @param AttendeeControllerBase $controller
24
+	 * @since 4.9.66.p
25
+	 * @return string
26
+	 */
27
+	public function userAvatar(array $wpdb_row, WP_REST_Request $request, AttendeeControllerBase $controller)
28
+	{
29
+		if (is_array($wpdb_row) && isset($wpdb_row['Attendee_Meta.ATT_email'])) {
30
+			$email_address = $wpdb_row['Attendee_Meta.ATT_email'];
31
+		}
32
+		if (empty($email_address)) {
33
+			return '';
34
+		}
35
+		$avatar = get_avatar_url($email_address);
36
+		return $avatar ? $avatar : '';
37
+	}
38 38
 
39 39
 
40
-    /**
41
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
42
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
43
-     *
44
-     * @since 4.9.68.p
45
-     * @return array
46
-     */
47
-    public function schemaForCalculations()
48
-    {
49
-        return array(
50
-            'user_avatar' => array(
51
-                'description' => esc_html__(
52
-                    'The avatar url for the attendee (if available).',
53
-                    'event_espresso'
54
-                ),
55
-                'type'        => 'string',
56
-            ),
57
-        );
58
-    }
40
+	/**
41
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
42
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
43
+	 *
44
+	 * @since 4.9.68.p
45
+	 * @return array
46
+	 */
47
+	public function schemaForCalculations()
48
+	{
49
+		return array(
50
+			'user_avatar' => array(
51
+				'description' => esc_html__(
52
+					'The avatar url for the attendee (if available).',
53
+					'event_espresso'
54
+				),
55
+				'type'        => 'string',
56
+			),
57
+		);
58
+	}
59 59
 }
Please login to merge, or discard this patch.