Completed
Branch EE5Update (bc64e6)
by
unknown
09:36 queued 05:38
created
core/EE_Session.core.php 2 patches
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -246,22 +246,22 @@  discard block
 block discarded – undo
246 246
         // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
247 247
         // (which currently fires on the init hook at priority 9),
248 248
         // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
249
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
249
+        if ( ! apply_filters('FHEE_load_EE_Session', true)) {
250 250
             return;
251 251
         }
252 252
         $this->session_start_handler = $session_start_handler;
253 253
         $this->session_lifespan = $lifespan;
254 254
         $this->request = $request;
255
-        if (! defined('ESPRESSO_SESSION')) {
255
+        if ( ! defined('ESPRESSO_SESSION')) {
256 256
             define('ESPRESSO_SESSION', true);
257 257
         }
258 258
         // retrieve session options from db
259 259
         $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
260
-        if (! empty($session_settings)) {
260
+        if ( ! empty($session_settings)) {
261 261
             // cycle though existing session options
262 262
             foreach ($session_settings as $var_name => $session_setting) {
263 263
                 // set values for class properties
264
-                $var_name = '_' . $var_name;
264
+                $var_name = '_'.$var_name;
265 265
                 $this->{$var_name} = $session_setting;
266 266
             }
267 267
         }
@@ -322,7 +322,7 @@  discard block
 block discarded – undo
322 322
     public function open_session()
323 323
     {
324 324
         // check for existing session and retrieve it from db
325
-        if (! $this->_espresso_session()) {
325
+        if ( ! $this->_espresso_session()) {
326 326
             // or just start a new one
327 327
             $this->_create_espresso_session();
328 328
         }
@@ -399,7 +399,7 @@  discard block
 block discarded – undo
399 399
             EE_Session::SAVE_STATE_CLEAN,
400 400
             EE_Session::SAVE_STATE_DIRTY,
401 401
         ];
402
-        if (! in_array($save_state, $valid_save_states, true)) {
402
+        if ( ! in_array($save_state, $valid_save_states, true)) {
403 403
             $save_state = EE_Session::SAVE_STATE_DIRTY;
404 404
         }
405 405
         $this->save_state = $save_state;
@@ -417,9 +417,9 @@  discard block
 block discarded – undo
417 417
         // set some defaults
418 418
         foreach ($this->_default_session_vars as $key => $default_var) {
419 419
             if (is_array($default_var)) {
420
-                $this->_session_data[ $key ] = array();
420
+                $this->_session_data[$key] = array();
421 421
             } else {
422
-                $this->_session_data[ $key ] = '';
422
+                $this->_session_data[$key] = '';
423 423
             }
424 424
         }
425 425
     }
@@ -555,8 +555,8 @@  discard block
 block discarded – undo
555 555
             $this->reset_checkout();
556 556
             $this->reset_transaction();
557 557
         }
558
-        if (! empty($key)) {
559
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
558
+        if ( ! empty($key)) {
559
+            return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null;
560 560
         }
561 561
         return $this->_session_data;
562 562
     }
@@ -584,7 +584,7 @@  discard block
 block discarded – undo
584 584
             return false;
585 585
         }
586 586
         foreach ($data as $key => $value) {
587
-            if (isset($this->_default_session_vars[ $key ])) {
587
+            if (isset($this->_default_session_vars[$key])) {
588 588
                 EE_Error::add_error(
589 589
                     sprintf(
590 590
                         esc_html__(
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
                 );
600 600
                 return false;
601 601
             }
602
-            $this->_session_data[ $key ] = $value;
602
+            $this->_session_data[$key] = $value;
603 603
             $this->setSaveState();
604 604
         }
605 605
         return true;
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
         $this->_user_agent = $this->request->userAgent();
631 631
         // now let's retrieve what's in the db
632 632
         $session_data = $this->_retrieve_session_data();
633
-        if (! empty($session_data)) {
633
+        if ( ! empty($session_data)) {
634 634
             // get the current time in UTC
635 635
             $this->_time = $this->_time !== null ? $this->_time : time();
636 636
             // and reset the session expiration
@@ -641,7 +641,7 @@  discard block
 block discarded – undo
641 641
             // set initial site access time and the session expiration
642 642
             $this->_set_init_access_and_expiration();
643 643
             // set referer
644
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr(
644
+            $this->_session_data['pages_visited'][$this->_session_data['init_access']] = esc_attr(
645 645
                 $this->request->getServerParam('HTTP_REFERER')
646 646
             );
647 647
             // no previous session = go back and create one (on top of the data above)
@@ -679,7 +679,7 @@  discard block
 block discarded – undo
679 679
      */
680 680
     protected function _retrieve_session_data()
681 681
     {
682
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
682
+        $ssn_key = EE_Session::session_id_prefix.$this->_sid;
683 683
         try {
684 684
             // we're using WP's Transient API to store session data using the PHP session ID as the option name
685 685
             $session_data = $this->cache_storage->get($ssn_key, false);
@@ -688,7 +688,7 @@  discard block
 block discarded – undo
688 688
             }
689 689
             if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
690 690
                 $hash_check = $this->cache_storage->get(
691
-                    EE_Session::hash_check_prefix . $this->_sid,
691
+                    EE_Session::hash_check_prefix.$this->_sid,
692 692
                     false
693 693
                 );
694 694
                 if ($hash_check && $hash_check !== md5($session_data)) {
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
                                 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
699 699
                                 'event_espresso'
700 700
                             ),
701
-                            EE_Session::session_id_prefix . $this->_sid
701
+                            EE_Session::session_id_prefix.$this->_sid
702 702
                         ),
703 703
                         __FILE__,
704 704
                         __FUNCTION__,
@@ -712,17 +712,17 @@  discard block
 block discarded – undo
712 712
             $row = $wpdb->get_row(
713 713
                 $wpdb->prepare(
714 714
                     "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
715
-                    '_transient_' . $ssn_key
715
+                    '_transient_'.$ssn_key
716 716
                 )
717 717
             );
718 718
             $session_data = is_object($row) ? $row->option_value : null;
719 719
             if ($session_data) {
720 720
                 $session_data = preg_replace_callback(
721 721
                     '!s:(d+):"(.*?)";!',
722
-                    function ($match) {
722
+                    function($match) {
723 723
                         return $match[1] === strlen($match[2])
724 724
                             ? $match[0]
725
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
725
+                            : 's:'.strlen($match[2]).':"'.$match[2].'";';
726 726
                     },
727 727
                     $session_data
728 728
                 );
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
         $session_data = $this->encryption instanceof EE_Encryption
734 734
             ? $this->encryption->base64_string_decode($session_data)
735 735
             : $session_data;
736
-        if (! is_array($session_data)) {
736
+        if ( ! is_array($session_data)) {
737 737
             try {
738 738
                 $session_data = maybe_unserialize($session_data);
739 739
             } catch (Exception $e) {
@@ -747,21 +747,21 @@  discard block
 block discarded – undo
747 747
                       . '</pre><br>'
748 748
                       . $this->find_serialize_error($session_data)
749 749
                     : '';
750
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
750
+                $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
751 751
                 throw new InvalidSessionDataException($msg, 0, $e);
752 752
             }
753 753
         }
754 754
         // just a check to make sure the session array is indeed an array
755
-        if (! is_array($session_data)) {
755
+        if ( ! is_array($session_data)) {
756 756
             // no?!?! then something is wrong
757 757
             $msg = esc_html__(
758 758
                 'The session data is missing, invalid, or corrupted.',
759 759
                 'event_espresso'
760 760
             );
761 761
             $msg .= WP_DEBUG
762
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
762
+                ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data)
763 763
                 : '';
764
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
764
+            $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
765 765
             throw new InvalidSessionDataException($msg);
766 766
         }
767 767
         if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
@@ -787,7 +787,7 @@  discard block
 block discarded – undo
787 787
         // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
788 788
         $session_id = $this->request->requestParamIsSet('EESID')
789 789
             ? $this->request->getRequestParam('EESID')
790
-            : md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
790
+            : md5(session_id().get_current_blog_id().$this->_get_sid_salt());
791 791
         return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
792 792
     }
793 793
 
@@ -889,19 +889,19 @@  discard block
 block discarded – undo
889 889
                     $page_visit = $this->_get_page_visit();
890 890
                     if ($page_visit) {
891 891
                         // set pages visited where the first will be the http referrer
892
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
892
+                        $this->_session_data['pages_visited'][$this->_time] = $page_visit;
893 893
                         // we'll only save the last 10 page visits.
894 894
                         $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
895 895
                     }
896 896
                     break;
897 897
                 default:
898 898
                     // carry any other data over
899
-                    $session_data[ $key ] = $this->_session_data[ $key ];
899
+                    $session_data[$key] = $this->_session_data[$key];
900 900
             }
901 901
         }
902 902
         $this->_session_data = $session_data;
903 903
         // creating a new session does not require saving to the db just yet
904
-        if (! $new_session) {
904
+        if ( ! $new_session) {
905 905
             // ready? let's save
906 906
             if ($this->_save_session_to_db()) {
907 907
                 return true;
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
         }
980 980
         $transaction = $this->transaction();
981 981
         if ($transaction instanceof EE_Transaction) {
982
-            if (! $transaction->ID()) {
982
+            if ( ! $transaction->ID()) {
983 983
                 $transaction->save();
984 984
             }
985 985
             $this->_session_data['transaction'] = $transaction->ID();
@@ -993,14 +993,14 @@  discard block
 block discarded – undo
993 993
         // maybe save hash check
994 994
         if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
995 995
             $this->cache_storage->add(
996
-                EE_Session::hash_check_prefix . $this->_sid,
996
+                EE_Session::hash_check_prefix.$this->_sid,
997 997
                 md5($session_data),
998 998
                 $this->session_lifespan->inSeconds()
999 999
             );
1000 1000
         }
1001 1001
         // we're using the Transient API for storing session data,
1002 1002
         $saved = $this->cache_storage->add(
1003
-            EE_Session::session_id_prefix . $this->_sid,
1003
+            EE_Session::session_id_prefix.$this->_sid,
1004 1004
             $session_data,
1005 1005
             $this->session_lifespan->inSeconds()
1006 1006
         );
@@ -1015,7 +1015,7 @@  discard block
 block discarded – undo
1015 1015
      */
1016 1016
     public function _get_page_visit()
1017 1017
     {
1018
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
1018
+        $page_visit = home_url('/').'wp-admin/admin-ajax.php';
1019 1019
         // check for request url
1020 1020
         if ($this->request->serverParamIsSet('REQUEST_URI')) {
1021 1021
             $page_id = '?';
@@ -1027,14 +1027,14 @@  discard block
 block discarded – undo
1027 1027
             // check for page_id in SERVER REQUEST
1028 1028
             if ($this->request->requestParamIsSet('page_id')) {
1029 1029
                 // rebuild $e_reg without any of the extra parameters
1030
-                $page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&amp;';
1030
+                $page_id .= 'page_id='.$this->request->getRequestParam('page_id', 0, 'int').'&amp;';
1031 1031
             }
1032 1032
             // check for $e_reg in SERVER REQUEST
1033 1033
             if ($this->request->requestParamIsSet('ee')) {
1034 1034
                 // rebuild $e_reg without any of the extra parameters
1035
-                $e_reg = 'ee=' . $this->request->getRequestParam('ee');
1035
+                $e_reg = 'ee='.$this->request->getRequestParam('ee');
1036 1036
             }
1037
-            $page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?'));
1037
+            $page_visit = esc_url(rtrim($http_host.$request_uri.$page_id.$e_reg, '?'));
1038 1038
         }
1039 1039
         return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
1040 1040
     }
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1072 1072
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1073 1073
 // </h3>';
1074
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1074
+        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()');
1075 1075
         $this->reset_cart();
1076 1076
         $this->reset_checkout();
1077 1077
         $this->reset_transaction();
@@ -1094,7 +1094,7 @@  discard block
 block discarded – undo
1094 1094
     public function reset_data($data_to_reset = array(), $show_all_notices = false)
1095 1095
     {
1096 1096
         // if $data_to_reset is not in an array, then put it in one
1097
-        if (! is_array($data_to_reset)) {
1097
+        if ( ! is_array($data_to_reset)) {
1098 1098
             $data_to_reset = array($data_to_reset);
1099 1099
         }
1100 1100
         // nothing ??? go home!
@@ -1114,11 +1114,11 @@  discard block
 block discarded – undo
1114 1114
         // since $data_to_reset is an array, cycle through the values
1115 1115
         foreach ($data_to_reset as $reset) {
1116 1116
             // first check to make sure it is a valid session var
1117
-            if (isset($this->_session_data[ $reset ])) {
1117
+            if (isset($this->_session_data[$reset])) {
1118 1118
                 // then check to make sure it is not a default var
1119
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1119
+                if ( ! array_key_exists($reset, $this->_default_session_vars)) {
1120 1120
                     // remove session var
1121
-                    unset($this->_session_data[ $reset ]);
1121
+                    unset($this->_session_data[$reset]);
1122 1122
                     $this->setSaveState();
1123 1123
                     if ($show_all_notices) {
1124 1124
                         EE_Error::add_success(
@@ -1221,7 +1221,7 @@  discard block
 block discarded – undo
1221 1221
             // or use that for the new transient cleanup query limit
1222 1222
             add_filter(
1223 1223
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1224
-                function () use ($expired_session_transient_delete_query_limit) {
1224
+                function() use ($expired_session_transient_delete_query_limit) {
1225 1225
                     return $expired_session_transient_delete_query_limit;
1226 1226
                 }
1227 1227
             );
@@ -1239,7 +1239,7 @@  discard block
 block discarded – undo
1239 1239
         $error = '<pre>';
1240 1240
         $data2 = preg_replace_callback(
1241 1241
             '!s:(\d+):"(.*?)";!',
1242
-            function ($match) {
1242
+            function($match) {
1243 1243
                 return ($match[1] === strlen($match[2]))
1244 1244
                     ? $match[0]
1245 1245
                     : 's:'
@@ -1251,13 +1251,13 @@  discard block
 block discarded – undo
1251 1251
             $data1
1252 1252
         );
1253 1253
         $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1254
-        $error .= $data1 . PHP_EOL;
1255
-        $error .= $data2 . PHP_EOL;
1254
+        $error .= $data1.PHP_EOL;
1255
+        $error .= $data2.PHP_EOL;
1256 1256
         for ($i = 0; $i < $max; $i++) {
1257
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1258
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1259
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1260
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1257
+            if (@$data1[$i] !== @$data2[$i]) {
1258
+                $error .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL;
1259
+                $error .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL;
1260
+                $error .= "\t-> Line Number = $i".PHP_EOL;
1261 1261
                 $start = ($i - 20);
1262 1262
                 $start = ($start < 0) ? 0 : $start;
1263 1263
                 $length = 40;
@@ -1272,7 +1272,7 @@  discard block
 block discarded – undo
1272 1272
                 $error .= "\t-> Section Data1  = ";
1273 1273
                 $error .= substr_replace(
1274 1274
                     substr($data1, $start, $length),
1275
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1275
+                    "<b style=\"color:green\">{$data1[$i]}</b>",
1276 1276
                     $rpoint,
1277 1277
                     $rlength
1278 1278
                 );
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
                 $error .= "\t-> Section Data2  = ";
1281 1281
                 $error .= substr_replace(
1282 1282
                     substr($data2, $start, $length),
1283
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1283
+                    "<b style=\"color:red\">{$data2[$i]}</b>",
1284 1284
                     $rpoint,
1285 1285
                     $rlength
1286 1286
                 );
@@ -1311,7 +1311,7 @@  discard block
 block discarded – undo
1311 1311
     public function garbageCollection()
1312 1312
     {
1313 1313
         // only perform during regular requests if last garbage collection was over an hour ago
1314
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1314
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1315 1315
             $this->_last_gc = time();
1316 1316
             $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1317 1317
             /** @type WPDB $wpdb */
@@ -1346,7 +1346,7 @@  discard block
 block discarded – undo
1346 1346
                 // AND option_value < 1508368198 LIMIT 50
1347 1347
                 $expired_sessions = $wpdb->get_col($SQL);
1348 1348
                 // valid results?
1349
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1349
+                if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1350 1350
                     $this->cache_storage->deleteMany($expired_sessions, true);
1351 1351
                 }
1352 1352
             }
Please login to merge, or discard this patch.
Indentation   +1312 added lines, -1312 removed lines patch added patch discarded remove patch
@@ -23,1310 +23,1310 @@  discard block
 block discarded – undo
23 23
  */
24 24
 class EE_Session implements SessionIdentifierInterface
25 25
 {
26
-    const session_id_prefix = 'ee_ssn_';
27
-
28
-    const hash_check_prefix = 'ee_shc_';
29
-
30
-    const OPTION_NAME_SETTINGS = 'ee_session_settings';
31
-
32
-    const STATUS_CLOSED = 0;
33
-
34
-    const STATUS_OPEN = 1;
35
-
36
-    const SAVE_STATE_CLEAN = 'clean';
37
-    const SAVE_STATE_DIRTY = 'dirty';
38
-
39
-
40
-    /**
41
-     * instance of the EE_Session object
42
-     *
43
-     * @var EE_Session
44
-     */
45
-    private static $_instance;
46
-
47
-    /**
48
-     * @var CacheStorageInterface $cache_storage
49
-     */
50
-    protected $cache_storage;
51
-
52
-    /**
53
-     * @var EE_Encryption $encryption
54
-     */
55
-    protected $encryption;
56
-
57
-    /**
58
-     * @var SessionStartHandler $session_start_handler
59
-     */
60
-    protected $session_start_handler;
61
-
62
-    /**
63
-     * the session id
64
-     *
65
-     * @var string
66
-     */
67
-    private $_sid;
68
-
69
-    /**
70
-     * session id salt
71
-     *
72
-     * @var string
73
-     */
74
-    private $_sid_salt;
75
-
76
-    /**
77
-     * session data
78
-     *
79
-     * @var array
80
-     */
81
-    private $_session_data = array();
82
-
83
-    /**
84
-     * how long an EE session lasts
85
-     * default session lifespan of 1 hour (for not so instant IPNs)
86
-     *
87
-     * @var SessionLifespan $session_lifespan
88
-     */
89
-    private $session_lifespan;
90
-
91
-    /**
92
-     * session expiration time as Unix timestamp in GMT
93
-     *
94
-     * @var int
95
-     */
96
-    private $_expiration;
97
-
98
-    /**
99
-     * whether or not session has expired at some point
100
-     *
101
-     * @var boolean
102
-     */
103
-    private $_expired = false;
104
-
105
-    /**
106
-     * current time as Unix timestamp in GMT
107
-     *
108
-     * @var int
109
-     */
110
-    private $_time;
111
-
112
-    /**
113
-     * whether to encrypt session data
114
-     *
115
-     * @var bool
116
-     */
117
-    private $_use_encryption;
118
-
119
-    /**
120
-     * well... according to the server...
121
-     *
122
-     * @var null
123
-     */
124
-    private $_user_agent;
125
-
126
-    /**
127
-     * do you really trust the server ?
128
-     *
129
-     * @var null
130
-     */
131
-    private $_ip_address;
132
-
133
-    /**
134
-     * current WP user_id
135
-     *
136
-     * @var null
137
-     */
138
-    private $_wp_user_id;
139
-
140
-    /**
141
-     * array for defining default session vars
142
-     *
143
-     * @var array
144
-     */
145
-    private $_default_session_vars = array(
146
-        'id'            => null,
147
-        'user_id'       => null,
148
-        'ip_address'    => null,
149
-        'user_agent'    => null,
150
-        'init_access'   => null,
151
-        'last_access'   => null,
152
-        'expiration'    => null,
153
-        'pages_visited' => array(),
154
-    );
155
-
156
-    /**
157
-     * timestamp for when last garbage collection cycle was performed
158
-     *
159
-     * @var int $_last_gc
160
-     */
161
-    private $_last_gc;
162
-
163
-    /**
164
-     * @var RequestInterface $request
165
-     */
166
-    protected $request;
167
-
168
-    /**
169
-     * whether session is active or not
170
-     *
171
-     * @var int $status
172
-     */
173
-    private $status = EE_Session::STATUS_CLOSED;
174
-
175
-    /**
176
-     * whether session data has changed therefore requiring a session save
177
-     *
178
-     * @var string $save_state
179
-     */
180
-    private $save_state = EE_Session::SAVE_STATE_CLEAN;
181
-
182
-
183
-    /**
184
-     * @singleton method used to instantiate class object
185
-     * @param CacheStorageInterface $cache_storage
186
-     * @param SessionLifespan|null  $lifespan
187
-     * @param RequestInterface      $request
188
-     * @param SessionStartHandler   $session_start_handler
189
-     * @param EE_Encryption         $encryption
190
-     * @return EE_Session
191
-     * @throws InvalidArgumentException
192
-     * @throws InvalidDataTypeException
193
-     * @throws InvalidInterfaceException
194
-     */
195
-    public static function instance(
196
-        CacheStorageInterface $cache_storage = null,
197
-        SessionLifespan $lifespan = null,
198
-        RequestInterface $request = null,
199
-        SessionStartHandler $session_start_handler = null,
200
-        EE_Encryption $encryption = null
201
-    ) {
202
-        // check if class object is instantiated
203
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
204
-        // add_filter( 'FHEE_load_EE_Session', '__return_false' );
205
-        if (
206
-            ! self::$_instance instanceof EE_Session
207
-            && $cache_storage instanceof CacheStorageInterface
208
-            && $lifespan instanceof SessionLifespan
209
-            && $request instanceof RequestInterface
210
-            && $session_start_handler instanceof SessionStartHandler
211
-            && apply_filters('FHEE_load_EE_Session', true)
212
-        ) {
213
-            self::$_instance = new self(
214
-                $cache_storage,
215
-                $lifespan,
216
-                $request,
217
-                $session_start_handler,
218
-                $encryption
219
-            );
220
-        }
221
-        return self::$_instance;
222
-    }
223
-
224
-
225
-    /**
226
-     * protected constructor to prevent direct creation
227
-     *
228
-     * @param CacheStorageInterface $cache_storage
229
-     * @param SessionLifespan       $lifespan
230
-     * @param RequestInterface      $request
231
-     * @param SessionStartHandler   $session_start_handler
232
-     * @param EE_Encryption         $encryption
233
-     * @throws InvalidArgumentException
234
-     * @throws InvalidDataTypeException
235
-     * @throws InvalidInterfaceException
236
-     */
237
-    protected function __construct(
238
-        CacheStorageInterface $cache_storage,
239
-        SessionLifespan $lifespan,
240
-        RequestInterface $request,
241
-        SessionStartHandler $session_start_handler,
242
-        EE_Encryption $encryption = null
243
-    ) {
244
-        // session loading is turned ON by default,
245
-        // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
246
-        // (which currently fires on the init hook at priority 9),
247
-        // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
248
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
249
-            return;
250
-        }
251
-        $this->session_start_handler = $session_start_handler;
252
-        $this->session_lifespan = $lifespan;
253
-        $this->request = $request;
254
-        if (! defined('ESPRESSO_SESSION')) {
255
-            define('ESPRESSO_SESSION', true);
256
-        }
257
-        // retrieve session options from db
258
-        $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
259
-        if (! empty($session_settings)) {
260
-            // cycle though existing session options
261
-            foreach ($session_settings as $var_name => $session_setting) {
262
-                // set values for class properties
263
-                $var_name = '_' . $var_name;
264
-                $this->{$var_name} = $session_setting;
265
-            }
266
-        }
267
-        $this->cache_storage = $cache_storage;
268
-        // are we using encryption?
269
-        $this->_use_encryption = $encryption instanceof EE_Encryption
270
-                                 && EE_Registry::instance()->CFG->admin->encode_session_data();
271
-        // encrypt data via: $this->encryption->encrypt();
272
-        $this->encryption = $encryption;
273
-        // filter hook allows outside functions/classes/plugins to change default empty cart
274
-        $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
275
-        array_merge($this->_default_session_vars, $extra_default_session_vars);
276
-        // apply default session vars
277
-        $this->_set_defaults();
278
-        add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
279
-        // check request for 'clear_session' param
280
-        add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
281
-        // once everything is all said and done,
282
-        add_action('shutdown', array($this, 'update'), 100);
283
-        add_action('shutdown', array($this, 'garbageCollection'), 1000);
284
-        $this->configure_garbage_collection_filters();
285
-    }
286
-
287
-
288
-    /**
289
-     * @return bool
290
-     * @throws InvalidArgumentException
291
-     * @throws InvalidDataTypeException
292
-     * @throws InvalidInterfaceException
293
-     */
294
-    public static function isLoadedAndActive()
295
-    {
296
-        return did_action('AHEE__EE_System__core_loaded_and_ready')
297
-               && EE_Session::instance() instanceof EE_Session
298
-               && EE_Session::instance()->isActive();
299
-    }
300
-
301
-
302
-    /**
303
-     * @return bool
304
-     */
305
-    public function isActive()
306
-    {
307
-        return $this->status === EE_Session::STATUS_OPEN;
308
-    }
309
-
310
-
311
-    /**
312
-     * @return void
313
-     * @throws EE_Error
314
-     * @throws InvalidArgumentException
315
-     * @throws InvalidDataTypeException
316
-     * @throws InvalidInterfaceException
317
-     * @throws InvalidSessionDataException
318
-     * @throws RuntimeException
319
-     * @throws ReflectionException
320
-     */
321
-    public function open_session()
322
-    {
323
-        // check for existing session and retrieve it from db
324
-        if (! $this->_espresso_session()) {
325
-            // or just start a new one
326
-            $this->_create_espresso_session();
327
-        }
328
-    }
329
-
330
-
331
-    /**
332
-     * @return bool
333
-     */
334
-    public function expired()
335
-    {
336
-        return $this->_expired;
337
-    }
338
-
339
-
340
-    /**
341
-     * @return void
342
-     */
343
-    public function reset_expired()
344
-    {
345
-        $this->_expired = false;
346
-    }
347
-
348
-
349
-    /**
350
-     * @return int
351
-     */
352
-    public function expiration()
353
-    {
354
-        return $this->_expiration;
355
-    }
356
-
357
-
358
-    /**
359
-     * @return int
360
-     */
361
-    public function extension()
362
-    {
363
-        return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
364
-    }
365
-
366
-
367
-    /**
368
-     * @param int $time number of seconds to add to session expiration
369
-     */
370
-    public function extend_expiration($time = 0)
371
-    {
372
-        $time = $time ? $time : $this->extension();
373
-        $this->_expiration += absint($time);
374
-    }
375
-
376
-
377
-    /**
378
-     * @return int
379
-     */
380
-    public function lifespan()
381
-    {
382
-        return $this->session_lifespan->inSeconds();
383
-    }
384
-
385
-
386
-    /**
387
-     * Marks whether the session data has been updated or not.
388
-     * Valid options are:
389
-     *      EE_Session::SAVE_STATE_CLEAN - session data remains unchanged and updating is not necessary
390
-     *      EE_Session::SAVE_STATE_DIRTY - session data has changed since last save and needs to be updated
391
-     * default value is EE_Session::SAVE_STATE_DIRTY
392
-     *
393
-     * @param string $save_state
394
-     */
395
-    public function setSaveState($save_state = EE_Session::SAVE_STATE_DIRTY)
396
-    {
397
-        $valid_save_states = [
398
-            EE_Session::SAVE_STATE_CLEAN,
399
-            EE_Session::SAVE_STATE_DIRTY,
400
-        ];
401
-        if (! in_array($save_state, $valid_save_states, true)) {
402
-            $save_state = EE_Session::SAVE_STATE_DIRTY;
403
-        }
404
-        $this->save_state = $save_state;
405
-    }
406
-
407
-
408
-
409
-    /**
410
-     * This just sets some defaults for the _session data property
411
-     *
412
-     * @return void
413
-     */
414
-    private function _set_defaults()
415
-    {
416
-        // set some defaults
417
-        foreach ($this->_default_session_vars as $key => $default_var) {
418
-            if (is_array($default_var)) {
419
-                $this->_session_data[ $key ] = array();
420
-            } else {
421
-                $this->_session_data[ $key ] = '';
422
-            }
423
-        }
424
-    }
425
-
426
-
427
-    /**
428
-     * @retrieve  session data
429
-     * @return    string
430
-     */
431
-    public function id()
432
-    {
433
-        return $this->_sid;
434
-    }
435
-
436
-
437
-    /**
438
-     * @param \EE_Cart $cart
439
-     * @return bool
440
-     */
441
-    public function set_cart(EE_Cart $cart)
442
-    {
443
-        $this->_session_data['cart'] = $cart;
444
-        $this->setSaveState();
445
-        return true;
446
-    }
447
-
448
-
449
-    /**
450
-     * reset_cart
451
-     */
452
-    public function reset_cart()
453
-    {
454
-        do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
455
-        $this->_session_data['cart'] = null;
456
-        $this->setSaveState();
457
-    }
458
-
459
-
460
-    /**
461
-     * @return \EE_Cart
462
-     */
463
-    public function cart()
464
-    {
465
-        return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
466
-            ? $this->_session_data['cart']
467
-            : null;
468
-    }
469
-
470
-
471
-    /**
472
-     * @param \EE_Checkout $checkout
473
-     * @return bool
474
-     */
475
-    public function set_checkout(EE_Checkout $checkout)
476
-    {
477
-        $this->_session_data['checkout'] = $checkout;
478
-        $this->setSaveState();
479
-        return true;
480
-    }
481
-
482
-
483
-    /**
484
-     * reset_checkout
485
-     */
486
-    public function reset_checkout()
487
-    {
488
-        do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
489
-        $this->_session_data['checkout'] = null;
490
-        $this->setSaveState();
491
-    }
492
-
493
-
494
-    /**
495
-     * @return \EE_Checkout
496
-     */
497
-    public function checkout()
498
-    {
499
-        return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
500
-            ? $this->_session_data['checkout']
501
-            : null;
502
-    }
503
-
504
-
505
-    /**
506
-     * @param \EE_Transaction $transaction
507
-     * @return bool
508
-     * @throws EE_Error
509
-     */
510
-    public function set_transaction(EE_Transaction $transaction)
511
-    {
512
-        // first remove the session from the transaction before we save the transaction in the session
513
-        $transaction->set_txn_session_data(null);
514
-        $this->_session_data['transaction'] = $transaction;
515
-        $this->setSaveState();
516
-        return true;
517
-    }
518
-
519
-
520
-    /**
521
-     * reset_transaction
522
-     */
523
-    public function reset_transaction()
524
-    {
525
-        do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
526
-        $this->_session_data['transaction'] = null;
527
-        $this->setSaveState();
528
-    }
529
-
530
-
531
-    /**
532
-     * @return \EE_Transaction
533
-     */
534
-    public function transaction()
535
-    {
536
-        return isset($this->_session_data['transaction'])
537
-               && $this->_session_data['transaction'] instanceof EE_Transaction
538
-            ? $this->_session_data['transaction']
539
-            : null;
540
-    }
541
-
542
-
543
-    /**
544
-     * retrieve session data
545
-     *
546
-     * @param null $key
547
-     * @param bool $reset_cache
548
-     * @return array|EE_Cart|EE_Checkout|EE_Transaction
549
-     */
550
-    public function get_session_data($key = null, $reset_cache = false)
551
-    {
552
-        if ($reset_cache) {
553
-            $this->reset_cart();
554
-            $this->reset_checkout();
555
-            $this->reset_transaction();
556
-        }
557
-        if (! empty($key)) {
558
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
559
-        }
560
-        return $this->_session_data;
561
-    }
562
-
563
-
564
-    /**
565
-     * Returns TRUE on success, FALSE on fail
566
-     *
567
-     * @param array $data
568
-     * @return bool
569
-     */
570
-    public function set_session_data($data)
571
-    {
572
-        // nothing ??? bad data ??? go home!
573
-        if (empty($data) || ! is_array($data)) {
574
-            EE_Error::add_error(
575
-                esc_html__(
576
-                    'No session data or invalid session data was provided.',
577
-                    'event_espresso'
578
-                ),
579
-                __FILE__,
580
-                __FUNCTION__,
581
-                __LINE__
582
-            );
583
-            return false;
584
-        }
585
-        foreach ($data as $key => $value) {
586
-            if (isset($this->_default_session_vars[ $key ])) {
587
-                EE_Error::add_error(
588
-                    sprintf(
589
-                        esc_html__(
590
-                            'Sorry! %s is a default session datum and can not be reset.',
591
-                            'event_espresso'
592
-                        ),
593
-                        $key
594
-                    ),
595
-                    __FILE__,
596
-                    __FUNCTION__,
597
-                    __LINE__
598
-                );
599
-                return false;
600
-            }
601
-            $this->_session_data[ $key ] = $value;
602
-            $this->setSaveState();
603
-        }
604
-        return true;
605
-    }
606
-
607
-
608
-    /**
609
-     * @initiate session
610
-     * @return bool TRUE on success, FALSE on fail
611
-     * @throws EE_Error
612
-     * @throws InvalidArgumentException
613
-     * @throws InvalidDataTypeException
614
-     * @throws InvalidInterfaceException
615
-     * @throws InvalidSessionDataException
616
-     * @throws RuntimeException
617
-     * @throws ReflectionException
618
-     */
619
-    private function _espresso_session()
620
-    {
621
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
622
-        $this->session_start_handler->startSession();
623
-        $this->status = EE_Session::STATUS_OPEN;
624
-        // get our modified session ID
625
-        $this->_sid = $this->_generate_session_id();
626
-        // and the visitors IP
627
-        $this->_ip_address = $this->request->ipAddress();
628
-        // set the "user agent"
629
-        $this->_user_agent = $this->request->userAgent();
630
-        // now let's retrieve what's in the db
631
-        $session_data = $this->_retrieve_session_data();
632
-        if (! empty($session_data)) {
633
-            // get the current time in UTC
634
-            $this->_time = $this->_time !== null ? $this->_time : time();
635
-            // and reset the session expiration
636
-            $this->_expiration = isset($session_data['expiration'])
637
-                ? $session_data['expiration']
638
-                : $this->_time + $this->session_lifespan->inSeconds();
639
-        } else {
640
-            // set initial site access time and the session expiration
641
-            $this->_set_init_access_and_expiration();
642
-            // set referer
643
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr(
644
-                $this->request->getServerParam('HTTP_REFERER')
645
-            );
646
-            // no previous session = go back and create one (on top of the data above)
647
-            return false;
648
-        }
649
-        // now the user agent
650
-        if ($session_data['user_agent'] !== $this->_user_agent) {
651
-            return false;
652
-        }
653
-        // wait a minute... how old are you?
654
-        if ($this->_time > $this->_expiration) {
655
-            // yer too old fer me!
656
-            $this->_expired = true;
657
-            // wipe out everything that isn't a default session datum
658
-            $this->clear_session(__CLASS__, __FUNCTION__);
659
-        }
660
-        // make event espresso session data available to plugin
661
-        $this->_session_data = array_merge($this->_session_data, $session_data);
662
-        return true;
663
-    }
664
-
665
-
666
-    /**
667
-     * _get_session_data
668
-     * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
669
-     * databases
670
-     *
671
-     * @return array
672
-     * @throws EE_Error
673
-     * @throws InvalidArgumentException
674
-     * @throws InvalidSessionDataException
675
-     * @throws InvalidDataTypeException
676
-     * @throws InvalidInterfaceException
677
-     * @throws RuntimeException
678
-     */
679
-    protected function _retrieve_session_data()
680
-    {
681
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
682
-        try {
683
-            // we're using WP's Transient API to store session data using the PHP session ID as the option name
684
-            $session_data = $this->cache_storage->get($ssn_key, false);
685
-            if (empty($session_data)) {
686
-                return array();
687
-            }
688
-            if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
689
-                $hash_check = $this->cache_storage->get(
690
-                    EE_Session::hash_check_prefix . $this->_sid,
691
-                    false
692
-                );
693
-                if ($hash_check && $hash_check !== md5($session_data)) {
694
-                    EE_Error::add_error(
695
-                        sprintf(
696
-                            esc_html__(
697
-                                'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
698
-                                'event_espresso'
699
-                            ),
700
-                            EE_Session::session_id_prefix . $this->_sid
701
-                        ),
702
-                        __FILE__,
703
-                        __FUNCTION__,
704
-                        __LINE__
705
-                    );
706
-                }
707
-            }
708
-        } catch (Exception $e) {
709
-            // let's just eat that error for now and attempt to correct any corrupted data
710
-            global $wpdb;
711
-            $row = $wpdb->get_row(
712
-                $wpdb->prepare(
713
-                    "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
714
-                    '_transient_' . $ssn_key
715
-                )
716
-            );
717
-            $session_data = is_object($row) ? $row->option_value : null;
718
-            if ($session_data) {
719
-                $session_data = preg_replace_callback(
720
-                    '!s:(d+):"(.*?)";!',
721
-                    function ($match) {
722
-                        return $match[1] === strlen($match[2])
723
-                            ? $match[0]
724
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
725
-                    },
726
-                    $session_data
727
-                );
728
-            }
729
-            $session_data = maybe_unserialize($session_data);
730
-        }
731
-        // in case the data is encoded... try to decode it
732
-        $session_data = $this->encryption instanceof EE_Encryption
733
-            ? $this->encryption->base64_string_decode($session_data)
734
-            : $session_data;
735
-        if (! is_array($session_data)) {
736
-            try {
737
-                $session_data = maybe_unserialize($session_data);
738
-            } catch (Exception $e) {
739
-                $msg = esc_html__(
740
-                    'An error occurred while attempting to unserialize the session data.',
741
-                    'event_espresso'
742
-                );
743
-                $msg .= WP_DEBUG
744
-                    ? '<br><pre>'
745
-                      . print_r($session_data, true)
746
-                      . '</pre><br>'
747
-                      . $this->find_serialize_error($session_data)
748
-                    : '';
749
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
750
-                throw new InvalidSessionDataException($msg, 0, $e);
751
-            }
752
-        }
753
-        // just a check to make sure the session array is indeed an array
754
-        if (! is_array($session_data)) {
755
-            // no?!?! then something is wrong
756
-            $msg = esc_html__(
757
-                'The session data is missing, invalid, or corrupted.',
758
-                'event_espresso'
759
-            );
760
-            $msg .= WP_DEBUG
761
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
762
-                : '';
763
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
764
-            throw new InvalidSessionDataException($msg);
765
-        }
766
-        if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
767
-            $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
768
-                $session_data['transaction']
769
-            );
770
-        }
771
-        return $session_data;
772
-    }
773
-
774
-
775
-    /**
776
-     * _generate_session_id
777
-     * Retrieves the PHP session id either directly from the PHP session,
778
-     * or from the request array if it was passed in from an AJAX request.
779
-     * The session id is then salted and hashed (mmm sounds tasty)
780
-     * so that it can be safely used as a request param
781
-     *
782
-     * @return string
783
-     */
784
-    protected function _generate_session_id()
785
-    {
786
-        // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
787
-        $session_id = $this->request->requestParamIsSet('EESID')
788
-            ? $this->request->getRequestParam('EESID')
789
-            : md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
790
-        return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
791
-    }
792
-
793
-
794
-    /**
795
-     * _get_sid_salt
796
-     *
797
-     * @return string
798
-     */
799
-    protected function _get_sid_salt()
800
-    {
801
-        // was session id salt already saved to db ?
802
-        if (empty($this->_sid_salt)) {
803
-            // no?  then maybe use WP defined constant
804
-            if (defined('AUTH_SALT')) {
805
-                $this->_sid_salt = AUTH_SALT;
806
-            }
807
-            // if salt doesn't exist or is too short
808
-            if (strlen($this->_sid_salt) < 32) {
809
-                // create a new one
810
-                $this->_sid_salt = wp_generate_password(64);
811
-            }
812
-            // and save it as a permanent session setting
813
-            $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
814
-        }
815
-        return $this->_sid_salt;
816
-    }
817
-
818
-
819
-    /**
820
-     * _set_init_access_and_expiration
821
-     *
822
-     * @return void
823
-     */
824
-    protected function _set_init_access_and_expiration()
825
-    {
826
-        $this->_time = time();
827
-        $this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
828
-        // set initial site access time
829
-        $this->_session_data['init_access'] = $this->_time;
830
-        // and the session expiration
831
-        $this->_session_data['expiration'] = $this->_expiration;
832
-    }
833
-
834
-
835
-    /**
836
-     * @update session data  prior to saving to the db
837
-     * @param bool $new_session
838
-     * @return bool TRUE on success, FALSE on fail
839
-     * @throws EE_Error
840
-     * @throws InvalidArgumentException
841
-     * @throws InvalidDataTypeException
842
-     * @throws InvalidInterfaceException
843
-     * @throws ReflectionException
844
-     */
845
-    public function update($new_session = false)
846
-    {
847
-        $this->_session_data = is_array($this->_session_data) && isset($this->_session_data['id'])
848
-            ? $this->_session_data
849
-            : array();
850
-        if (empty($this->_session_data)) {
851
-            $this->_set_defaults();
852
-        }
853
-        $session_data = array();
854
-        foreach ($this->_session_data as $key => $value) {
855
-            switch ($key) {
856
-                case 'id':
857
-                    // session ID
858
-                    $session_data['id'] = $this->_sid;
859
-                    break;
860
-                case 'ip_address':
861
-                    // visitor ip address
862
-                    $session_data['ip_address'] = $this->request->ipAddress();
863
-                    break;
864
-                case 'user_agent':
865
-                    // visitor user_agent
866
-                    $session_data['user_agent'] = $this->_user_agent;
867
-                    break;
868
-                case 'init_access':
869
-                    $session_data['init_access'] = absint($value);
870
-                    break;
871
-                case 'last_access':
872
-                    // current access time
873
-                    $session_data['last_access'] = $this->_time;
874
-                    break;
875
-                case 'expiration':
876
-                    // when the session expires
877
-                    $session_data['expiration'] = ! empty($this->_expiration)
878
-                        ? $this->_expiration
879
-                        : $session_data['init_access'] + $this->session_lifespan->inSeconds();
880
-                    break;
881
-                case 'user_id':
882
-                    // current user if logged in
883
-                    $session_data['user_id'] = $this->_wp_user_id();
884
-                    break;
885
-                case 'pages_visited':
886
-                    $page_visit = $this->_get_page_visit();
887
-                    if ($page_visit) {
888
-                        // set pages visited where the first will be the http referrer
889
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
890
-                        // we'll only save the last 10 page visits.
891
-                        $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
892
-                    }
893
-                    break;
894
-                default:
895
-                    // carry any other data over
896
-                    $session_data[ $key ] = $this->_session_data[ $key ];
897
-            }
898
-        }
899
-        $this->_session_data = $session_data;
900
-        // creating a new session does not require saving to the db just yet
901
-        if (! $new_session) {
902
-            // ready? let's save
903
-            if ($this->_save_session_to_db()) {
904
-                return true;
905
-            }
906
-            return false;
907
-        }
908
-        // meh, why not?
909
-        return true;
910
-    }
911
-
912
-
913
-    /**
914
-     * @create session data array
915
-     * @throws EE_Error
916
-     * @throws InvalidArgumentException
917
-     * @throws InvalidDataTypeException
918
-     * @throws InvalidInterfaceException
919
-     * @throws ReflectionException
920
-     */
921
-    private function _create_espresso_session()
922
-    {
923
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
924
-        // use the update function for now with $new_session arg set to TRUE
925
-        $this->update(true);
926
-    }
927
-
928
-    /**
929
-     * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
930
-     * too). This is used when determining if we want to save the session or not.
931
-     * @since 4.9.67.p
932
-     * @return bool
933
-     */
934
-    private function sessionHasStuffWorthSaving()
935
-    {
936
-        return $this->save_state === EE_Session::SAVE_STATE_DIRTY
937
-               // we may want to eventually remove the following
938
-               // on the assumption that the above check is enough
939
-               || $this->cart() instanceof EE_Cart
940
-               || (
941
-                   isset($this->_session_data['ee_notices'])
942
-                   && (
943
-                       ! empty($this->_session_data['ee_notices']['attention'])
944
-                       || ! empty($this->_session_data['ee_notices']['errors'])
945
-                       || ! empty($this->_session_data['ee_notices']['success'])
946
-                   )
947
-               );
948
-    }
949
-
950
-
951
-    /**
952
-     * _save_session_to_db
953
-     *
954
-     * @param bool $clear_session
955
-     * @return bool
956
-     * @throws EE_Error
957
-     * @throws InvalidArgumentException
958
-     * @throws InvalidDataTypeException
959
-     * @throws InvalidInterfaceException
960
-     * @throws ReflectionException
961
-     */
962
-    private function _save_session_to_db($clear_session = false)
963
-    {
964
-        // don't save sessions for crawlers
965
-        // and unless we're deleting the session data, don't save anything if there isn't a cart
966
-        if (
967
-            $this->request->isBot()
968
-            || (
969
-                ! $clear_session
970
-                && ! $this->sessionHasStuffWorthSaving()
971
-                && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
972
-            )
973
-        ) {
974
-            return false;
975
-        }
976
-        $transaction = $this->transaction();
977
-        if ($transaction instanceof EE_Transaction) {
978
-            if (! $transaction->ID()) {
979
-                $transaction->save();
980
-            }
981
-            $this->_session_data['transaction'] = $transaction->ID();
982
-        }
983
-        // then serialize all of our session data
984
-        $session_data = serialize($this->_session_data);
985
-        // do we need to also encode it to avoid corrupted data when saved to the db?
986
-        $session_data = $this->_use_encryption
987
-            ? $this->encryption->base64_string_encode($session_data)
988
-            : $session_data;
989
-        // maybe save hash check
990
-        if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
991
-            $this->cache_storage->add(
992
-                EE_Session::hash_check_prefix . $this->_sid,
993
-                md5($session_data),
994
-                $this->session_lifespan->inSeconds()
995
-            );
996
-        }
997
-        // we're using the Transient API for storing session data,
998
-        $saved = $this->cache_storage->add(
999
-            EE_Session::session_id_prefix . $this->_sid,
1000
-            $session_data,
1001
-            $this->session_lifespan->inSeconds()
1002
-        );
1003
-        $this->setSaveState(EE_Session::SAVE_STATE_CLEAN);
1004
-        return $saved;
1005
-    }
1006
-
1007
-
1008
-    /**
1009
-     * @get    the full page request the visitor is accessing
1010
-     * @return string
1011
-     */
1012
-    public function _get_page_visit()
1013
-    {
1014
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
1015
-        // check for request url
1016
-        if ($this->request->serverParamIsSet('REQUEST_URI')) {
1017
-            $page_id = '?';
1018
-            $e_reg = '';
1019
-            $request_uri = $this->request->getServerParam('REQUEST_URI');
1020
-            $ru_bits = explode('?', $request_uri);
1021
-            $request_uri = $ru_bits[0];
1022
-            $http_host = $this->request->getServerParam('HTTP_HOST');
1023
-            // check for page_id in SERVER REQUEST
1024
-            if ($this->request->requestParamIsSet('page_id')) {
1025
-                // rebuild $e_reg without any of the extra parameters
1026
-                $page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&amp;';
1027
-            }
1028
-            // check for $e_reg in SERVER REQUEST
1029
-            if ($this->request->requestParamIsSet('ee')) {
1030
-                // rebuild $e_reg without any of the extra parameters
1031
-                $e_reg = 'ee=' . $this->request->getRequestParam('ee');
1032
-            }
1033
-            $page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?'));
1034
-        }
1035
-        return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * @the    current wp user id
1041
-     * @return int
1042
-     */
1043
-    public function _wp_user_id()
1044
-    {
1045
-        // if I need to explain the following lines of code, then you shouldn't be looking at this!
1046
-        $this->_wp_user_id = get_current_user_id();
1047
-        return $this->_wp_user_id;
1048
-    }
1049
-
1050
-
1051
-    /**
1052
-     * Clear EE_Session data
1053
-     *
1054
-     * @param string $class
1055
-     * @param string $function
1056
-     * @return void
1057
-     * @throws EE_Error
1058
-     * @throws InvalidArgumentException
1059
-     * @throws InvalidDataTypeException
1060
-     * @throws InvalidInterfaceException
1061
-     * @throws ReflectionException
1062
-     */
1063
-    public function clear_session($class = '', $function = '')
1064
-    {
26
+	const session_id_prefix = 'ee_ssn_';
27
+
28
+	const hash_check_prefix = 'ee_shc_';
29
+
30
+	const OPTION_NAME_SETTINGS = 'ee_session_settings';
31
+
32
+	const STATUS_CLOSED = 0;
33
+
34
+	const STATUS_OPEN = 1;
35
+
36
+	const SAVE_STATE_CLEAN = 'clean';
37
+	const SAVE_STATE_DIRTY = 'dirty';
38
+
39
+
40
+	/**
41
+	 * instance of the EE_Session object
42
+	 *
43
+	 * @var EE_Session
44
+	 */
45
+	private static $_instance;
46
+
47
+	/**
48
+	 * @var CacheStorageInterface $cache_storage
49
+	 */
50
+	protected $cache_storage;
51
+
52
+	/**
53
+	 * @var EE_Encryption $encryption
54
+	 */
55
+	protected $encryption;
56
+
57
+	/**
58
+	 * @var SessionStartHandler $session_start_handler
59
+	 */
60
+	protected $session_start_handler;
61
+
62
+	/**
63
+	 * the session id
64
+	 *
65
+	 * @var string
66
+	 */
67
+	private $_sid;
68
+
69
+	/**
70
+	 * session id salt
71
+	 *
72
+	 * @var string
73
+	 */
74
+	private $_sid_salt;
75
+
76
+	/**
77
+	 * session data
78
+	 *
79
+	 * @var array
80
+	 */
81
+	private $_session_data = array();
82
+
83
+	/**
84
+	 * how long an EE session lasts
85
+	 * default session lifespan of 1 hour (for not so instant IPNs)
86
+	 *
87
+	 * @var SessionLifespan $session_lifespan
88
+	 */
89
+	private $session_lifespan;
90
+
91
+	/**
92
+	 * session expiration time as Unix timestamp in GMT
93
+	 *
94
+	 * @var int
95
+	 */
96
+	private $_expiration;
97
+
98
+	/**
99
+	 * whether or not session has expired at some point
100
+	 *
101
+	 * @var boolean
102
+	 */
103
+	private $_expired = false;
104
+
105
+	/**
106
+	 * current time as Unix timestamp in GMT
107
+	 *
108
+	 * @var int
109
+	 */
110
+	private $_time;
111
+
112
+	/**
113
+	 * whether to encrypt session data
114
+	 *
115
+	 * @var bool
116
+	 */
117
+	private $_use_encryption;
118
+
119
+	/**
120
+	 * well... according to the server...
121
+	 *
122
+	 * @var null
123
+	 */
124
+	private $_user_agent;
125
+
126
+	/**
127
+	 * do you really trust the server ?
128
+	 *
129
+	 * @var null
130
+	 */
131
+	private $_ip_address;
132
+
133
+	/**
134
+	 * current WP user_id
135
+	 *
136
+	 * @var null
137
+	 */
138
+	private $_wp_user_id;
139
+
140
+	/**
141
+	 * array for defining default session vars
142
+	 *
143
+	 * @var array
144
+	 */
145
+	private $_default_session_vars = array(
146
+		'id'            => null,
147
+		'user_id'       => null,
148
+		'ip_address'    => null,
149
+		'user_agent'    => null,
150
+		'init_access'   => null,
151
+		'last_access'   => null,
152
+		'expiration'    => null,
153
+		'pages_visited' => array(),
154
+	);
155
+
156
+	/**
157
+	 * timestamp for when last garbage collection cycle was performed
158
+	 *
159
+	 * @var int $_last_gc
160
+	 */
161
+	private $_last_gc;
162
+
163
+	/**
164
+	 * @var RequestInterface $request
165
+	 */
166
+	protected $request;
167
+
168
+	/**
169
+	 * whether session is active or not
170
+	 *
171
+	 * @var int $status
172
+	 */
173
+	private $status = EE_Session::STATUS_CLOSED;
174
+
175
+	/**
176
+	 * whether session data has changed therefore requiring a session save
177
+	 *
178
+	 * @var string $save_state
179
+	 */
180
+	private $save_state = EE_Session::SAVE_STATE_CLEAN;
181
+
182
+
183
+	/**
184
+	 * @singleton method used to instantiate class object
185
+	 * @param CacheStorageInterface $cache_storage
186
+	 * @param SessionLifespan|null  $lifespan
187
+	 * @param RequestInterface      $request
188
+	 * @param SessionStartHandler   $session_start_handler
189
+	 * @param EE_Encryption         $encryption
190
+	 * @return EE_Session
191
+	 * @throws InvalidArgumentException
192
+	 * @throws InvalidDataTypeException
193
+	 * @throws InvalidInterfaceException
194
+	 */
195
+	public static function instance(
196
+		CacheStorageInterface $cache_storage = null,
197
+		SessionLifespan $lifespan = null,
198
+		RequestInterface $request = null,
199
+		SessionStartHandler $session_start_handler = null,
200
+		EE_Encryption $encryption = null
201
+	) {
202
+		// check if class object is instantiated
203
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
204
+		// add_filter( 'FHEE_load_EE_Session', '__return_false' );
205
+		if (
206
+			! self::$_instance instanceof EE_Session
207
+			&& $cache_storage instanceof CacheStorageInterface
208
+			&& $lifespan instanceof SessionLifespan
209
+			&& $request instanceof RequestInterface
210
+			&& $session_start_handler instanceof SessionStartHandler
211
+			&& apply_filters('FHEE_load_EE_Session', true)
212
+		) {
213
+			self::$_instance = new self(
214
+				$cache_storage,
215
+				$lifespan,
216
+				$request,
217
+				$session_start_handler,
218
+				$encryption
219
+			);
220
+		}
221
+		return self::$_instance;
222
+	}
223
+
224
+
225
+	/**
226
+	 * protected constructor to prevent direct creation
227
+	 *
228
+	 * @param CacheStorageInterface $cache_storage
229
+	 * @param SessionLifespan       $lifespan
230
+	 * @param RequestInterface      $request
231
+	 * @param SessionStartHandler   $session_start_handler
232
+	 * @param EE_Encryption         $encryption
233
+	 * @throws InvalidArgumentException
234
+	 * @throws InvalidDataTypeException
235
+	 * @throws InvalidInterfaceException
236
+	 */
237
+	protected function __construct(
238
+		CacheStorageInterface $cache_storage,
239
+		SessionLifespan $lifespan,
240
+		RequestInterface $request,
241
+		SessionStartHandler $session_start_handler,
242
+		EE_Encryption $encryption = null
243
+	) {
244
+		// session loading is turned ON by default,
245
+		// but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook
246
+		// (which currently fires on the init hook at priority 9),
247
+		// can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
248
+		if (! apply_filters('FHEE_load_EE_Session', true)) {
249
+			return;
250
+		}
251
+		$this->session_start_handler = $session_start_handler;
252
+		$this->session_lifespan = $lifespan;
253
+		$this->request = $request;
254
+		if (! defined('ESPRESSO_SESSION')) {
255
+			define('ESPRESSO_SESSION', true);
256
+		}
257
+		// retrieve session options from db
258
+		$session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
259
+		if (! empty($session_settings)) {
260
+			// cycle though existing session options
261
+			foreach ($session_settings as $var_name => $session_setting) {
262
+				// set values for class properties
263
+				$var_name = '_' . $var_name;
264
+				$this->{$var_name} = $session_setting;
265
+			}
266
+		}
267
+		$this->cache_storage = $cache_storage;
268
+		// are we using encryption?
269
+		$this->_use_encryption = $encryption instanceof EE_Encryption
270
+								 && EE_Registry::instance()->CFG->admin->encode_session_data();
271
+		// encrypt data via: $this->encryption->encrypt();
272
+		$this->encryption = $encryption;
273
+		// filter hook allows outside functions/classes/plugins to change default empty cart
274
+		$extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
275
+		array_merge($this->_default_session_vars, $extra_default_session_vars);
276
+		// apply default session vars
277
+		$this->_set_defaults();
278
+		add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
279
+		// check request for 'clear_session' param
280
+		add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
281
+		// once everything is all said and done,
282
+		add_action('shutdown', array($this, 'update'), 100);
283
+		add_action('shutdown', array($this, 'garbageCollection'), 1000);
284
+		$this->configure_garbage_collection_filters();
285
+	}
286
+
287
+
288
+	/**
289
+	 * @return bool
290
+	 * @throws InvalidArgumentException
291
+	 * @throws InvalidDataTypeException
292
+	 * @throws InvalidInterfaceException
293
+	 */
294
+	public static function isLoadedAndActive()
295
+	{
296
+		return did_action('AHEE__EE_System__core_loaded_and_ready')
297
+			   && EE_Session::instance() instanceof EE_Session
298
+			   && EE_Session::instance()->isActive();
299
+	}
300
+
301
+
302
+	/**
303
+	 * @return bool
304
+	 */
305
+	public function isActive()
306
+	{
307
+		return $this->status === EE_Session::STATUS_OPEN;
308
+	}
309
+
310
+
311
+	/**
312
+	 * @return void
313
+	 * @throws EE_Error
314
+	 * @throws InvalidArgumentException
315
+	 * @throws InvalidDataTypeException
316
+	 * @throws InvalidInterfaceException
317
+	 * @throws InvalidSessionDataException
318
+	 * @throws RuntimeException
319
+	 * @throws ReflectionException
320
+	 */
321
+	public function open_session()
322
+	{
323
+		// check for existing session and retrieve it from db
324
+		if (! $this->_espresso_session()) {
325
+			// or just start a new one
326
+			$this->_create_espresso_session();
327
+		}
328
+	}
329
+
330
+
331
+	/**
332
+	 * @return bool
333
+	 */
334
+	public function expired()
335
+	{
336
+		return $this->_expired;
337
+	}
338
+
339
+
340
+	/**
341
+	 * @return void
342
+	 */
343
+	public function reset_expired()
344
+	{
345
+		$this->_expired = false;
346
+	}
347
+
348
+
349
+	/**
350
+	 * @return int
351
+	 */
352
+	public function expiration()
353
+	{
354
+		return $this->_expiration;
355
+	}
356
+
357
+
358
+	/**
359
+	 * @return int
360
+	 */
361
+	public function extension()
362
+	{
363
+		return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
364
+	}
365
+
366
+
367
+	/**
368
+	 * @param int $time number of seconds to add to session expiration
369
+	 */
370
+	public function extend_expiration($time = 0)
371
+	{
372
+		$time = $time ? $time : $this->extension();
373
+		$this->_expiration += absint($time);
374
+	}
375
+
376
+
377
+	/**
378
+	 * @return int
379
+	 */
380
+	public function lifespan()
381
+	{
382
+		return $this->session_lifespan->inSeconds();
383
+	}
384
+
385
+
386
+	/**
387
+	 * Marks whether the session data has been updated or not.
388
+	 * Valid options are:
389
+	 *      EE_Session::SAVE_STATE_CLEAN - session data remains unchanged and updating is not necessary
390
+	 *      EE_Session::SAVE_STATE_DIRTY - session data has changed since last save and needs to be updated
391
+	 * default value is EE_Session::SAVE_STATE_DIRTY
392
+	 *
393
+	 * @param string $save_state
394
+	 */
395
+	public function setSaveState($save_state = EE_Session::SAVE_STATE_DIRTY)
396
+	{
397
+		$valid_save_states = [
398
+			EE_Session::SAVE_STATE_CLEAN,
399
+			EE_Session::SAVE_STATE_DIRTY,
400
+		];
401
+		if (! in_array($save_state, $valid_save_states, true)) {
402
+			$save_state = EE_Session::SAVE_STATE_DIRTY;
403
+		}
404
+		$this->save_state = $save_state;
405
+	}
406
+
407
+
408
+
409
+	/**
410
+	 * This just sets some defaults for the _session data property
411
+	 *
412
+	 * @return void
413
+	 */
414
+	private function _set_defaults()
415
+	{
416
+		// set some defaults
417
+		foreach ($this->_default_session_vars as $key => $default_var) {
418
+			if (is_array($default_var)) {
419
+				$this->_session_data[ $key ] = array();
420
+			} else {
421
+				$this->_session_data[ $key ] = '';
422
+			}
423
+		}
424
+	}
425
+
426
+
427
+	/**
428
+	 * @retrieve  session data
429
+	 * @return    string
430
+	 */
431
+	public function id()
432
+	{
433
+		return $this->_sid;
434
+	}
435
+
436
+
437
+	/**
438
+	 * @param \EE_Cart $cart
439
+	 * @return bool
440
+	 */
441
+	public function set_cart(EE_Cart $cart)
442
+	{
443
+		$this->_session_data['cart'] = $cart;
444
+		$this->setSaveState();
445
+		return true;
446
+	}
447
+
448
+
449
+	/**
450
+	 * reset_cart
451
+	 */
452
+	public function reset_cart()
453
+	{
454
+		do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
455
+		$this->_session_data['cart'] = null;
456
+		$this->setSaveState();
457
+	}
458
+
459
+
460
+	/**
461
+	 * @return \EE_Cart
462
+	 */
463
+	public function cart()
464
+	{
465
+		return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
466
+			? $this->_session_data['cart']
467
+			: null;
468
+	}
469
+
470
+
471
+	/**
472
+	 * @param \EE_Checkout $checkout
473
+	 * @return bool
474
+	 */
475
+	public function set_checkout(EE_Checkout $checkout)
476
+	{
477
+		$this->_session_data['checkout'] = $checkout;
478
+		$this->setSaveState();
479
+		return true;
480
+	}
481
+
482
+
483
+	/**
484
+	 * reset_checkout
485
+	 */
486
+	public function reset_checkout()
487
+	{
488
+		do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
489
+		$this->_session_data['checkout'] = null;
490
+		$this->setSaveState();
491
+	}
492
+
493
+
494
+	/**
495
+	 * @return \EE_Checkout
496
+	 */
497
+	public function checkout()
498
+	{
499
+		return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
500
+			? $this->_session_data['checkout']
501
+			: null;
502
+	}
503
+
504
+
505
+	/**
506
+	 * @param \EE_Transaction $transaction
507
+	 * @return bool
508
+	 * @throws EE_Error
509
+	 */
510
+	public function set_transaction(EE_Transaction $transaction)
511
+	{
512
+		// first remove the session from the transaction before we save the transaction in the session
513
+		$transaction->set_txn_session_data(null);
514
+		$this->_session_data['transaction'] = $transaction;
515
+		$this->setSaveState();
516
+		return true;
517
+	}
518
+
519
+
520
+	/**
521
+	 * reset_transaction
522
+	 */
523
+	public function reset_transaction()
524
+	{
525
+		do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
526
+		$this->_session_data['transaction'] = null;
527
+		$this->setSaveState();
528
+	}
529
+
530
+
531
+	/**
532
+	 * @return \EE_Transaction
533
+	 */
534
+	public function transaction()
535
+	{
536
+		return isset($this->_session_data['transaction'])
537
+			   && $this->_session_data['transaction'] instanceof EE_Transaction
538
+			? $this->_session_data['transaction']
539
+			: null;
540
+	}
541
+
542
+
543
+	/**
544
+	 * retrieve session data
545
+	 *
546
+	 * @param null $key
547
+	 * @param bool $reset_cache
548
+	 * @return array|EE_Cart|EE_Checkout|EE_Transaction
549
+	 */
550
+	public function get_session_data($key = null, $reset_cache = false)
551
+	{
552
+		if ($reset_cache) {
553
+			$this->reset_cart();
554
+			$this->reset_checkout();
555
+			$this->reset_transaction();
556
+		}
557
+		if (! empty($key)) {
558
+			return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
559
+		}
560
+		return $this->_session_data;
561
+	}
562
+
563
+
564
+	/**
565
+	 * Returns TRUE on success, FALSE on fail
566
+	 *
567
+	 * @param array $data
568
+	 * @return bool
569
+	 */
570
+	public function set_session_data($data)
571
+	{
572
+		// nothing ??? bad data ??? go home!
573
+		if (empty($data) || ! is_array($data)) {
574
+			EE_Error::add_error(
575
+				esc_html__(
576
+					'No session data or invalid session data was provided.',
577
+					'event_espresso'
578
+				),
579
+				__FILE__,
580
+				__FUNCTION__,
581
+				__LINE__
582
+			);
583
+			return false;
584
+		}
585
+		foreach ($data as $key => $value) {
586
+			if (isset($this->_default_session_vars[ $key ])) {
587
+				EE_Error::add_error(
588
+					sprintf(
589
+						esc_html__(
590
+							'Sorry! %s is a default session datum and can not be reset.',
591
+							'event_espresso'
592
+						),
593
+						$key
594
+					),
595
+					__FILE__,
596
+					__FUNCTION__,
597
+					__LINE__
598
+				);
599
+				return false;
600
+			}
601
+			$this->_session_data[ $key ] = $value;
602
+			$this->setSaveState();
603
+		}
604
+		return true;
605
+	}
606
+
607
+
608
+	/**
609
+	 * @initiate session
610
+	 * @return bool TRUE on success, FALSE on fail
611
+	 * @throws EE_Error
612
+	 * @throws InvalidArgumentException
613
+	 * @throws InvalidDataTypeException
614
+	 * @throws InvalidInterfaceException
615
+	 * @throws InvalidSessionDataException
616
+	 * @throws RuntimeException
617
+	 * @throws ReflectionException
618
+	 */
619
+	private function _espresso_session()
620
+	{
621
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
622
+		$this->session_start_handler->startSession();
623
+		$this->status = EE_Session::STATUS_OPEN;
624
+		// get our modified session ID
625
+		$this->_sid = $this->_generate_session_id();
626
+		// and the visitors IP
627
+		$this->_ip_address = $this->request->ipAddress();
628
+		// set the "user agent"
629
+		$this->_user_agent = $this->request->userAgent();
630
+		// now let's retrieve what's in the db
631
+		$session_data = $this->_retrieve_session_data();
632
+		if (! empty($session_data)) {
633
+			// get the current time in UTC
634
+			$this->_time = $this->_time !== null ? $this->_time : time();
635
+			// and reset the session expiration
636
+			$this->_expiration = isset($session_data['expiration'])
637
+				? $session_data['expiration']
638
+				: $this->_time + $this->session_lifespan->inSeconds();
639
+		} else {
640
+			// set initial site access time and the session expiration
641
+			$this->_set_init_access_and_expiration();
642
+			// set referer
643
+			$this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr(
644
+				$this->request->getServerParam('HTTP_REFERER')
645
+			);
646
+			// no previous session = go back and create one (on top of the data above)
647
+			return false;
648
+		}
649
+		// now the user agent
650
+		if ($session_data['user_agent'] !== $this->_user_agent) {
651
+			return false;
652
+		}
653
+		// wait a minute... how old are you?
654
+		if ($this->_time > $this->_expiration) {
655
+			// yer too old fer me!
656
+			$this->_expired = true;
657
+			// wipe out everything that isn't a default session datum
658
+			$this->clear_session(__CLASS__, __FUNCTION__);
659
+		}
660
+		// make event espresso session data available to plugin
661
+		$this->_session_data = array_merge($this->_session_data, $session_data);
662
+		return true;
663
+	}
664
+
665
+
666
+	/**
667
+	 * _get_session_data
668
+	 * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
669
+	 * databases
670
+	 *
671
+	 * @return array
672
+	 * @throws EE_Error
673
+	 * @throws InvalidArgumentException
674
+	 * @throws InvalidSessionDataException
675
+	 * @throws InvalidDataTypeException
676
+	 * @throws InvalidInterfaceException
677
+	 * @throws RuntimeException
678
+	 */
679
+	protected function _retrieve_session_data()
680
+	{
681
+		$ssn_key = EE_Session::session_id_prefix . $this->_sid;
682
+		try {
683
+			// we're using WP's Transient API to store session data using the PHP session ID as the option name
684
+			$session_data = $this->cache_storage->get($ssn_key, false);
685
+			if (empty($session_data)) {
686
+				return array();
687
+			}
688
+			if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
689
+				$hash_check = $this->cache_storage->get(
690
+					EE_Session::hash_check_prefix . $this->_sid,
691
+					false
692
+				);
693
+				if ($hash_check && $hash_check !== md5($session_data)) {
694
+					EE_Error::add_error(
695
+						sprintf(
696
+							esc_html__(
697
+								'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
698
+								'event_espresso'
699
+							),
700
+							EE_Session::session_id_prefix . $this->_sid
701
+						),
702
+						__FILE__,
703
+						__FUNCTION__,
704
+						__LINE__
705
+					);
706
+				}
707
+			}
708
+		} catch (Exception $e) {
709
+			// let's just eat that error for now and attempt to correct any corrupted data
710
+			global $wpdb;
711
+			$row = $wpdb->get_row(
712
+				$wpdb->prepare(
713
+					"SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
714
+					'_transient_' . $ssn_key
715
+				)
716
+			);
717
+			$session_data = is_object($row) ? $row->option_value : null;
718
+			if ($session_data) {
719
+				$session_data = preg_replace_callback(
720
+					'!s:(d+):"(.*?)";!',
721
+					function ($match) {
722
+						return $match[1] === strlen($match[2])
723
+							? $match[0]
724
+							: 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
725
+					},
726
+					$session_data
727
+				);
728
+			}
729
+			$session_data = maybe_unserialize($session_data);
730
+		}
731
+		// in case the data is encoded... try to decode it
732
+		$session_data = $this->encryption instanceof EE_Encryption
733
+			? $this->encryption->base64_string_decode($session_data)
734
+			: $session_data;
735
+		if (! is_array($session_data)) {
736
+			try {
737
+				$session_data = maybe_unserialize($session_data);
738
+			} catch (Exception $e) {
739
+				$msg = esc_html__(
740
+					'An error occurred while attempting to unserialize the session data.',
741
+					'event_espresso'
742
+				);
743
+				$msg .= WP_DEBUG
744
+					? '<br><pre>'
745
+					  . print_r($session_data, true)
746
+					  . '</pre><br>'
747
+					  . $this->find_serialize_error($session_data)
748
+					: '';
749
+				$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
750
+				throw new InvalidSessionDataException($msg, 0, $e);
751
+			}
752
+		}
753
+		// just a check to make sure the session array is indeed an array
754
+		if (! is_array($session_data)) {
755
+			// no?!?! then something is wrong
756
+			$msg = esc_html__(
757
+				'The session data is missing, invalid, or corrupted.',
758
+				'event_espresso'
759
+			);
760
+			$msg .= WP_DEBUG
761
+				? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
762
+				: '';
763
+			$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
764
+			throw new InvalidSessionDataException($msg);
765
+		}
766
+		if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
767
+			$session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
768
+				$session_data['transaction']
769
+			);
770
+		}
771
+		return $session_data;
772
+	}
773
+
774
+
775
+	/**
776
+	 * _generate_session_id
777
+	 * Retrieves the PHP session id either directly from the PHP session,
778
+	 * or from the request array if it was passed in from an AJAX request.
779
+	 * The session id is then salted and hashed (mmm sounds tasty)
780
+	 * so that it can be safely used as a request param
781
+	 *
782
+	 * @return string
783
+	 */
784
+	protected function _generate_session_id()
785
+	{
786
+		// check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
787
+		$session_id = $this->request->requestParamIsSet('EESID')
788
+			? $this->request->getRequestParam('EESID')
789
+			: md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
790
+		return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
791
+	}
792
+
793
+
794
+	/**
795
+	 * _get_sid_salt
796
+	 *
797
+	 * @return string
798
+	 */
799
+	protected function _get_sid_salt()
800
+	{
801
+		// was session id salt already saved to db ?
802
+		if (empty($this->_sid_salt)) {
803
+			// no?  then maybe use WP defined constant
804
+			if (defined('AUTH_SALT')) {
805
+				$this->_sid_salt = AUTH_SALT;
806
+			}
807
+			// if salt doesn't exist or is too short
808
+			if (strlen($this->_sid_salt) < 32) {
809
+				// create a new one
810
+				$this->_sid_salt = wp_generate_password(64);
811
+			}
812
+			// and save it as a permanent session setting
813
+			$this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
814
+		}
815
+		return $this->_sid_salt;
816
+	}
817
+
818
+
819
+	/**
820
+	 * _set_init_access_and_expiration
821
+	 *
822
+	 * @return void
823
+	 */
824
+	protected function _set_init_access_and_expiration()
825
+	{
826
+		$this->_time = time();
827
+		$this->_expiration = $this->_time + $this->session_lifespan->inSeconds();
828
+		// set initial site access time
829
+		$this->_session_data['init_access'] = $this->_time;
830
+		// and the session expiration
831
+		$this->_session_data['expiration'] = $this->_expiration;
832
+	}
833
+
834
+
835
+	/**
836
+	 * @update session data  prior to saving to the db
837
+	 * @param bool $new_session
838
+	 * @return bool TRUE on success, FALSE on fail
839
+	 * @throws EE_Error
840
+	 * @throws InvalidArgumentException
841
+	 * @throws InvalidDataTypeException
842
+	 * @throws InvalidInterfaceException
843
+	 * @throws ReflectionException
844
+	 */
845
+	public function update($new_session = false)
846
+	{
847
+		$this->_session_data = is_array($this->_session_data) && isset($this->_session_data['id'])
848
+			? $this->_session_data
849
+			: array();
850
+		if (empty($this->_session_data)) {
851
+			$this->_set_defaults();
852
+		}
853
+		$session_data = array();
854
+		foreach ($this->_session_data as $key => $value) {
855
+			switch ($key) {
856
+				case 'id':
857
+					// session ID
858
+					$session_data['id'] = $this->_sid;
859
+					break;
860
+				case 'ip_address':
861
+					// visitor ip address
862
+					$session_data['ip_address'] = $this->request->ipAddress();
863
+					break;
864
+				case 'user_agent':
865
+					// visitor user_agent
866
+					$session_data['user_agent'] = $this->_user_agent;
867
+					break;
868
+				case 'init_access':
869
+					$session_data['init_access'] = absint($value);
870
+					break;
871
+				case 'last_access':
872
+					// current access time
873
+					$session_data['last_access'] = $this->_time;
874
+					break;
875
+				case 'expiration':
876
+					// when the session expires
877
+					$session_data['expiration'] = ! empty($this->_expiration)
878
+						? $this->_expiration
879
+						: $session_data['init_access'] + $this->session_lifespan->inSeconds();
880
+					break;
881
+				case 'user_id':
882
+					// current user if logged in
883
+					$session_data['user_id'] = $this->_wp_user_id();
884
+					break;
885
+				case 'pages_visited':
886
+					$page_visit = $this->_get_page_visit();
887
+					if ($page_visit) {
888
+						// set pages visited where the first will be the http referrer
889
+						$this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
890
+						// we'll only save the last 10 page visits.
891
+						$session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
892
+					}
893
+					break;
894
+				default:
895
+					// carry any other data over
896
+					$session_data[ $key ] = $this->_session_data[ $key ];
897
+			}
898
+		}
899
+		$this->_session_data = $session_data;
900
+		// creating a new session does not require saving to the db just yet
901
+		if (! $new_session) {
902
+			// ready? let's save
903
+			if ($this->_save_session_to_db()) {
904
+				return true;
905
+			}
906
+			return false;
907
+		}
908
+		// meh, why not?
909
+		return true;
910
+	}
911
+
912
+
913
+	/**
914
+	 * @create session data array
915
+	 * @throws EE_Error
916
+	 * @throws InvalidArgumentException
917
+	 * @throws InvalidDataTypeException
918
+	 * @throws InvalidInterfaceException
919
+	 * @throws ReflectionException
920
+	 */
921
+	private function _create_espresso_session()
922
+	{
923
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
924
+		// use the update function for now with $new_session arg set to TRUE
925
+		$this->update(true);
926
+	}
927
+
928
+	/**
929
+	 * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good
930
+	 * too). This is used when determining if we want to save the session or not.
931
+	 * @since 4.9.67.p
932
+	 * @return bool
933
+	 */
934
+	private function sessionHasStuffWorthSaving()
935
+	{
936
+		return $this->save_state === EE_Session::SAVE_STATE_DIRTY
937
+			   // we may want to eventually remove the following
938
+			   // on the assumption that the above check is enough
939
+			   || $this->cart() instanceof EE_Cart
940
+			   || (
941
+				   isset($this->_session_data['ee_notices'])
942
+				   && (
943
+					   ! empty($this->_session_data['ee_notices']['attention'])
944
+					   || ! empty($this->_session_data['ee_notices']['errors'])
945
+					   || ! empty($this->_session_data['ee_notices']['success'])
946
+				   )
947
+			   );
948
+	}
949
+
950
+
951
+	/**
952
+	 * _save_session_to_db
953
+	 *
954
+	 * @param bool $clear_session
955
+	 * @return bool
956
+	 * @throws EE_Error
957
+	 * @throws InvalidArgumentException
958
+	 * @throws InvalidDataTypeException
959
+	 * @throws InvalidInterfaceException
960
+	 * @throws ReflectionException
961
+	 */
962
+	private function _save_session_to_db($clear_session = false)
963
+	{
964
+		// don't save sessions for crawlers
965
+		// and unless we're deleting the session data, don't save anything if there isn't a cart
966
+		if (
967
+			$this->request->isBot()
968
+			|| (
969
+				! $clear_session
970
+				&& ! $this->sessionHasStuffWorthSaving()
971
+				&& apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true)
972
+			)
973
+		) {
974
+			return false;
975
+		}
976
+		$transaction = $this->transaction();
977
+		if ($transaction instanceof EE_Transaction) {
978
+			if (! $transaction->ID()) {
979
+				$transaction->save();
980
+			}
981
+			$this->_session_data['transaction'] = $transaction->ID();
982
+		}
983
+		// then serialize all of our session data
984
+		$session_data = serialize($this->_session_data);
985
+		// do we need to also encode it to avoid corrupted data when saved to the db?
986
+		$session_data = $this->_use_encryption
987
+			? $this->encryption->base64_string_encode($session_data)
988
+			: $session_data;
989
+		// maybe save hash check
990
+		if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
991
+			$this->cache_storage->add(
992
+				EE_Session::hash_check_prefix . $this->_sid,
993
+				md5($session_data),
994
+				$this->session_lifespan->inSeconds()
995
+			);
996
+		}
997
+		// we're using the Transient API for storing session data,
998
+		$saved = $this->cache_storage->add(
999
+			EE_Session::session_id_prefix . $this->_sid,
1000
+			$session_data,
1001
+			$this->session_lifespan->inSeconds()
1002
+		);
1003
+		$this->setSaveState(EE_Session::SAVE_STATE_CLEAN);
1004
+		return $saved;
1005
+	}
1006
+
1007
+
1008
+	/**
1009
+	 * @get    the full page request the visitor is accessing
1010
+	 * @return string
1011
+	 */
1012
+	public function _get_page_visit()
1013
+	{
1014
+		$page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
1015
+		// check for request url
1016
+		if ($this->request->serverParamIsSet('REQUEST_URI')) {
1017
+			$page_id = '?';
1018
+			$e_reg = '';
1019
+			$request_uri = $this->request->getServerParam('REQUEST_URI');
1020
+			$ru_bits = explode('?', $request_uri);
1021
+			$request_uri = $ru_bits[0];
1022
+			$http_host = $this->request->getServerParam('HTTP_HOST');
1023
+			// check for page_id in SERVER REQUEST
1024
+			if ($this->request->requestParamIsSet('page_id')) {
1025
+				// rebuild $e_reg without any of the extra parameters
1026
+				$page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&amp;';
1027
+			}
1028
+			// check for $e_reg in SERVER REQUEST
1029
+			if ($this->request->requestParamIsSet('ee')) {
1030
+				// rebuild $e_reg without any of the extra parameters
1031
+				$e_reg = 'ee=' . $this->request->getRequestParam('ee');
1032
+			}
1033
+			$page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?'));
1034
+		}
1035
+		return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * @the    current wp user id
1041
+	 * @return int
1042
+	 */
1043
+	public function _wp_user_id()
1044
+	{
1045
+		// if I need to explain the following lines of code, then you shouldn't be looking at this!
1046
+		$this->_wp_user_id = get_current_user_id();
1047
+		return $this->_wp_user_id;
1048
+	}
1049
+
1050
+
1051
+	/**
1052
+	 * Clear EE_Session data
1053
+	 *
1054
+	 * @param string $class
1055
+	 * @param string $function
1056
+	 * @return void
1057
+	 * @throws EE_Error
1058
+	 * @throws InvalidArgumentException
1059
+	 * @throws InvalidDataTypeException
1060
+	 * @throws InvalidInterfaceException
1061
+	 * @throws ReflectionException
1062
+	 */
1063
+	public function clear_session($class = '', $function = '')
1064
+	{
1065 1065
 //         echo '
1066 1066
 // <h3 style="color:#999;line-height:.9em;">
1067 1067
 // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/>
1068 1068
 // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b>
1069 1069
 // </h3>';
1070
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1071
-        $this->reset_cart();
1072
-        $this->reset_checkout();
1073
-        $this->reset_transaction();
1074
-        // wipe out everything that isn't a default session datum
1075
-        $this->reset_data(array_keys($this->_session_data));
1076
-        // reset initial site access time and the session expiration
1077
-        $this->_set_init_access_and_expiration();
1078
-        $this->setSaveState();
1079
-        $this->_save_session_to_db(true);
1080
-    }
1081
-
1082
-
1083
-    /**
1084
-     * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1085
-     *
1086
-     * @param array|mixed $data_to_reset
1087
-     * @param bool        $show_all_notices
1088
-     * @return bool
1089
-     */
1090
-    public function reset_data($data_to_reset = array(), $show_all_notices = false)
1091
-    {
1092
-        // if $data_to_reset is not in an array, then put it in one
1093
-        if (! is_array($data_to_reset)) {
1094
-            $data_to_reset = array($data_to_reset);
1095
-        }
1096
-        // nothing ??? go home!
1097
-        if (empty($data_to_reset)) {
1098
-            EE_Error::add_error(
1099
-                esc_html__(
1100
-                    'No session data could be reset, because no session var name was provided.',
1101
-                    'event_espresso'
1102
-                ),
1103
-                __FILE__,
1104
-                __FUNCTION__,
1105
-                __LINE__
1106
-            );
1107
-            return false;
1108
-        }
1109
-        $return_value = true;
1110
-        // since $data_to_reset is an array, cycle through the values
1111
-        foreach ($data_to_reset as $reset) {
1112
-            // first check to make sure it is a valid session var
1113
-            if (isset($this->_session_data[ $reset ])) {
1114
-                // then check to make sure it is not a default var
1115
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1116
-                    // remove session var
1117
-                    unset($this->_session_data[ $reset ]);
1118
-                    $this->setSaveState();
1119
-                    if ($show_all_notices) {
1120
-                        EE_Error::add_success(
1121
-                            sprintf(
1122
-                                esc_html__('The session variable %s was removed.', 'event_espresso'),
1123
-                                $reset
1124
-                            ),
1125
-                            __FILE__,
1126
-                            __FUNCTION__,
1127
-                            __LINE__
1128
-                        );
1129
-                    }
1130
-                } else {
1131
-                    // yeeeeeeeeerrrrrrrrrrr OUT !!!!
1132
-                    if ($show_all_notices) {
1133
-                        EE_Error::add_error(
1134
-                            sprintf(
1135
-                                esc_html__(
1136
-                                    'Sorry! %s is a default session datum and can not be reset.',
1137
-                                    'event_espresso'
1138
-                                ),
1139
-                                $reset
1140
-                            ),
1141
-                            __FILE__,
1142
-                            __FUNCTION__,
1143
-                            __LINE__
1144
-                        );
1145
-                    }
1146
-                    $return_value = false;
1147
-                }
1148
-            } elseif ($show_all_notices) {
1149
-                // oops! that session var does not exist!
1150
-                EE_Error::add_error(
1151
-                    sprintf(
1152
-                        esc_html__(
1153
-                            'The session item provided, %s, is invalid or does not exist.',
1154
-                            'event_espresso'
1155
-                        ),
1156
-                        $reset
1157
-                    ),
1158
-                    __FILE__,
1159
-                    __FUNCTION__,
1160
-                    __LINE__
1161
-                );
1162
-                $return_value = false;
1163
-            }
1164
-        } // end of foreach
1165
-        return $return_value;
1166
-    }
1167
-
1168
-
1169
-    /**
1170
-     *   wp_loaded
1171
-     *
1172
-     * @throws EE_Error
1173
-     * @throws InvalidDataTypeException
1174
-     * @throws InvalidInterfaceException
1175
-     * @throws InvalidArgumentException
1176
-     * @throws ReflectionException
1177
-     */
1178
-    public function wp_loaded()
1179
-    {
1180
-        if ($this->request->requestParamIsSet('clear_session')) {
1181
-            $this->clear_session(__CLASS__, __FUNCTION__);
1182
-        }
1183
-    }
1184
-
1185
-
1186
-    /**
1187
-     * Used to reset the entire object (for tests).
1188
-     *
1189
-     * @since 4.3.0
1190
-     * @throws EE_Error
1191
-     * @throws InvalidDataTypeException
1192
-     * @throws InvalidInterfaceException
1193
-     * @throws InvalidArgumentException
1194
-     * @throws ReflectionException
1195
-     */
1196
-    public function reset_instance()
1197
-    {
1198
-        $this->clear_session();
1199
-        self::$_instance = null;
1200
-    }
1201
-
1202
-
1203
-    public function configure_garbage_collection_filters()
1204
-    {
1205
-        // run old filter we had for controlling session cleanup
1206
-        $expired_session_transient_delete_query_limit = absint(
1207
-            apply_filters(
1208
-                'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1209
-                50
1210
-            )
1211
-        );
1212
-        // is there a value? or one that is different than the default 50 records?
1213
-        if ($expired_session_transient_delete_query_limit === 0) {
1214
-            // hook into TransientCacheStorage in case Session cleanup was turned off
1215
-            add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1216
-        } elseif ($expired_session_transient_delete_query_limit !== 50) {
1217
-            // or use that for the new transient cleanup query limit
1218
-            add_filter(
1219
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1220
-                function () use ($expired_session_transient_delete_query_limit) {
1221
-                    return $expired_session_transient_delete_query_limit;
1222
-                }
1223
-            );
1224
-        }
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1230
-     * @param $data1
1231
-     * @return string
1232
-     */
1233
-    private function find_serialize_error($data1)
1234
-    {
1235
-        $error = '<pre>';
1236
-        $data2 = preg_replace_callback(
1237
-            '!s:(\d+):"(.*?)";!',
1238
-            function ($match) {
1239
-                return ($match[1] === strlen($match[2]))
1240
-                    ? $match[0]
1241
-                    : 's:'
1242
-                      . strlen($match[2])
1243
-                      . ':"'
1244
-                      . $match[2]
1245
-                      . '";';
1246
-            },
1247
-            $data1
1248
-        );
1249
-        $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1250
-        $error .= $data1 . PHP_EOL;
1251
-        $error .= $data2 . PHP_EOL;
1252
-        for ($i = 0; $i < $max; $i++) {
1253
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1254
-                $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1255
-                $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1256
-                $error .= "\t-> Line Number = $i" . PHP_EOL;
1257
-                $start = ($i - 20);
1258
-                $start = ($start < 0) ? 0 : $start;
1259
-                $length = 40;
1260
-                $point = $max - $i;
1261
-                if ($point < 20) {
1262
-                    $rlength = 1;
1263
-                    $rpoint = -$point;
1264
-                } else {
1265
-                    $rpoint = $length - 20;
1266
-                    $rlength = 1;
1267
-                }
1268
-                $error .= "\t-> Section Data1  = ";
1269
-                $error .= substr_replace(
1270
-                    substr($data1, $start, $length),
1271
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1272
-                    $rpoint,
1273
-                    $rlength
1274
-                );
1275
-                $error .= PHP_EOL;
1276
-                $error .= "\t-> Section Data2  = ";
1277
-                $error .= substr_replace(
1278
-                    substr($data2, $start, $length),
1279
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1280
-                    $rpoint,
1281
-                    $rlength
1282
-                );
1283
-                $error .= PHP_EOL;
1284
-            }
1285
-        }
1286
-        $error .= '</pre>';
1287
-        return $error;
1288
-    }
1289
-
1290
-
1291
-    /**
1292
-     * Saves an  array of settings used for configuring aspects of session behaviour
1293
-     *
1294
-     * @param array $updated_settings
1295
-     */
1296
-    private function updateSessionSettings(array $updated_settings = array())
1297
-    {
1298
-        // add existing settings, but only if not included in incoming $updated_settings array
1299
-        $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1300
-        update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1301
-    }
1302
-
1303
-
1304
-    /**
1305
-     * garbage_collection
1306
-     */
1307
-    public function garbageCollection()
1308
-    {
1309
-        // only perform during regular requests if last garbage collection was over an hour ago
1310
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1311
-            $this->_last_gc = time();
1312
-            $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1313
-            /** @type WPDB $wpdb */
1314
-            global $wpdb;
1315
-            // filter the query limit. Set to 0 to turn off garbage collection
1316
-            $expired_session_transient_delete_query_limit = absint(
1317
-                apply_filters(
1318
-                    'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1319
-                    50
1320
-                )
1321
-            );
1322
-            // non-zero LIMIT means take out the trash
1323
-            if ($expired_session_transient_delete_query_limit) {
1324
-                $session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1325
-                $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1326
-                // since transient expiration timestamps are set in the future, we can compare against NOW
1327
-                // but we only want to pick up any trash that's been around for more than a day
1328
-                $expiration = time() - DAY_IN_SECONDS;
1329
-                $SQL = "
1070
+		do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
1071
+		$this->reset_cart();
1072
+		$this->reset_checkout();
1073
+		$this->reset_transaction();
1074
+		// wipe out everything that isn't a default session datum
1075
+		$this->reset_data(array_keys($this->_session_data));
1076
+		// reset initial site access time and the session expiration
1077
+		$this->_set_init_access_and_expiration();
1078
+		$this->setSaveState();
1079
+		$this->_save_session_to_db(true);
1080
+	}
1081
+
1082
+
1083
+	/**
1084
+	 * resets all non-default session vars. Returns TRUE on success, FALSE on fail
1085
+	 *
1086
+	 * @param array|mixed $data_to_reset
1087
+	 * @param bool        $show_all_notices
1088
+	 * @return bool
1089
+	 */
1090
+	public function reset_data($data_to_reset = array(), $show_all_notices = false)
1091
+	{
1092
+		// if $data_to_reset is not in an array, then put it in one
1093
+		if (! is_array($data_to_reset)) {
1094
+			$data_to_reset = array($data_to_reset);
1095
+		}
1096
+		// nothing ??? go home!
1097
+		if (empty($data_to_reset)) {
1098
+			EE_Error::add_error(
1099
+				esc_html__(
1100
+					'No session data could be reset, because no session var name was provided.',
1101
+					'event_espresso'
1102
+				),
1103
+				__FILE__,
1104
+				__FUNCTION__,
1105
+				__LINE__
1106
+			);
1107
+			return false;
1108
+		}
1109
+		$return_value = true;
1110
+		// since $data_to_reset is an array, cycle through the values
1111
+		foreach ($data_to_reset as $reset) {
1112
+			// first check to make sure it is a valid session var
1113
+			if (isset($this->_session_data[ $reset ])) {
1114
+				// then check to make sure it is not a default var
1115
+				if (! array_key_exists($reset, $this->_default_session_vars)) {
1116
+					// remove session var
1117
+					unset($this->_session_data[ $reset ]);
1118
+					$this->setSaveState();
1119
+					if ($show_all_notices) {
1120
+						EE_Error::add_success(
1121
+							sprintf(
1122
+								esc_html__('The session variable %s was removed.', 'event_espresso'),
1123
+								$reset
1124
+							),
1125
+							__FILE__,
1126
+							__FUNCTION__,
1127
+							__LINE__
1128
+						);
1129
+					}
1130
+				} else {
1131
+					// yeeeeeeeeerrrrrrrrrrr OUT !!!!
1132
+					if ($show_all_notices) {
1133
+						EE_Error::add_error(
1134
+							sprintf(
1135
+								esc_html__(
1136
+									'Sorry! %s is a default session datum and can not be reset.',
1137
+									'event_espresso'
1138
+								),
1139
+								$reset
1140
+							),
1141
+							__FILE__,
1142
+							__FUNCTION__,
1143
+							__LINE__
1144
+						);
1145
+					}
1146
+					$return_value = false;
1147
+				}
1148
+			} elseif ($show_all_notices) {
1149
+				// oops! that session var does not exist!
1150
+				EE_Error::add_error(
1151
+					sprintf(
1152
+						esc_html__(
1153
+							'The session item provided, %s, is invalid or does not exist.',
1154
+							'event_espresso'
1155
+						),
1156
+						$reset
1157
+					),
1158
+					__FILE__,
1159
+					__FUNCTION__,
1160
+					__LINE__
1161
+				);
1162
+				$return_value = false;
1163
+			}
1164
+		} // end of foreach
1165
+		return $return_value;
1166
+	}
1167
+
1168
+
1169
+	/**
1170
+	 *   wp_loaded
1171
+	 *
1172
+	 * @throws EE_Error
1173
+	 * @throws InvalidDataTypeException
1174
+	 * @throws InvalidInterfaceException
1175
+	 * @throws InvalidArgumentException
1176
+	 * @throws ReflectionException
1177
+	 */
1178
+	public function wp_loaded()
1179
+	{
1180
+		if ($this->request->requestParamIsSet('clear_session')) {
1181
+			$this->clear_session(__CLASS__, __FUNCTION__);
1182
+		}
1183
+	}
1184
+
1185
+
1186
+	/**
1187
+	 * Used to reset the entire object (for tests).
1188
+	 *
1189
+	 * @since 4.3.0
1190
+	 * @throws EE_Error
1191
+	 * @throws InvalidDataTypeException
1192
+	 * @throws InvalidInterfaceException
1193
+	 * @throws InvalidArgumentException
1194
+	 * @throws ReflectionException
1195
+	 */
1196
+	public function reset_instance()
1197
+	{
1198
+		$this->clear_session();
1199
+		self::$_instance = null;
1200
+	}
1201
+
1202
+
1203
+	public function configure_garbage_collection_filters()
1204
+	{
1205
+		// run old filter we had for controlling session cleanup
1206
+		$expired_session_transient_delete_query_limit = absint(
1207
+			apply_filters(
1208
+				'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1209
+				50
1210
+			)
1211
+		);
1212
+		// is there a value? or one that is different than the default 50 records?
1213
+		if ($expired_session_transient_delete_query_limit === 0) {
1214
+			// hook into TransientCacheStorage in case Session cleanup was turned off
1215
+			add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1216
+		} elseif ($expired_session_transient_delete_query_limit !== 50) {
1217
+			// or use that for the new transient cleanup query limit
1218
+			add_filter(
1219
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1220
+				function () use ($expired_session_transient_delete_query_limit) {
1221
+					return $expired_session_transient_delete_query_limit;
1222
+				}
1223
+			);
1224
+		}
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1230
+	 * @param $data1
1231
+	 * @return string
1232
+	 */
1233
+	private function find_serialize_error($data1)
1234
+	{
1235
+		$error = '<pre>';
1236
+		$data2 = preg_replace_callback(
1237
+			'!s:(\d+):"(.*?)";!',
1238
+			function ($match) {
1239
+				return ($match[1] === strlen($match[2]))
1240
+					? $match[0]
1241
+					: 's:'
1242
+					  . strlen($match[2])
1243
+					  . ':"'
1244
+					  . $match[2]
1245
+					  . '";';
1246
+			},
1247
+			$data1
1248
+		);
1249
+		$max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1250
+		$error .= $data1 . PHP_EOL;
1251
+		$error .= $data2 . PHP_EOL;
1252
+		for ($i = 0; $i < $max; $i++) {
1253
+			if (@$data1[ $i ] !== @$data2[ $i ]) {
1254
+				$error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1255
+				$error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1256
+				$error .= "\t-> Line Number = $i" . PHP_EOL;
1257
+				$start = ($i - 20);
1258
+				$start = ($start < 0) ? 0 : $start;
1259
+				$length = 40;
1260
+				$point = $max - $i;
1261
+				if ($point < 20) {
1262
+					$rlength = 1;
1263
+					$rpoint = -$point;
1264
+				} else {
1265
+					$rpoint = $length - 20;
1266
+					$rlength = 1;
1267
+				}
1268
+				$error .= "\t-> Section Data1  = ";
1269
+				$error .= substr_replace(
1270
+					substr($data1, $start, $length),
1271
+					"<b style=\"color:green\">{$data1[ $i ]}</b>",
1272
+					$rpoint,
1273
+					$rlength
1274
+				);
1275
+				$error .= PHP_EOL;
1276
+				$error .= "\t-> Section Data2  = ";
1277
+				$error .= substr_replace(
1278
+					substr($data2, $start, $length),
1279
+					"<b style=\"color:red\">{$data2[ $i ]}</b>",
1280
+					$rpoint,
1281
+					$rlength
1282
+				);
1283
+				$error .= PHP_EOL;
1284
+			}
1285
+		}
1286
+		$error .= '</pre>';
1287
+		return $error;
1288
+	}
1289
+
1290
+
1291
+	/**
1292
+	 * Saves an  array of settings used for configuring aspects of session behaviour
1293
+	 *
1294
+	 * @param array $updated_settings
1295
+	 */
1296
+	private function updateSessionSettings(array $updated_settings = array())
1297
+	{
1298
+		// add existing settings, but only if not included in incoming $updated_settings array
1299
+		$updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1300
+		update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1301
+	}
1302
+
1303
+
1304
+	/**
1305
+	 * garbage_collection
1306
+	 */
1307
+	public function garbageCollection()
1308
+	{
1309
+		// only perform during regular requests if last garbage collection was over an hour ago
1310
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1311
+			$this->_last_gc = time();
1312
+			$this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1313
+			/** @type WPDB $wpdb */
1314
+			global $wpdb;
1315
+			// filter the query limit. Set to 0 to turn off garbage collection
1316
+			$expired_session_transient_delete_query_limit = absint(
1317
+				apply_filters(
1318
+					'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1319
+					50
1320
+				)
1321
+			);
1322
+			// non-zero LIMIT means take out the trash
1323
+			if ($expired_session_transient_delete_query_limit) {
1324
+				$session_key = str_replace('_', '\_', EE_Session::session_id_prefix);
1325
+				$hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1326
+				// since transient expiration timestamps are set in the future, we can compare against NOW
1327
+				// but we only want to pick up any trash that's been around for more than a day
1328
+				$expiration = time() - DAY_IN_SECONDS;
1329
+				$SQL = "
1330 1330
                     SELECT option_name
1331 1331
                     FROM {$wpdb->options}
1332 1332
                     WHERE
@@ -1335,17 +1335,17 @@  discard block
 block discarded – undo
1335 1335
                     AND option_value < {$expiration}
1336 1336
                     LIMIT {$expired_session_transient_delete_query_limit}
1337 1337
                 ";
1338
-                // produces something like:
1339
-                // SELECT option_name FROM wp_options
1340
-                // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1341
-                // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1342
-                // AND option_value < 1508368198 LIMIT 50
1343
-                $expired_sessions = $wpdb->get_col($SQL);
1344
-                // valid results?
1345
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1346
-                    $this->cache_storage->deleteMany($expired_sessions, true);
1347
-                }
1348
-            }
1349
-        }
1350
-    }
1338
+				// produces something like:
1339
+				// SELECT option_name FROM wp_options
1340
+				// WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1341
+				// OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1342
+				// AND option_value < 1508368198 LIMIT 50
1343
+				$expired_sessions = $wpdb->get_col($SQL);
1344
+				// valid results?
1345
+				if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1346
+					$this->cache_storage->deleteMany($expired_sessions, true);
1347
+				}
1348
+			}
1349
+		}
1350
+	}
1351 1351
 }
Please login to merge, or discard this patch.
core/services/orm/tree_traversal/ModelObjNode.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
                 continue;
70 70
             }
71 71
             if ($relation instanceof EE_Has_Many_Relation) {
72
-                $this->nodes[ $relationName ] = new RelationNode(
72
+                $this->nodes[$relationName] = new RelationNode(
73 73
                     $this->id,
74 74
                     $this->model,
75 75
                     $relation->get_other_model(),
@@ -82,7 +82,7 @@  discard block
 block discarded – undo
82 82
                     $this->dont_traverse_models
83 83
                 )
84 84
             ) {
85
-                $this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode(
85
+                $this->nodes[$relation->get_join_model()->get_this_model_name()] = new RelationNode(
86 86
                     $this->id,
87 87
                     $this->model,
88 88
                     $relation->get_join_model(),
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
             // To save on space when serializing, only bother keeping a record of relation nodes that actually found
131 131
             // related model objects.
132 132
             if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) {
133
-                unset($this->nodes[ $model_name ]);
133
+                unset($this->nodes[$model_name]);
134 134
             }
135 135
             if ($num_identified >= $model_objects_to_identify) {
136 136
                 // ...but admit we're wrong if the work exceeded the budget.
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
             $tree['rels'] = null;
162 162
         } else {
163 163
             foreach ($this->nodes as $relation_name => $relation_node) {
164
-                $tree['rels'][ $relation_name ] = $relation_node->toArray();
164
+                $tree['rels'][$relation_name] = $relation_node->toArray();
165 165
             }
166 166
         }
167 167
         return $tree;
Please login to merge, or discard this patch.
Indentation   +212 added lines, -212 removed lines patch added patch discarded remove patch
@@ -23,218 +23,218 @@
 block discarded – undo
23 23
  */
24 24
 class ModelObjNode extends BaseNode
25 25
 {
26
-    /**
27
-     * @var int|string
28
-     */
29
-    protected $id;
30
-
31
-    /**
32
-     * @var EEM_Base
33
-     */
34
-    protected $model;
35
-
36
-    /**
37
-     * @var RelationNode[]
38
-     */
39
-    protected $nodes;
40
-
41
-
42
-    /**
43
-     * We don't pass the model objects because this needs to serialize to something tiny for effiency.
44
-     *
45
-     * @param          $model_obj_id
46
-     * @param EEM_Base $model
47
-     * @param array    $dont_traverse_models array of model names we DON'T want to traverse.
48
-     */
49
-    public function __construct($model_obj_id, EEM_Base $model, array $dont_traverse_models = [])
50
-    {
51
-        $this->id                   = $model_obj_id;
52
-        $this->model                = $model;
53
-        $this->dont_traverse_models = $dont_traverse_models;
54
-    }
55
-
56
-
57
-    /**
58
-     * Creates a relation node for each relation of this model's relations.
59
-     * Does NOT call `discover` on them yet though.
60
-     *
61
-     * @throws EE_Error
62
-     * @throws InvalidDataTypeException
63
-     * @throws InvalidInterfaceException
64
-     * @throws InvalidArgumentException
65
-     * @throws ReflectionException
66
-     * @since 4.10.12.p
67
-     */
68
-    protected function discover()
69
-    {
70
-        $this->nodes = [];
71
-        foreach ($this->model->relation_settings() as $relationName => $relation) {
72
-            // Make sure this isn't one of the models we were told to not traverse into.
73
-            if (in_array($relationName, $this->dont_traverse_models)) {
74
-                continue;
75
-            }
76
-            if ($relation instanceof EE_Has_Many_Relation) {
77
-                $this->nodes[ $relationName ] = new RelationNode(
78
-                    $this->id,
79
-                    $this->model,
80
-                    $relation->get_other_model(),
81
-                    $this->dont_traverse_models
82
-                );
83
-            } elseif (
84
-                $relation instanceof EE_HABTM_Relation &&
85
-                ! in_array(
86
-                    $relation->get_join_model()->get_this_model_name(),
87
-                    $this->dont_traverse_models
88
-                )
89
-            ) {
90
-                $this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode(
91
-                    $this->id,
92
-                    $this->model,
93
-                    $relation->get_join_model(),
94
-                    $this->dont_traverse_models
95
-                );
96
-            }
97
-        }
98
-        ksort($this->nodes);
99
-    }
100
-
101
-
102
-    /**
103
-     * Whether this item has already been initialized
104
-     */
105
-    protected function isDiscovered()
106
-    {
107
-        return $this->nodes !== null && is_array($this->nodes);
108
-    }
109
-
110
-    /**
111
-     * @since 4.10.12.p
112
-     * @return boolean
113
-     */
114
-    public function isComplete()
115
-    {
116
-        if ($this->complete === null) {
117
-            $this->complete = false;
118
-        }
119
-        return $this->complete;
120
-    }
121
-
122
-
123
-    /**
124
-     * Triggers working on each child relation node that has work to do.
125
-     *
126
-     * @param $model_objects_to_identify
127
-     * @return int units of work done
128
-     * @since 4.10.12.p
129
-     */
130
-    protected function work($model_objects_to_identify)
131
-    {
132
-        $num_identified = 0;
133
-        // Begin assuming we'll finish all the work on this node and its children...
134
-        $this->complete = true;
135
-        foreach ($this->nodes as $model_name => $relation_node) {
136
-            $num_identified += $relation_node->visit($model_objects_to_identify - $num_identified);
137
-            // To save on space when serializing, only bother keeping a record of relation nodes that actually found
138
-            // related model objects.
139
-            if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) {
140
-                unset($this->nodes[ $model_name ]);
141
-            }
142
-            if ($num_identified >= $model_objects_to_identify) {
143
-                // ...but admit we're wrong if the work exceeded the budget.
144
-                $this->complete = false;
145
-                break;
146
-            }
147
-        }
148
-        return $num_identified;
149
-    }
150
-
151
-
152
-    /**
153
-     * @return array
154
-     * @throws EE_Error
155
-     * @throws InvalidDataTypeException
156
-     * @throws InvalidInterfaceException
157
-     * @throws InvalidArgumentException
158
-     * @throws ReflectionException
159
-     * @since 4.10.12.p
160
-     */
161
-    public function toArray()
162
-    {
163
-        $tree = [
164
-            'id'       => $this->id,
165
-            'complete' => $this->isComplete(),
166
-            'rels'     => [],
167
-        ];
168
-        if ($this->nodes === null) {
169
-            $tree['rels'] = null;
170
-        } else {
171
-            foreach ($this->nodes as $relation_name => $relation_node) {
172
-                $tree['rels'][ $relation_name ] = $relation_node->toArray();
173
-            }
174
-        }
175
-        return $tree;
176
-    }
177
-
178
-
179
-    /**
180
-     * @return array|mixed
181
-     * @throws InvalidArgumentException
182
-     * @throws InvalidDataTypeException
183
-     * @throws InvalidInterfaceException
184
-     * @throws ReflectionException
185
-     * @throws EE_Error
186
-     * @since 4.10.12.p
187
-     */
188
-    public function getIds()
189
-    {
190
-        $ids = [
191
-            $this->model->get_this_model_name() => [
192
-                $this->id => $this->id,
193
-            ],
194
-        ];
195
-        if ($this->nodes && is_array($this->nodes)) {
196
-            foreach ($this->nodes as $relation_node) {
197
-                $ids = array_replace_recursive($ids, $relation_node->getIds());
198
-            }
199
-        }
200
-        return $ids;
201
-    }
202
-
203
-
204
-    /**
205
-     * Don't serialize the models. Just record their names on some dynamic properties.
206
-     *
207
-     * @since 4.10.12.p
208
-     */
209
-    public function __sleep()
210
-    {
211
-        $this->m = $this->model->get_this_model_name();
212
-        return array_merge(
213
-            [
214
-                'm',
215
-                'id',
216
-                'nodes',
217
-            ],
218
-            parent::__sleep()
219
-        );
220
-    }
221
-
222
-
223
-    /**
224
-     * Use the dynamic properties to instantiate the models we use.
225
-     *
226
-     * @throws EE_Error
227
-     * @throws InvalidArgumentException
228
-     * @throws InvalidDataTypeException
229
-     * @throws InvalidInterfaceException
230
-     * @throws ReflectionException
231
-     * @since 4.10.12.p
232
-     */
233
-    public function __wakeup()
234
-    {
235
-        $this->model = EE_Registry::instance()->load_model($this->m);
236
-        parent::__wakeup();
237
-    }
26
+	/**
27
+	 * @var int|string
28
+	 */
29
+	protected $id;
30
+
31
+	/**
32
+	 * @var EEM_Base
33
+	 */
34
+	protected $model;
35
+
36
+	/**
37
+	 * @var RelationNode[]
38
+	 */
39
+	protected $nodes;
40
+
41
+
42
+	/**
43
+	 * We don't pass the model objects because this needs to serialize to something tiny for effiency.
44
+	 *
45
+	 * @param          $model_obj_id
46
+	 * @param EEM_Base $model
47
+	 * @param array    $dont_traverse_models array of model names we DON'T want to traverse.
48
+	 */
49
+	public function __construct($model_obj_id, EEM_Base $model, array $dont_traverse_models = [])
50
+	{
51
+		$this->id                   = $model_obj_id;
52
+		$this->model                = $model;
53
+		$this->dont_traverse_models = $dont_traverse_models;
54
+	}
55
+
56
+
57
+	/**
58
+	 * Creates a relation node for each relation of this model's relations.
59
+	 * Does NOT call `discover` on them yet though.
60
+	 *
61
+	 * @throws EE_Error
62
+	 * @throws InvalidDataTypeException
63
+	 * @throws InvalidInterfaceException
64
+	 * @throws InvalidArgumentException
65
+	 * @throws ReflectionException
66
+	 * @since 4.10.12.p
67
+	 */
68
+	protected function discover()
69
+	{
70
+		$this->nodes = [];
71
+		foreach ($this->model->relation_settings() as $relationName => $relation) {
72
+			// Make sure this isn't one of the models we were told to not traverse into.
73
+			if (in_array($relationName, $this->dont_traverse_models)) {
74
+				continue;
75
+			}
76
+			if ($relation instanceof EE_Has_Many_Relation) {
77
+				$this->nodes[ $relationName ] = new RelationNode(
78
+					$this->id,
79
+					$this->model,
80
+					$relation->get_other_model(),
81
+					$this->dont_traverse_models
82
+				);
83
+			} elseif (
84
+				$relation instanceof EE_HABTM_Relation &&
85
+				! in_array(
86
+					$relation->get_join_model()->get_this_model_name(),
87
+					$this->dont_traverse_models
88
+				)
89
+			) {
90
+				$this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode(
91
+					$this->id,
92
+					$this->model,
93
+					$relation->get_join_model(),
94
+					$this->dont_traverse_models
95
+				);
96
+			}
97
+		}
98
+		ksort($this->nodes);
99
+	}
100
+
101
+
102
+	/**
103
+	 * Whether this item has already been initialized
104
+	 */
105
+	protected function isDiscovered()
106
+	{
107
+		return $this->nodes !== null && is_array($this->nodes);
108
+	}
109
+
110
+	/**
111
+	 * @since 4.10.12.p
112
+	 * @return boolean
113
+	 */
114
+	public function isComplete()
115
+	{
116
+		if ($this->complete === null) {
117
+			$this->complete = false;
118
+		}
119
+		return $this->complete;
120
+	}
121
+
122
+
123
+	/**
124
+	 * Triggers working on each child relation node that has work to do.
125
+	 *
126
+	 * @param $model_objects_to_identify
127
+	 * @return int units of work done
128
+	 * @since 4.10.12.p
129
+	 */
130
+	protected function work($model_objects_to_identify)
131
+	{
132
+		$num_identified = 0;
133
+		// Begin assuming we'll finish all the work on this node and its children...
134
+		$this->complete = true;
135
+		foreach ($this->nodes as $model_name => $relation_node) {
136
+			$num_identified += $relation_node->visit($model_objects_to_identify - $num_identified);
137
+			// To save on space when serializing, only bother keeping a record of relation nodes that actually found
138
+			// related model objects.
139
+			if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) {
140
+				unset($this->nodes[ $model_name ]);
141
+			}
142
+			if ($num_identified >= $model_objects_to_identify) {
143
+				// ...but admit we're wrong if the work exceeded the budget.
144
+				$this->complete = false;
145
+				break;
146
+			}
147
+		}
148
+		return $num_identified;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @return array
154
+	 * @throws EE_Error
155
+	 * @throws InvalidDataTypeException
156
+	 * @throws InvalidInterfaceException
157
+	 * @throws InvalidArgumentException
158
+	 * @throws ReflectionException
159
+	 * @since 4.10.12.p
160
+	 */
161
+	public function toArray()
162
+	{
163
+		$tree = [
164
+			'id'       => $this->id,
165
+			'complete' => $this->isComplete(),
166
+			'rels'     => [],
167
+		];
168
+		if ($this->nodes === null) {
169
+			$tree['rels'] = null;
170
+		} else {
171
+			foreach ($this->nodes as $relation_name => $relation_node) {
172
+				$tree['rels'][ $relation_name ] = $relation_node->toArray();
173
+			}
174
+		}
175
+		return $tree;
176
+	}
177
+
178
+
179
+	/**
180
+	 * @return array|mixed
181
+	 * @throws InvalidArgumentException
182
+	 * @throws InvalidDataTypeException
183
+	 * @throws InvalidInterfaceException
184
+	 * @throws ReflectionException
185
+	 * @throws EE_Error
186
+	 * @since 4.10.12.p
187
+	 */
188
+	public function getIds()
189
+	{
190
+		$ids = [
191
+			$this->model->get_this_model_name() => [
192
+				$this->id => $this->id,
193
+			],
194
+		];
195
+		if ($this->nodes && is_array($this->nodes)) {
196
+			foreach ($this->nodes as $relation_node) {
197
+				$ids = array_replace_recursive($ids, $relation_node->getIds());
198
+			}
199
+		}
200
+		return $ids;
201
+	}
202
+
203
+
204
+	/**
205
+	 * Don't serialize the models. Just record their names on some dynamic properties.
206
+	 *
207
+	 * @since 4.10.12.p
208
+	 */
209
+	public function __sleep()
210
+	{
211
+		$this->m = $this->model->get_this_model_name();
212
+		return array_merge(
213
+			[
214
+				'm',
215
+				'id',
216
+				'nodes',
217
+			],
218
+			parent::__sleep()
219
+		);
220
+	}
221
+
222
+
223
+	/**
224
+	 * Use the dynamic properties to instantiate the models we use.
225
+	 *
226
+	 * @throws EE_Error
227
+	 * @throws InvalidArgumentException
228
+	 * @throws InvalidDataTypeException
229
+	 * @throws InvalidInterfaceException
230
+	 * @throws ReflectionException
231
+	 * @since 4.10.12.p
232
+	 */
233
+	public function __wakeup()
234
+	{
235
+		$this->model = EE_Registry::instance()->load_model($this->m);
236
+		parent::__wakeup();
237
+	}
238 238
 }
239 239
 // End of file Visitor.php
240 240
 // Location: EventEspresso\core\services\orm\tree_traversal/Visitor.php
Please login to merge, or discard this patch.
core/EED_Module.module.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
     protected static function getRequest()
134 134
     {
135 135
         static $request;
136
-        if (! $request instanceof RequestInterface) {
136
+        if ( ! $request instanceof RequestInterface) {
137 137
             $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
138 138
         }
139 139
         return $request;
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
     protected static function getResponse()
148 148
     {
149 149
         static $response;
150
-        if (! $response instanceof RequestInterface) {
150
+        if ( ! $response instanceof RequestInterface) {
151 151
             $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
152 152
         }
153 153
         return $response;
Please login to merge, or discard this patch.
Indentation   +137 added lines, -137 removed lines patch added patch discarded remove patch
@@ -14,141 +14,141 @@
 block discarded – undo
14 14
  */
15 15
 abstract class EED_Module extends EE_Configurable implements ResettableInterface
16 16
 {
17
-    /**
18
-     * rendered output to be returned to WP
19
-     *
20
-     * @var    string $output
21
-     */
22
-    protected $output = '';
23
-
24
-    /**
25
-     * the current active espresso template theme
26
-     *
27
-     * @var    string $theme
28
-     */
29
-    protected $theme = '';
30
-
31
-
32
-    /**
33
-     * @return void
34
-     */
35
-    public static function reset()
36
-    {
37
-        $module_name = get_called_class();
38
-        new $module_name();
39
-    }
40
-
41
-
42
-    /**
43
-     *    set_hooks - for hooking into EE Core, other modules, etc
44
-     *
45
-     * @access    public
46
-     * @return    void
47
-     */
48
-    public static function set_hooks()
49
-    {
50
-    }
51
-
52
-
53
-    /**
54
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
55
-     *
56
-     * @access    public
57
-     * @return    void
58
-     */
59
-    public static function set_hooks_admin()
60
-    {
61
-    }
62
-
63
-
64
-    /**
65
-     *    run - initial module setup
66
-     *    this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
67
-     *
68
-     * @access    public
69
-     * @var            WP $WP
70
-     * @return    void
71
-     */
72
-    abstract public function run($WP);
73
-
74
-
75
-    /**
76
-     * EED_Module constructor.
77
-     */
78
-    final public function __construct()
79
-    {
80
-        $this->theme = EE_Config::get_current_theme();
81
-        $module_name = $this->module_name();
82
-        EE_Registry::instance()->modules->{$module_name} = $this;
83
-    }
84
-
85
-
86
-    /**
87
-     * @param string $module_name
88
-     * @return EED_Module|mixed
89
-     * @throws EE_Error
90
-     * @throws ReflectionException
91
-     */
92
-    protected static function get_instance($module_name = '')
93
-    {
94
-        $module_name = ! empty($module_name)
95
-            ? $module_name
96
-            : get_called_class();
97
-        if (
98
-            ! isset(EE_Registry::instance()->modules->{$module_name})
99
-            || ! EE_Registry::instance()->modules->{$module_name} instanceof EED_Module
100
-        ) {
101
-            EE_Registry::instance()->add_module($module_name);
102
-        }
103
-        return EE_Registry::instance()->get_module($module_name);
104
-    }
105
-
106
-
107
-    /**
108
-     *    module_name
109
-     *
110
-     * @access    public
111
-     * @return    string
112
-     */
113
-    public function module_name()
114
-    {
115
-        return get_class($this);
116
-    }
117
-
118
-
119
-    /**
120
-     * @return string
121
-     */
122
-    public function theme()
123
-    {
124
-        return $this->theme;
125
-    }
126
-
127
-
128
-    /**
129
-     * @return RequestInterface
130
-     * @since   4.10.14.p
131
-     */
132
-    protected static function getRequest()
133
-    {
134
-        static $request;
135
-        if (! $request instanceof RequestInterface) {
136
-            $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
137
-        }
138
-        return $request;
139
-    }
140
-
141
-
142
-    /**
143
-     * @return ResponseInterface
144
-     * @since   4.10.14.p
145
-     */
146
-    protected static function getResponse()
147
-    {
148
-        static $response;
149
-        if (! $response instanceof RequestInterface) {
150
-            $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
151
-        }
152
-        return $response;
153
-    }
17
+	/**
18
+	 * rendered output to be returned to WP
19
+	 *
20
+	 * @var    string $output
21
+	 */
22
+	protected $output = '';
23
+
24
+	/**
25
+	 * the current active espresso template theme
26
+	 *
27
+	 * @var    string $theme
28
+	 */
29
+	protected $theme = '';
30
+
31
+
32
+	/**
33
+	 * @return void
34
+	 */
35
+	public static function reset()
36
+	{
37
+		$module_name = get_called_class();
38
+		new $module_name();
39
+	}
40
+
41
+
42
+	/**
43
+	 *    set_hooks - for hooking into EE Core, other modules, etc
44
+	 *
45
+	 * @access    public
46
+	 * @return    void
47
+	 */
48
+	public static function set_hooks()
49
+	{
50
+	}
51
+
52
+
53
+	/**
54
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
55
+	 *
56
+	 * @access    public
57
+	 * @return    void
58
+	 */
59
+	public static function set_hooks_admin()
60
+	{
61
+	}
62
+
63
+
64
+	/**
65
+	 *    run - initial module setup
66
+	 *    this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
67
+	 *
68
+	 * @access    public
69
+	 * @var            WP $WP
70
+	 * @return    void
71
+	 */
72
+	abstract public function run($WP);
73
+
74
+
75
+	/**
76
+	 * EED_Module constructor.
77
+	 */
78
+	final public function __construct()
79
+	{
80
+		$this->theme = EE_Config::get_current_theme();
81
+		$module_name = $this->module_name();
82
+		EE_Registry::instance()->modules->{$module_name} = $this;
83
+	}
84
+
85
+
86
+	/**
87
+	 * @param string $module_name
88
+	 * @return EED_Module|mixed
89
+	 * @throws EE_Error
90
+	 * @throws ReflectionException
91
+	 */
92
+	protected static function get_instance($module_name = '')
93
+	{
94
+		$module_name = ! empty($module_name)
95
+			? $module_name
96
+			: get_called_class();
97
+		if (
98
+			! isset(EE_Registry::instance()->modules->{$module_name})
99
+			|| ! EE_Registry::instance()->modules->{$module_name} instanceof EED_Module
100
+		) {
101
+			EE_Registry::instance()->add_module($module_name);
102
+		}
103
+		return EE_Registry::instance()->get_module($module_name);
104
+	}
105
+
106
+
107
+	/**
108
+	 *    module_name
109
+	 *
110
+	 * @access    public
111
+	 * @return    string
112
+	 */
113
+	public function module_name()
114
+	{
115
+		return get_class($this);
116
+	}
117
+
118
+
119
+	/**
120
+	 * @return string
121
+	 */
122
+	public function theme()
123
+	{
124
+		return $this->theme;
125
+	}
126
+
127
+
128
+	/**
129
+	 * @return RequestInterface
130
+	 * @since   4.10.14.p
131
+	 */
132
+	protected static function getRequest()
133
+	{
134
+		static $request;
135
+		if (! $request instanceof RequestInterface) {
136
+			$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
137
+		}
138
+		return $request;
139
+	}
140
+
141
+
142
+	/**
143
+	 * @return ResponseInterface
144
+	 * @since   4.10.14.p
145
+	 */
146
+	protected static function getResponse()
147
+	{
148
+		static $response;
149
+		if (! $response instanceof RequestInterface) {
150
+			$response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
151
+		}
152
+		return $response;
153
+	}
154 154
 }
Please login to merge, or discard this patch.
caffeinated/core/libraries/shortcodes/EE_Question_List_Shortcodes.lib.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -94,16 +94,16 @@
 block discarded – undo
94 94
             ? $this->_extra_data['template']['question_list']
95 95
             : $template;
96 96
         $ans_result       = '';
97
-        $answers          = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'])
98
-            ? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']
97
+        $answers          = ! empty($this->_extra_data['data']->registrations[$reg_obj->ID()]['ans_objs'])
98
+            ? $this->_extra_data['data']->registrations[$reg_obj->ID()]['ans_objs']
99 99
             : [];
100 100
         $questions        = ! empty($this->_extra_data['data']->questions)
101 101
             ? $this->_extra_data['data']->questions
102 102
             : [];
103 103
         foreach ($answers as $answer) {
104 104
             // first see if the question is in our $questions array.  If not then try to get from answer object
105
-            $question = isset($questions[ $answer->ID() ])
106
-                ? $questions[ $answer->ID() ]
105
+            $question = isset($questions[$answer->ID()])
106
+                ? $questions[$answer->ID()]
107 107
                 : null;
108 108
             $question = ! $question instanceof EE_Question
109 109
                 ? $answer->question()
Please login to merge, or discard this patch.
Indentation   +98 added lines, -98 removed lines patch added patch discarded remove patch
@@ -15,113 +15,113 @@
 block discarded – undo
15 15
  */
16 16
 class EE_Question_List_Shortcodes extends EE_Shortcodes
17 17
 {
18
-    public function __construct()
19
-    {
20
-        parent::__construct();
21
-    }
18
+	public function __construct()
19
+	{
20
+		parent::__construct();
21
+	}
22 22
 
23 23
 
24
-    protected function _init_props()
25
-    {
26
-        $this->label       = esc_html__('Questions and Answers Shortcodes', 'event_espresso');
27
-        $this->description = esc_html__('All shortcodes related to custom questions and answers', 'event_espresso');
28
-        $this->_shortcodes = [
29
-            '[QUESTION_LIST]' => esc_html__(
30
-                'This is used to indicate where you want the list of questions and answers to show for the registrant.  You place this within the "[attendee_list]" field.',
31
-                'event_espresso'
32
-            ),
33
-        ];
34
-    }
24
+	protected function _init_props()
25
+	{
26
+		$this->label       = esc_html__('Questions and Answers Shortcodes', 'event_espresso');
27
+		$this->description = esc_html__('All shortcodes related to custom questions and answers', 'event_espresso');
28
+		$this->_shortcodes = [
29
+			'[QUESTION_LIST]' => esc_html__(
30
+				'This is used to indicate where you want the list of questions and answers to show for the registrant.  You place this within the "[attendee_list]" field.',
31
+				'event_espresso'
32
+			),
33
+		];
34
+	}
35 35
 
36 36
 
37
-    /**
38
-     * @param string $shortcode
39
-     * @return string
40
-     * @throws EE_Error
41
-     * @throws ReflectionException
42
-     */
43
-    protected function _parser($shortcode)
44
-    {
45
-        switch ($shortcode) {
46
-            case '[QUESTION_LIST]':
47
-                return $this->_get_question_list();
48
-        }
49
-        return '';
50
-    }
37
+	/**
38
+	 * @param string $shortcode
39
+	 * @return string
40
+	 * @throws EE_Error
41
+	 * @throws ReflectionException
42
+	 */
43
+	protected function _parser($shortcode)
44
+	{
45
+		switch ($shortcode) {
46
+			case '[QUESTION_LIST]':
47
+				return $this->_get_question_list();
48
+		}
49
+		return '';
50
+	}
51 51
 
52 52
 
53
-    /**
54
-     * @return string
55
-     * @throws EE_Error
56
-     * @throws ReflectionException
57
-     */
58
-    protected function _get_question_list()
59
-    {
60
-        $this->_validate_list_requirements();
53
+	/**
54
+	 * @return string
55
+	 * @throws EE_Error
56
+	 * @throws ReflectionException
57
+	 */
58
+	protected function _get_question_list()
59
+	{
60
+		$this->_validate_list_requirements();
61 61
 
62
-        // for when [QUESTION_LIST] is used in the [attendee_list] field.
63
-        if ($this->_data['data'] instanceof EE_Registration) {
64
-            return $this->_get_question_answer_list_for_attendee();
65
-        }
62
+		// for when [QUESTION_LIST] is used in the [attendee_list] field.
63
+		if ($this->_data['data'] instanceof EE_Registration) {
64
+			return $this->_get_question_answer_list_for_attendee();
65
+		}
66 66
 
67
-        // for when [QUESTION_LIST] is used in the main content field.
68
-        if (
69
-            $this->_data['data'] instanceof EE_Messages_Addressee
70
-            && $this->_data['data']->reg_obj instanceof EE_Registration
71
-        ) {
72
-            return $this->_get_question_answer_list_for_attendee($this->_data['data']->reg_obj);
73
-        }
74
-        return '';
75
-    }
67
+		// for when [QUESTION_LIST] is used in the main content field.
68
+		if (
69
+			$this->_data['data'] instanceof EE_Messages_Addressee
70
+			&& $this->_data['data']->reg_obj instanceof EE_Registration
71
+		) {
72
+			return $this->_get_question_answer_list_for_attendee($this->_data['data']->reg_obj);
73
+		}
74
+		return '';
75
+	}
76 76
 
77 77
 
78
-    /**
79
-     * Note when we parse the "[question_list]" shortcode for attendees we're actually going to retrieve the list of
80
-     * answers for that attendee since that is what we really need (we can derive the questions from the answers);
81
-     *
82
-     * @param null $reg_obj
83
-     * @return string parsed template.
84
-     * @throws EE_Error
85
-     * @throws ReflectionException
86
-     */
87
-    private function _get_question_answer_list_for_attendee($reg_obj = null)
88
-    {
89
-        $valid_shortcodes = ['question'];
90
-        $reg_obj          = $reg_obj instanceof EE_Registration
91
-            ? $reg_obj
92
-            : $this->_data['data'];
93
-        $template         = is_array($this->_data['template']) && isset($this->_data['template']['question_list'])
94
-            ? $this->_data['template']['question_list']
95
-            : '';
96
-        $template         = empty($template) && isset($this->_extra_data['template']['question_list'])
97
-            ? $this->_extra_data['template']['question_list']
98
-            : $template;
99
-        $ans_result       = '';
100
-        $answers          = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'])
101
-            ? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']
102
-            : [];
103
-        $questions        = ! empty($this->_extra_data['data']->questions)
104
-            ? $this->_extra_data['data']->questions
105
-            : [];
106
-        foreach ($answers as $answer) {
107
-            // first see if the question is in our $questions array.  If not then try to get from answer object
108
-            $question = isset($questions[ $answer->ID() ])
109
-                ? $questions[ $answer->ID() ]
110
-                : null;
111
-            $question = ! $question instanceof EE_Question
112
-                ? $answer->question()
113
-                : $question;
114
-            if ($question instanceof EE_Question and $question->admin_only()) {
115
-                continue;
116
-            }
117
-            $ans_result .= $this->_shortcode_helper->parse_question_list_template(
118
-                $template,
119
-                $answer,
120
-                $valid_shortcodes,
121
-                $this->_extra_data
122
-            );
123
-        }
78
+	/**
79
+	 * Note when we parse the "[question_list]" shortcode for attendees we're actually going to retrieve the list of
80
+	 * answers for that attendee since that is what we really need (we can derive the questions from the answers);
81
+	 *
82
+	 * @param null $reg_obj
83
+	 * @return string parsed template.
84
+	 * @throws EE_Error
85
+	 * @throws ReflectionException
86
+	 */
87
+	private function _get_question_answer_list_for_attendee($reg_obj = null)
88
+	{
89
+		$valid_shortcodes = ['question'];
90
+		$reg_obj          = $reg_obj instanceof EE_Registration
91
+			? $reg_obj
92
+			: $this->_data['data'];
93
+		$template         = is_array($this->_data['template']) && isset($this->_data['template']['question_list'])
94
+			? $this->_data['template']['question_list']
95
+			: '';
96
+		$template         = empty($template) && isset($this->_extra_data['template']['question_list'])
97
+			? $this->_extra_data['template']['question_list']
98
+			: $template;
99
+		$ans_result       = '';
100
+		$answers          = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'])
101
+			? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']
102
+			: [];
103
+		$questions        = ! empty($this->_extra_data['data']->questions)
104
+			? $this->_extra_data['data']->questions
105
+			: [];
106
+		foreach ($answers as $answer) {
107
+			// first see if the question is in our $questions array.  If not then try to get from answer object
108
+			$question = isset($questions[ $answer->ID() ])
109
+				? $questions[ $answer->ID() ]
110
+				: null;
111
+			$question = ! $question instanceof EE_Question
112
+				? $answer->question()
113
+				: $question;
114
+			if ($question instanceof EE_Question and $question->admin_only()) {
115
+				continue;
116
+			}
117
+			$ans_result .= $this->_shortcode_helper->parse_question_list_template(
118
+				$template,
119
+				$answer,
120
+				$valid_shortcodes,
121
+				$this->_extra_data
122
+			);
123
+		}
124 124
 
125
-        return $ans_result;
126
-    }
125
+		return $ans_result;
126
+	}
127 127
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelDataTranslator.php 2 patches
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
         ) {
70 70
             $new_value_maybe_array = [];
71 71
             foreach ($original_value_maybe_array as $array_key => $array_item) {
72
-                $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
72
+                $new_value_maybe_array[$array_key] = ModelDataTranslator::prepareFieldValueFromJson(
73 73
                     $field_obj,
74 74
                     $array_item,
75 75
                     $requested_version,
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
         if (is_array($original_value_maybe_array)) {
104 104
             $new_value = [];
105 105
             foreach ($original_value_maybe_array as $key => $value) {
106
-                $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
106
+                $new_value[$key] = ModelDataTranslator::prepareFieldValuesForJson(
107 107
                     $field_obj,
108 108
                     $value,
109 109
                     $request_version
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
                 '0',
245 245
                 STR_PAD_LEFT
246 246
             );
247
-        return $original_timestamp . $offset_sign . $offset_string;
247
+        return $original_timestamp.$offset_sign.$offset_string;
248 248
     }
249 249
 
250 250
 
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
                     // first, check if its a MySQL timestamp in GMT
324 324
                     $datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
325 325
                 }
326
-                if (! $datetime_obj instanceof DateTime) {
326
+                if ( ! $datetime_obj instanceof DateTime) {
327 327
                     // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
328 328
                     $datetime_obj = $field_obj->prepare_for_set($original_value);
329 329
                 }
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
                         $original_value,
350 350
                         $field_obj->get_name(),
351 351
                         $field_obj->get_model_name(),
352
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
352
+                        $field_obj->get_time_format().' '.$field_obj->get_time_format()
353 353
                     )
354 354
                 );
355 355
             }
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
         }
364 364
         // are we about to send an object? just don't. We have no good way to represent it in JSON.
365 365
         // can't just check using is_object() because that missed PHP incomplete objects
366
-        if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
366
+        if ( ! ModelDataTranslator::isRepresentableInJson($new_value)) {
367 367
             $new_value = [
368 368
                 'error_code'    => 'php_object_not_return',
369 369
                 'error_message' => esc_html__(
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
             if ($query_param_meta->getField() instanceof EE_Model_Field_Base) {
415 415
                 $translated_value = $query_param_meta->determineConditionsQueryParameterValue();
416 416
                 if (
417
-                    (isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ])
417
+                    (isset($query_param_for_models[$query_param_meta->getQueryParamKey()])
418 418
                      && $query_param_meta->isGmtField())
419 419
                     || $translated_value === null
420 420
                 ) {
@@ -423,11 +423,11 @@  discard block
 block discarded – undo
423 423
                     // OR we couldn't create a translated value from their input
424 424
                     continue;
425 425
                 }
426
-                $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value;
426
+                $query_param_for_models[$query_param_meta->getQueryParamKey()] = $translated_value;
427 427
             } else {
428 428
                 $nested_query_params = $query_param_meta->determineNestedConditionQueryParameters();
429 429
                 if ($nested_query_params) {
430
-                    $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params;
430
+                    $query_param_for_models[$query_param_meta->getQueryParamKey()] = $nested_query_params;
431 431
                 }
432 432
             }
433 433
         }
@@ -457,7 +457,7 @@  discard block
 block discarded – undo
457 457
      */
458 458
     public static function removeGmtFromFieldName($field_name)
459 459
     {
460
-        if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
460
+        if ( ! ModelDataTranslator::isGmtDateFieldName($field_name)) {
461 461
             return $field_name;
462 462
         }
463 463
         $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
     {
501 501
         $new_array = [];
502 502
         foreach ($field_names as $key => $field_name) {
503
-            $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
503
+            $new_array[$key] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
504 504
         }
505 505
         return $new_array;
506 506
     }
@@ -517,7 +517,7 @@  discard block
 block discarded – undo
517 517
     {
518 518
         $new_array = [];
519 519
         foreach ($field_names_as_keys as $field_name => $value) {
520
-            $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
520
+            $new_array[ModelDataTranslator::prepareFieldNameFromJson($field_name)] = $value;
521 521
         }
522 522
         return $new_array;
523 523
     }
@@ -613,10 +613,10 @@  discard block
 block discarded – undo
613 613
                         $requested_version
614 614
                     );
615 615
                 }
616
-                $query_param_for_models[ $query_param_key ] = $translated_value;
616
+                $query_param_for_models[$query_param_key] = $translated_value;
617 617
             } else {
618 618
                 // so it's not for a field, assume it's a logic query param key
619
-                $query_param_for_models[ $query_param_key ] =
619
+                $query_param_for_models[$query_param_key] =
620 620
                     ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
621 621
                         $query_param_value,
622 622
                         $model,
@@ -668,11 +668,11 @@  discard block
 block discarded – undo
668 668
             );
669 669
         }
670 670
         $number_of_parts       = count($query_param_parts);
671
-        $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
671
+        $last_query_param_part = $query_param_parts[count($query_param_parts) - 1];
672 672
         $field_name            = $last_query_param_part;
673 673
         if ($number_of_parts !== 1) {
674 674
             // the last part is the column name, and there are only 2parts. therefore...
675
-            $model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
675
+            $model = EE_Registry::instance()->load_model($query_param_parts[$number_of_parts - 2]);
676 676
         }
677 677
         try {
678 678
             return $model->field_settings_for($field_name, false);
Please login to merge, or discard this patch.
Indentation   +654 added lines, -654 removed lines patch added patch discarded remove patch
@@ -38,658 +38,658 @@
 block discarded – undo
38 38
  */
39 39
 class ModelDataTranslator
40 40
 {
41
-    /**
42
-     * We used to use -1 for infinity in the rest api, but that's ambiguous for
43
-     * fields that COULD contain -1; so we use null
44
-     */
45
-    const EE_INF_IN_REST = null;
46
-
47
-
48
-    /**
49
-     * Prepares a possible array of input values from JSON for use by the models
50
-     *
51
-     * @param EE_Model_Field_Base $field_obj
52
-     * @param mixed               $original_value_maybe_array
53
-     * @param string              $requested_version
54
-     * @param string              $timezone_string treat values as being in this timezone
55
-     * @return mixed
56
-     * @throws RestException
57
-     * @throws EE_Error
58
-     */
59
-    public static function prepareFieldValuesFromJson(
60
-        $field_obj,
61
-        $original_value_maybe_array,
62
-        $requested_version,
63
-        $timezone_string = 'UTC'
64
-    ) {
65
-        if (
66
-            is_array($original_value_maybe_array)
67
-            && ! $field_obj instanceof EE_Serialized_Text_Field
68
-        ) {
69
-            $new_value_maybe_array = [];
70
-            foreach ($original_value_maybe_array as $array_key => $array_item) {
71
-                $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
72
-                    $field_obj,
73
-                    $array_item,
74
-                    $requested_version,
75
-                    $timezone_string
76
-                );
77
-            }
78
-        } else {
79
-            $new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
80
-                $field_obj,
81
-                $original_value_maybe_array,
82
-                $requested_version,
83
-                $timezone_string
84
-            );
85
-        }
86
-        return $new_value_maybe_array;
87
-    }
88
-
89
-
90
-    /**
91
-     * Prepares an array of field values FOR use in JSON/REST API
92
-     *
93
-     * @param EE_Model_Field_Base $field_obj
94
-     * @param mixed               $original_value_maybe_array
95
-     * @param string              $request_version (eg 4.8.36)
96
-     * @return array|int|string
97
-     * @throws EE_Error
98
-     * @throws EE_Error
99
-     */
100
-    public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
101
-    {
102
-        if (is_array($original_value_maybe_array)) {
103
-            $new_value = [];
104
-            foreach ($original_value_maybe_array as $key => $value) {
105
-                $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
106
-                    $field_obj,
107
-                    $value,
108
-                    $request_version
109
-                );
110
-            }
111
-        } else {
112
-            $new_value = ModelDataTranslator::prepareFieldValueForJson(
113
-                $field_obj,
114
-                $original_value_maybe_array,
115
-                $request_version
116
-            );
117
-        }
118
-        return $new_value;
119
-    }
120
-
121
-
122
-    /**
123
-     * Prepares incoming data from the json or request parameters for the models'
124
-     * "$query_params".
125
-     *
126
-     * @param EE_Model_Field_Base $field_obj
127
-     * @param mixed               $original_value
128
-     * @param string              $requested_version
129
-     * @param string              $timezone_string treat values as being in this timezone
130
-     * @return mixed
131
-     * @throws RestException
132
-     * @throws DomainException
133
-     * @throws EE_Error
134
-     */
135
-    public static function prepareFieldValueFromJson(
136
-        $field_obj,
137
-        $original_value,
138
-        $requested_version,
139
-        $timezone_string = 'UTC'
140
-    ) {
141
-        // check if they accidentally submitted an error value. If so throw an exception
142
-        if (
143
-            is_array($original_value)
144
-            && isset($original_value['error_code'], $original_value['error_message'])
145
-        ) {
146
-            throw new RestException(
147
-                'rest_submitted_error_value',
148
-                sprintf(
149
-                    esc_html__(
150
-                        'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
151
-                        'event_espresso'
152
-                    ),
153
-                    $field_obj->get_name()
154
-                ),
155
-                [
156
-                    'status' => 400,
157
-                ]
158
-            );
159
-        }
160
-        // double-check for serialized PHP. We never accept serialized PHP. No way Jose.
161
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
162
-        $timezone_string =
163
-            $timezone_string !== ''
164
-                ? $timezone_string
165
-                : get_option('timezone_string', '');
166
-        // walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
167
-        // way Jose.
168
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
169
-        if (
170
-            $field_obj instanceof EE_Infinite_Integer_Field
171
-            && in_array($original_value, [null, ''], true)
172
-        ) {
173
-            $new_value = EE_INF;
174
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
175
-            $new_value = rest_parse_date(
176
-                self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
177
-            );
178
-            if ($new_value === false) {
179
-                throw new RestException(
180
-                    'invalid_format_for_timestamp',
181
-                    sprintf(
182
-                        esc_html__(
183
-                            'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
184
-                            'event_espresso'
185
-                        ),
186
-                        'RFC3339',
187
-                        'ISO8601',
188
-                        $original_value
189
-                    ),
190
-                    [
191
-                        'status' => 400,
192
-                    ]
193
-                );
194
-            }
195
-        } elseif ($field_obj instanceof EE_Boolean_Field) {
196
-            // Interpreted the strings "false", "true", "on", "off" appropriately.
197
-            $new_value = filter_var($original_value, FILTER_VALIDATE_BOOLEAN);
198
-        } else {
199
-            $new_value = $original_value;
200
-        }
201
-        return $new_value;
202
-    }
203
-
204
-
205
-    /**
206
-     * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
207
-     * information via details obtained from the host site.
208
-     *
209
-     * @param string            $original_timestamp
210
-     * @param EE_Datetime_Field $datetime_field
211
-     * @param                   $timezone_string
212
-     * @return string
213
-     * @throws DomainException
214
-     */
215
-    private static function getTimestampWithTimezoneOffset(
216
-        $original_timestamp,
217
-        EE_Datetime_Field $datetime_field,
218
-        $timezone_string
219
-    ) {
220
-        // already have timezone information?
221
-        if (preg_match('/Z|([+-])(\d{2}:\d{2})/', $original_timestamp)) {
222
-            // yes, we're ignoring the timezone.
223
-            return $original_timestamp;
224
-        }
225
-        // need to append timezone
226
-        list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
227
-            $datetime_field->get_timezone_offset(
228
-                new DateTimeZone($timezone_string),
229
-                $original_timestamp
230
-            )
231
-        );
232
-        $offset_string =
233
-            str_pad(
234
-                floor($offset_secs / HOUR_IN_SECONDS),
235
-                2,
236
-                '0',
237
-                STR_PAD_LEFT
238
-            )
239
-            . ':'
240
-            . str_pad(
241
-                ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
242
-                2,
243
-                '0',
244
-                STR_PAD_LEFT
245
-            );
246
-        return $original_timestamp . $offset_sign . $offset_string;
247
-    }
248
-
249
-
250
-    /**
251
-     * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
252
-     * think that can happen). If $data is an array, recurses into its keys and values
253
-     *
254
-     * @param mixed $data
255
-     * @return void
256
-     * @throws RestException
257
-     */
258
-    public static function throwExceptionIfContainsSerializedData($data)
259
-    {
260
-        if (is_array($data)) {
261
-            foreach ($data as $key => $value) {
262
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
263
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
264
-            }
265
-        } else {
266
-            if (is_serialized($data) || is_object($data)) {
267
-                throw new RestException(
268
-                    'serialized_data_submission_prohibited',
269
-                    esc_html__(
270
-                    // @codingStandardsIgnoreStart
271
-                        'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
272
-                        // @codingStandardsIgnoreEnd
273
-                        'event_espresso'
274
-                    )
275
-                );
276
-            }
277
-        }
278
-    }
279
-
280
-
281
-    /**
282
-     * determines what's going on with them timezone strings
283
-     *
284
-     * @param int $timezone_offset
285
-     * @return array
286
-     */
287
-    private static function parseTimezoneOffset($timezone_offset)
288
-    {
289
-        $first_char = substr((string) $timezone_offset, 0, 1);
290
-        if ($first_char === '+' || $first_char === '-') {
291
-            $offset_sign = $first_char;
292
-            $offset_secs = substr((string) $timezone_offset, 1);
293
-        } else {
294
-            $offset_sign = '+';
295
-            $offset_secs = $timezone_offset;
296
-        }
297
-        return [$offset_sign, $offset_secs];
298
-    }
299
-
300
-
301
-    /**
302
-     * Prepares a field's value for display in the API
303
-     *
304
-     * @param EE_Model_Field_Base $field_obj
305
-     * @param mixed               $original_value
306
-     * @param string              $requested_version
307
-     * @return mixed
308
-     * @throws EE_Error
309
-     * @throws EE_Error
310
-     */
311
-    public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
312
-    {
313
-        if ($original_value === EE_INF) {
314
-            $new_value = ModelDataTranslator::EE_INF_IN_REST;
315
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
316
-            if (is_string($original_value)) {
317
-                // did they submit a string of a unix timestamp?
318
-                if (is_numeric($original_value)) {
319
-                    $datetime_obj = new DateTime();
320
-                    $datetime_obj->setTimestamp((int) $original_value);
321
-                } else {
322
-                    // first, check if its a MySQL timestamp in GMT
323
-                    $datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
324
-                }
325
-                if (! $datetime_obj instanceof DateTime) {
326
-                    // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
327
-                    $datetime_obj = $field_obj->prepare_for_set($original_value);
328
-                }
329
-                $original_value = $datetime_obj;
330
-            }
331
-            if ($original_value instanceof DateTime) {
332
-                $new_value = $original_value->format('Y-m-d H:i:s');
333
-            } elseif (is_int($original_value) || is_float($original_value)) {
334
-                $new_value = date('Y-m-d H:i:s', $original_value);
335
-            } elseif ($original_value === null || $original_value === '') {
336
-                $new_value = null;
337
-            } else {
338
-                // so it's not a datetime object, unix timestamp (as string or int),
339
-                // MySQL timestamp, or even a string in the field object's format. So no idea what it is
340
-                throw new EE_Error(
341
-                    sprintf(
342
-                        esc_html__(
343
-                        // @codingStandardsIgnoreStart
344
-                            'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
345
-                            // @codingStandardsIgnoreEnd
346
-                            'event_espresso'
347
-                        ),
348
-                        $original_value,
349
-                        $field_obj->get_name(),
350
-                        $field_obj->get_model_name(),
351
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
352
-                    )
353
-                );
354
-            }
355
-            if ($new_value !== null) {
356
-                $new_value = mysql2date('Y-m-d\TH:i:s', $new_value, false);
357
-            }
358
-        } else {
359
-            $new_value = $original_value;
360
-        }
361
-        // are we about to send an object? just don't. We have no good way to represent it in JSON.
362
-        // can't just check using is_object() because that missed PHP incomplete objects
363
-        if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
364
-            $new_value = [
365
-                'error_code'    => 'php_object_not_return',
366
-                'error_message' => esc_html__(
367
-                    'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
368
-                    'event_espresso'
369
-                ),
370
-            ];
371
-        }
372
-        return apply_filters(
373
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
374
-            $new_value,
375
-            $field_obj,
376
-            $original_value,
377
-            $requested_version
378
-        );
379
-    }
380
-
381
-
382
-    /**
383
-     * Prepares condition-query-parameters (like what's in where and having) from
384
-     * the format expected in the API to use in the models
385
-     *
386
-     * @param array    $inputted_query_params_of_this_type
387
-     * @param EEM_Base $model
388
-     * @param string   $requested_version
389
-     * @param boolean  $writing whether this data will be written to the DB, or if we're just building a query.
390
-     *                          If we're writing to the DB, we don't expect any operators, or any logic query
391
-     *                          parameters, and we also won't accept serialized data unless the current user has
392
-     *                          unfiltered_html.
393
-     * @return array
394
-     * @throws DomainException
395
-     * @throws EE_Error
396
-     * @throws RestException
397
-     * @throws InvalidDataTypeException
398
-     * @throws InvalidInterfaceException
399
-     * @throws InvalidArgumentException
400
-     */
401
-    public static function prepareConditionsQueryParamsForModels(
402
-        $inputted_query_params_of_this_type,
403
-        EEM_Base $model,
404
-        $requested_version,
405
-        $writing = false
406
-    ) {
407
-        $query_param_for_models = [];
408
-        $context                = new RestIncomingQueryParamContext($model, $requested_version, $writing);
409
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
410
-            $query_param_meta = new RestIncomingQueryParamMetadata($query_param_key, $query_param_value, $context);
411
-            if ($query_param_meta->getField() instanceof EE_Model_Field_Base) {
412
-                $translated_value = $query_param_meta->determineConditionsQueryParameterValue();
413
-                if (
414
-                    (isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ])
415
-                     && $query_param_meta->isGmtField())
416
-                    || $translated_value === null
417
-                ) {
418
-                    // they have already provided a non-gmt field, ignore the gmt one. That's what WP core
419
-                    // currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
420
-                    // OR we couldn't create a translated value from their input
421
-                    continue;
422
-                }
423
-                $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value;
424
-            } else {
425
-                $nested_query_params = $query_param_meta->determineNestedConditionQueryParameters();
426
-                if ($nested_query_params) {
427
-                    $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params;
428
-                }
429
-            }
430
-        }
431
-        return $query_param_for_models;
432
-    }
433
-
434
-
435
-    /**
436
-     * Mostly checks if the last 4 characters are "_gmt", indicating its a
437
-     * gmt date field name
438
-     *
439
-     * @param string $field_name
440
-     * @return boolean
441
-     */
442
-    public static function isGmtDateFieldName($field_name)
443
-    {
444
-        $field_name = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name);
445
-        return substr($field_name, -4, 4) === '_gmt';
446
-    }
447
-
448
-
449
-    /**
450
-     * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
451
-     *
452
-     * @param string $field_name
453
-     * @return string
454
-     */
455
-    public static function removeGmtFromFieldName($field_name)
456
-    {
457
-        if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
458
-            return $field_name;
459
-        }
460
-        $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
461
-            $field_name
462
-        );
463
-        $query_param_sans_gmt_and_sans_stars = substr(
464
-            $query_param_sans_stars,
465
-            0,
466
-            strrpos(
467
-                $field_name,
468
-                '_gmt'
469
-            )
470
-        );
471
-        return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
472
-    }
473
-
474
-
475
-    /**
476
-     * Takes a field name from the REST API and prepares it for the model querying
477
-     *
478
-     * @param string $field_name
479
-     * @return string
480
-     */
481
-    public static function prepareFieldNameFromJson($field_name)
482
-    {
483
-        if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
484
-            return ModelDataTranslator::removeGmtFromFieldName($field_name);
485
-        }
486
-        return $field_name;
487
-    }
488
-
489
-
490
-    /**
491
-     * Takes array of field names from REST API and prepares for models
492
-     *
493
-     * @param array $field_names
494
-     * @return array of field names (possibly include model prefixes)
495
-     */
496
-    public static function prepareFieldNamesFromJson(array $field_names)
497
-    {
498
-        $new_array = [];
499
-        foreach ($field_names as $key => $field_name) {
500
-            $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
501
-        }
502
-        return $new_array;
503
-    }
504
-
505
-
506
-    /**
507
-     * Takes array where array keys are field names (possibly with model path prefixes)
508
-     * from the REST API and prepares them for model querying
509
-     *
510
-     * @param array $field_names_as_keys
511
-     * @return array
512
-     */
513
-    public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
514
-    {
515
-        $new_array = [];
516
-        foreach ($field_names_as_keys as $field_name => $value) {
517
-            $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
518
-        }
519
-        return $new_array;
520
-    }
521
-
522
-
523
-    /**
524
-     * Prepares an array of model query params for use in the REST API
525
-     *
526
-     * @param array    $model_query_params
527
-     * @param EEM_Base $model
528
-     * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
529
-     *                                     REST API
530
-     * @return array which can be passed into the EE4 REST API when querying a model resource
531
-     * @throws EE_Error
532
-     * @throws ReflectionException
533
-     */
534
-    public static function prepareQueryParamsForRestApi(
535
-        array $model_query_params,
536
-        EEM_Base $model,
537
-        $requested_version = null
538
-    ) {
539
-        if ($requested_version === null) {
540
-            $requested_version = EED_Core_Rest_Api::latest_rest_api_version();
541
-        }
542
-        $rest_query_params = $model_query_params;
543
-        if (isset($model_query_params[0])) {
544
-            $rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
545
-                $model_query_params[0],
546
-                $model,
547
-                $requested_version
548
-            );
549
-            unset($rest_query_params[0]);
550
-        }
551
-        if (isset($model_query_params['having'])) {
552
-            $rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
553
-                $model_query_params['having'],
554
-                $model,
555
-                $requested_version
556
-            );
557
-        }
558
-        return apply_filters(
559
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
560
-            $rest_query_params,
561
-            $model_query_params,
562
-            $model,
563
-            $requested_version
564
-        );
565
-    }
566
-
567
-
568
-    /**
569
-     * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
570
-     *
571
-     * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
572
-     * @param EEM_Base $model
573
-     * @param string   $requested_version                   eg "4.8.36"
574
-     * @return array ready for use in the rest api query params
575
-     * @throws EE_Error
576
-     * @throws RestException if somehow a PHP object were in the query params' values,*@throws
577
-     * @throws ReflectionException
578
-     *                                                      ReflectionException
579
-     *                                                      (which would be really unusual)
580
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
581
-     */
582
-    public static function prepareConditionsQueryParamsForRestApi(
583
-        $inputted_query_params_of_this_type,
584
-        EEM_Base $model,
585
-        $requested_version
586
-    ) {
587
-        $query_param_for_models = [];
588
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
589
-            $field = ModelDataTranslator::deduceFieldFromQueryParam(
590
-                ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
591
-                $model
592
-            );
593
-            if ($field instanceof EE_Model_Field_Base) {
594
-                // did they specify an operator?
595
-                if (is_array($query_param_value)) {
596
-                    $op               = $query_param_value[0];
597
-                    $translated_value = [$op];
598
-                    if (isset($query_param_value[1])) {
599
-                        $value               = $query_param_value[1];
600
-                        $translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
601
-                            $field,
602
-                            $value,
603
-                            $requested_version
604
-                        );
605
-                    }
606
-                } else {
607
-                    $translated_value = ModelDataTranslator::prepareFieldValueForJson(
608
-                        $field,
609
-                        $query_param_value,
610
-                        $requested_version
611
-                    );
612
-                }
613
-                $query_param_for_models[ $query_param_key ] = $translated_value;
614
-            } else {
615
-                // so it's not for a field, assume it's a logic query param key
616
-                $query_param_for_models[ $query_param_key ] =
617
-                    ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
618
-                        $query_param_value,
619
-                        $model,
620
-                        $requested_version
621
-                    );
622
-            }
623
-        }
624
-        return $query_param_for_models;
625
-    }
626
-
627
-
628
-    /**
629
-     * @param $condition_query_param_key
630
-     * @return string
631
-     */
632
-    public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
633
-    {
634
-        $pos_of_star = strpos($condition_query_param_key, '*');
635
-        if ($pos_of_star === false) {
636
-            return $condition_query_param_key;
637
-        }
638
-        return substr($condition_query_param_key, 0, $pos_of_star);
639
-    }
640
-
641
-
642
-    /**
643
-     * Takes the input parameter and finds the model field that it indicates.
644
-     *
645
-     * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
646
-     * @param EEM_Base $model
647
-     * @return EE_Model_Field_Base
648
-     * @throws EE_Error
649
-     * @throws ReflectionException
650
-     */
651
-    public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
652
-    {
653
-        // ok, now proceed with deducing which part is the model's name, and which is the field's name
654
-        // which will help us find the database table and column
655
-        $query_param_parts = explode('.', $query_param_name);
656
-        if (empty($query_param_parts)) {
657
-            throw new EE_Error(
658
-                sprintf(
659
-                    esc_html__(
660
-                        '_extract_column_name is empty when trying to extract column and table name from %s',
661
-                        'event_espresso'
662
-                    ),
663
-                    $query_param_name
664
-                )
665
-            );
666
-        }
667
-        $number_of_parts       = count($query_param_parts);
668
-        $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
669
-        $field_name            = $last_query_param_part;
670
-        if ($number_of_parts !== 1) {
671
-            // the last part is the column name, and there are only 2parts. therefore...
672
-            $model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
673
-        }
674
-        try {
675
-            return $model->field_settings_for($field_name, false);
676
-        } catch (EE_Error $e) {
677
-            return null;
678
-        }
679
-    }
680
-
681
-
682
-    /**
683
-     * Returns true if $data can be easily represented in JSON.
684
-     * Basically, objects and resources can't be represented in JSON easily.
685
-     *
686
-     * @param mixed $data
687
-     * @return bool
688
-     */
689
-    protected static function isRepresentableInJson($data)
690
-    {
691
-        return is_scalar($data)
692
-               || is_array($data)
693
-               || is_null($data);
694
-    }
41
+	/**
42
+	 * We used to use -1 for infinity in the rest api, but that's ambiguous for
43
+	 * fields that COULD contain -1; so we use null
44
+	 */
45
+	const EE_INF_IN_REST = null;
46
+
47
+
48
+	/**
49
+	 * Prepares a possible array of input values from JSON for use by the models
50
+	 *
51
+	 * @param EE_Model_Field_Base $field_obj
52
+	 * @param mixed               $original_value_maybe_array
53
+	 * @param string              $requested_version
54
+	 * @param string              $timezone_string treat values as being in this timezone
55
+	 * @return mixed
56
+	 * @throws RestException
57
+	 * @throws EE_Error
58
+	 */
59
+	public static function prepareFieldValuesFromJson(
60
+		$field_obj,
61
+		$original_value_maybe_array,
62
+		$requested_version,
63
+		$timezone_string = 'UTC'
64
+	) {
65
+		if (
66
+			is_array($original_value_maybe_array)
67
+			&& ! $field_obj instanceof EE_Serialized_Text_Field
68
+		) {
69
+			$new_value_maybe_array = [];
70
+			foreach ($original_value_maybe_array as $array_key => $array_item) {
71
+				$new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
72
+					$field_obj,
73
+					$array_item,
74
+					$requested_version,
75
+					$timezone_string
76
+				);
77
+			}
78
+		} else {
79
+			$new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
80
+				$field_obj,
81
+				$original_value_maybe_array,
82
+				$requested_version,
83
+				$timezone_string
84
+			);
85
+		}
86
+		return $new_value_maybe_array;
87
+	}
88
+
89
+
90
+	/**
91
+	 * Prepares an array of field values FOR use in JSON/REST API
92
+	 *
93
+	 * @param EE_Model_Field_Base $field_obj
94
+	 * @param mixed               $original_value_maybe_array
95
+	 * @param string              $request_version (eg 4.8.36)
96
+	 * @return array|int|string
97
+	 * @throws EE_Error
98
+	 * @throws EE_Error
99
+	 */
100
+	public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
101
+	{
102
+		if (is_array($original_value_maybe_array)) {
103
+			$new_value = [];
104
+			foreach ($original_value_maybe_array as $key => $value) {
105
+				$new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
106
+					$field_obj,
107
+					$value,
108
+					$request_version
109
+				);
110
+			}
111
+		} else {
112
+			$new_value = ModelDataTranslator::prepareFieldValueForJson(
113
+				$field_obj,
114
+				$original_value_maybe_array,
115
+				$request_version
116
+			);
117
+		}
118
+		return $new_value;
119
+	}
120
+
121
+
122
+	/**
123
+	 * Prepares incoming data from the json or request parameters for the models'
124
+	 * "$query_params".
125
+	 *
126
+	 * @param EE_Model_Field_Base $field_obj
127
+	 * @param mixed               $original_value
128
+	 * @param string              $requested_version
129
+	 * @param string              $timezone_string treat values as being in this timezone
130
+	 * @return mixed
131
+	 * @throws RestException
132
+	 * @throws DomainException
133
+	 * @throws EE_Error
134
+	 */
135
+	public static function prepareFieldValueFromJson(
136
+		$field_obj,
137
+		$original_value,
138
+		$requested_version,
139
+		$timezone_string = 'UTC'
140
+	) {
141
+		// check if they accidentally submitted an error value. If so throw an exception
142
+		if (
143
+			is_array($original_value)
144
+			&& isset($original_value['error_code'], $original_value['error_message'])
145
+		) {
146
+			throw new RestException(
147
+				'rest_submitted_error_value',
148
+				sprintf(
149
+					esc_html__(
150
+						'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
151
+						'event_espresso'
152
+					),
153
+					$field_obj->get_name()
154
+				),
155
+				[
156
+					'status' => 400,
157
+				]
158
+			);
159
+		}
160
+		// double-check for serialized PHP. We never accept serialized PHP. No way Jose.
161
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
162
+		$timezone_string =
163
+			$timezone_string !== ''
164
+				? $timezone_string
165
+				: get_option('timezone_string', '');
166
+		// walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
167
+		// way Jose.
168
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
169
+		if (
170
+			$field_obj instanceof EE_Infinite_Integer_Field
171
+			&& in_array($original_value, [null, ''], true)
172
+		) {
173
+			$new_value = EE_INF;
174
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
175
+			$new_value = rest_parse_date(
176
+				self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
177
+			);
178
+			if ($new_value === false) {
179
+				throw new RestException(
180
+					'invalid_format_for_timestamp',
181
+					sprintf(
182
+						esc_html__(
183
+							'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
184
+							'event_espresso'
185
+						),
186
+						'RFC3339',
187
+						'ISO8601',
188
+						$original_value
189
+					),
190
+					[
191
+						'status' => 400,
192
+					]
193
+				);
194
+			}
195
+		} elseif ($field_obj instanceof EE_Boolean_Field) {
196
+			// Interpreted the strings "false", "true", "on", "off" appropriately.
197
+			$new_value = filter_var($original_value, FILTER_VALIDATE_BOOLEAN);
198
+		} else {
199
+			$new_value = $original_value;
200
+		}
201
+		return $new_value;
202
+	}
203
+
204
+
205
+	/**
206
+	 * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
207
+	 * information via details obtained from the host site.
208
+	 *
209
+	 * @param string            $original_timestamp
210
+	 * @param EE_Datetime_Field $datetime_field
211
+	 * @param                   $timezone_string
212
+	 * @return string
213
+	 * @throws DomainException
214
+	 */
215
+	private static function getTimestampWithTimezoneOffset(
216
+		$original_timestamp,
217
+		EE_Datetime_Field $datetime_field,
218
+		$timezone_string
219
+	) {
220
+		// already have timezone information?
221
+		if (preg_match('/Z|([+-])(\d{2}:\d{2})/', $original_timestamp)) {
222
+			// yes, we're ignoring the timezone.
223
+			return $original_timestamp;
224
+		}
225
+		// need to append timezone
226
+		list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
227
+			$datetime_field->get_timezone_offset(
228
+				new DateTimeZone($timezone_string),
229
+				$original_timestamp
230
+			)
231
+		);
232
+		$offset_string =
233
+			str_pad(
234
+				floor($offset_secs / HOUR_IN_SECONDS),
235
+				2,
236
+				'0',
237
+				STR_PAD_LEFT
238
+			)
239
+			. ':'
240
+			. str_pad(
241
+				($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
242
+				2,
243
+				'0',
244
+				STR_PAD_LEFT
245
+			);
246
+		return $original_timestamp . $offset_sign . $offset_string;
247
+	}
248
+
249
+
250
+	/**
251
+	 * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
252
+	 * think that can happen). If $data is an array, recurses into its keys and values
253
+	 *
254
+	 * @param mixed $data
255
+	 * @return void
256
+	 * @throws RestException
257
+	 */
258
+	public static function throwExceptionIfContainsSerializedData($data)
259
+	{
260
+		if (is_array($data)) {
261
+			foreach ($data as $key => $value) {
262
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
263
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
264
+			}
265
+		} else {
266
+			if (is_serialized($data) || is_object($data)) {
267
+				throw new RestException(
268
+					'serialized_data_submission_prohibited',
269
+					esc_html__(
270
+					// @codingStandardsIgnoreStart
271
+						'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
272
+						// @codingStandardsIgnoreEnd
273
+						'event_espresso'
274
+					)
275
+				);
276
+			}
277
+		}
278
+	}
279
+
280
+
281
+	/**
282
+	 * determines what's going on with them timezone strings
283
+	 *
284
+	 * @param int $timezone_offset
285
+	 * @return array
286
+	 */
287
+	private static function parseTimezoneOffset($timezone_offset)
288
+	{
289
+		$first_char = substr((string) $timezone_offset, 0, 1);
290
+		if ($first_char === '+' || $first_char === '-') {
291
+			$offset_sign = $first_char;
292
+			$offset_secs = substr((string) $timezone_offset, 1);
293
+		} else {
294
+			$offset_sign = '+';
295
+			$offset_secs = $timezone_offset;
296
+		}
297
+		return [$offset_sign, $offset_secs];
298
+	}
299
+
300
+
301
+	/**
302
+	 * Prepares a field's value for display in the API
303
+	 *
304
+	 * @param EE_Model_Field_Base $field_obj
305
+	 * @param mixed               $original_value
306
+	 * @param string              $requested_version
307
+	 * @return mixed
308
+	 * @throws EE_Error
309
+	 * @throws EE_Error
310
+	 */
311
+	public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
312
+	{
313
+		if ($original_value === EE_INF) {
314
+			$new_value = ModelDataTranslator::EE_INF_IN_REST;
315
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
316
+			if (is_string($original_value)) {
317
+				// did they submit a string of a unix timestamp?
318
+				if (is_numeric($original_value)) {
319
+					$datetime_obj = new DateTime();
320
+					$datetime_obj->setTimestamp((int) $original_value);
321
+				} else {
322
+					// first, check if its a MySQL timestamp in GMT
323
+					$datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
324
+				}
325
+				if (! $datetime_obj instanceof DateTime) {
326
+					// so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
327
+					$datetime_obj = $field_obj->prepare_for_set($original_value);
328
+				}
329
+				$original_value = $datetime_obj;
330
+			}
331
+			if ($original_value instanceof DateTime) {
332
+				$new_value = $original_value->format('Y-m-d H:i:s');
333
+			} elseif (is_int($original_value) || is_float($original_value)) {
334
+				$new_value = date('Y-m-d H:i:s', $original_value);
335
+			} elseif ($original_value === null || $original_value === '') {
336
+				$new_value = null;
337
+			} else {
338
+				// so it's not a datetime object, unix timestamp (as string or int),
339
+				// MySQL timestamp, or even a string in the field object's format. So no idea what it is
340
+				throw new EE_Error(
341
+					sprintf(
342
+						esc_html__(
343
+						// @codingStandardsIgnoreStart
344
+							'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
345
+							// @codingStandardsIgnoreEnd
346
+							'event_espresso'
347
+						),
348
+						$original_value,
349
+						$field_obj->get_name(),
350
+						$field_obj->get_model_name(),
351
+						$field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
352
+					)
353
+				);
354
+			}
355
+			if ($new_value !== null) {
356
+				$new_value = mysql2date('Y-m-d\TH:i:s', $new_value, false);
357
+			}
358
+		} else {
359
+			$new_value = $original_value;
360
+		}
361
+		// are we about to send an object? just don't. We have no good way to represent it in JSON.
362
+		// can't just check using is_object() because that missed PHP incomplete objects
363
+		if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
364
+			$new_value = [
365
+				'error_code'    => 'php_object_not_return',
366
+				'error_message' => esc_html__(
367
+					'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
368
+					'event_espresso'
369
+				),
370
+			];
371
+		}
372
+		return apply_filters(
373
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
374
+			$new_value,
375
+			$field_obj,
376
+			$original_value,
377
+			$requested_version
378
+		);
379
+	}
380
+
381
+
382
+	/**
383
+	 * Prepares condition-query-parameters (like what's in where and having) from
384
+	 * the format expected in the API to use in the models
385
+	 *
386
+	 * @param array    $inputted_query_params_of_this_type
387
+	 * @param EEM_Base $model
388
+	 * @param string   $requested_version
389
+	 * @param boolean  $writing whether this data will be written to the DB, or if we're just building a query.
390
+	 *                          If we're writing to the DB, we don't expect any operators, or any logic query
391
+	 *                          parameters, and we also won't accept serialized data unless the current user has
392
+	 *                          unfiltered_html.
393
+	 * @return array
394
+	 * @throws DomainException
395
+	 * @throws EE_Error
396
+	 * @throws RestException
397
+	 * @throws InvalidDataTypeException
398
+	 * @throws InvalidInterfaceException
399
+	 * @throws InvalidArgumentException
400
+	 */
401
+	public static function prepareConditionsQueryParamsForModels(
402
+		$inputted_query_params_of_this_type,
403
+		EEM_Base $model,
404
+		$requested_version,
405
+		$writing = false
406
+	) {
407
+		$query_param_for_models = [];
408
+		$context                = new RestIncomingQueryParamContext($model, $requested_version, $writing);
409
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
410
+			$query_param_meta = new RestIncomingQueryParamMetadata($query_param_key, $query_param_value, $context);
411
+			if ($query_param_meta->getField() instanceof EE_Model_Field_Base) {
412
+				$translated_value = $query_param_meta->determineConditionsQueryParameterValue();
413
+				if (
414
+					(isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ])
415
+					 && $query_param_meta->isGmtField())
416
+					|| $translated_value === null
417
+				) {
418
+					// they have already provided a non-gmt field, ignore the gmt one. That's what WP core
419
+					// currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
420
+					// OR we couldn't create a translated value from their input
421
+					continue;
422
+				}
423
+				$query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value;
424
+			} else {
425
+				$nested_query_params = $query_param_meta->determineNestedConditionQueryParameters();
426
+				if ($nested_query_params) {
427
+					$query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params;
428
+				}
429
+			}
430
+		}
431
+		return $query_param_for_models;
432
+	}
433
+
434
+
435
+	/**
436
+	 * Mostly checks if the last 4 characters are "_gmt", indicating its a
437
+	 * gmt date field name
438
+	 *
439
+	 * @param string $field_name
440
+	 * @return boolean
441
+	 */
442
+	public static function isGmtDateFieldName($field_name)
443
+	{
444
+		$field_name = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name);
445
+		return substr($field_name, -4, 4) === '_gmt';
446
+	}
447
+
448
+
449
+	/**
450
+	 * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
451
+	 *
452
+	 * @param string $field_name
453
+	 * @return string
454
+	 */
455
+	public static function removeGmtFromFieldName($field_name)
456
+	{
457
+		if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
458
+			return $field_name;
459
+		}
460
+		$query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
461
+			$field_name
462
+		);
463
+		$query_param_sans_gmt_and_sans_stars = substr(
464
+			$query_param_sans_stars,
465
+			0,
466
+			strrpos(
467
+				$field_name,
468
+				'_gmt'
469
+			)
470
+		);
471
+		return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
472
+	}
473
+
474
+
475
+	/**
476
+	 * Takes a field name from the REST API and prepares it for the model querying
477
+	 *
478
+	 * @param string $field_name
479
+	 * @return string
480
+	 */
481
+	public static function prepareFieldNameFromJson($field_name)
482
+	{
483
+		if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
484
+			return ModelDataTranslator::removeGmtFromFieldName($field_name);
485
+		}
486
+		return $field_name;
487
+	}
488
+
489
+
490
+	/**
491
+	 * Takes array of field names from REST API and prepares for models
492
+	 *
493
+	 * @param array $field_names
494
+	 * @return array of field names (possibly include model prefixes)
495
+	 */
496
+	public static function prepareFieldNamesFromJson(array $field_names)
497
+	{
498
+		$new_array = [];
499
+		foreach ($field_names as $key => $field_name) {
500
+			$new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
501
+		}
502
+		return $new_array;
503
+	}
504
+
505
+
506
+	/**
507
+	 * Takes array where array keys are field names (possibly with model path prefixes)
508
+	 * from the REST API and prepares them for model querying
509
+	 *
510
+	 * @param array $field_names_as_keys
511
+	 * @return array
512
+	 */
513
+	public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
514
+	{
515
+		$new_array = [];
516
+		foreach ($field_names_as_keys as $field_name => $value) {
517
+			$new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
518
+		}
519
+		return $new_array;
520
+	}
521
+
522
+
523
+	/**
524
+	 * Prepares an array of model query params for use in the REST API
525
+	 *
526
+	 * @param array    $model_query_params
527
+	 * @param EEM_Base $model
528
+	 * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
529
+	 *                                     REST API
530
+	 * @return array which can be passed into the EE4 REST API when querying a model resource
531
+	 * @throws EE_Error
532
+	 * @throws ReflectionException
533
+	 */
534
+	public static function prepareQueryParamsForRestApi(
535
+		array $model_query_params,
536
+		EEM_Base $model,
537
+		$requested_version = null
538
+	) {
539
+		if ($requested_version === null) {
540
+			$requested_version = EED_Core_Rest_Api::latest_rest_api_version();
541
+		}
542
+		$rest_query_params = $model_query_params;
543
+		if (isset($model_query_params[0])) {
544
+			$rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
545
+				$model_query_params[0],
546
+				$model,
547
+				$requested_version
548
+			);
549
+			unset($rest_query_params[0]);
550
+		}
551
+		if (isset($model_query_params['having'])) {
552
+			$rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
553
+				$model_query_params['having'],
554
+				$model,
555
+				$requested_version
556
+			);
557
+		}
558
+		return apply_filters(
559
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
560
+			$rest_query_params,
561
+			$model_query_params,
562
+			$model,
563
+			$requested_version
564
+		);
565
+	}
566
+
567
+
568
+	/**
569
+	 * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
570
+	 *
571
+	 * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
572
+	 * @param EEM_Base $model
573
+	 * @param string   $requested_version                   eg "4.8.36"
574
+	 * @return array ready for use in the rest api query params
575
+	 * @throws EE_Error
576
+	 * @throws RestException if somehow a PHP object were in the query params' values,*@throws
577
+	 * @throws ReflectionException
578
+	 *                                                      ReflectionException
579
+	 *                                                      (which would be really unusual)
580
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
581
+	 */
582
+	public static function prepareConditionsQueryParamsForRestApi(
583
+		$inputted_query_params_of_this_type,
584
+		EEM_Base $model,
585
+		$requested_version
586
+	) {
587
+		$query_param_for_models = [];
588
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
589
+			$field = ModelDataTranslator::deduceFieldFromQueryParam(
590
+				ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
591
+				$model
592
+			);
593
+			if ($field instanceof EE_Model_Field_Base) {
594
+				// did they specify an operator?
595
+				if (is_array($query_param_value)) {
596
+					$op               = $query_param_value[0];
597
+					$translated_value = [$op];
598
+					if (isset($query_param_value[1])) {
599
+						$value               = $query_param_value[1];
600
+						$translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
601
+							$field,
602
+							$value,
603
+							$requested_version
604
+						);
605
+					}
606
+				} else {
607
+					$translated_value = ModelDataTranslator::prepareFieldValueForJson(
608
+						$field,
609
+						$query_param_value,
610
+						$requested_version
611
+					);
612
+				}
613
+				$query_param_for_models[ $query_param_key ] = $translated_value;
614
+			} else {
615
+				// so it's not for a field, assume it's a logic query param key
616
+				$query_param_for_models[ $query_param_key ] =
617
+					ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
618
+						$query_param_value,
619
+						$model,
620
+						$requested_version
621
+					);
622
+			}
623
+		}
624
+		return $query_param_for_models;
625
+	}
626
+
627
+
628
+	/**
629
+	 * @param $condition_query_param_key
630
+	 * @return string
631
+	 */
632
+	public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
633
+	{
634
+		$pos_of_star = strpos($condition_query_param_key, '*');
635
+		if ($pos_of_star === false) {
636
+			return $condition_query_param_key;
637
+		}
638
+		return substr($condition_query_param_key, 0, $pos_of_star);
639
+	}
640
+
641
+
642
+	/**
643
+	 * Takes the input parameter and finds the model field that it indicates.
644
+	 *
645
+	 * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
646
+	 * @param EEM_Base $model
647
+	 * @return EE_Model_Field_Base
648
+	 * @throws EE_Error
649
+	 * @throws ReflectionException
650
+	 */
651
+	public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
652
+	{
653
+		// ok, now proceed with deducing which part is the model's name, and which is the field's name
654
+		// which will help us find the database table and column
655
+		$query_param_parts = explode('.', $query_param_name);
656
+		if (empty($query_param_parts)) {
657
+			throw new EE_Error(
658
+				sprintf(
659
+					esc_html__(
660
+						'_extract_column_name is empty when trying to extract column and table name from %s',
661
+						'event_espresso'
662
+					),
663
+					$query_param_name
664
+				)
665
+			);
666
+		}
667
+		$number_of_parts       = count($query_param_parts);
668
+		$last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
669
+		$field_name            = $last_query_param_part;
670
+		if ($number_of_parts !== 1) {
671
+			// the last part is the column name, and there are only 2parts. therefore...
672
+			$model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
673
+		}
674
+		try {
675
+			return $model->field_settings_for($field_name, false);
676
+		} catch (EE_Error $e) {
677
+			return null;
678
+		}
679
+	}
680
+
681
+
682
+	/**
683
+	 * Returns true if $data can be easily represented in JSON.
684
+	 * Basically, objects and resources can't be represented in JSON easily.
685
+	 *
686
+	 * @param mixed $data
687
+	 * @return bool
688
+	 */
689
+	protected static function isRepresentableInJson($data)
690
+	{
691
+		return is_scalar($data)
692
+			   || is_array($data)
693
+			   || is_null($data);
694
+	}
695 695
 }
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Attendee_Shortcodes.lib.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
             ? null
115 115
             : $this->_data;
116 116
 
117
-        if (! $registration instanceof EE_Registration) {
117
+        if ( ! $registration instanceof EE_Registration) {
118 118
             // let's attempt to get the txn_id for the error message.
119 119
             $txn_id  = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction
120 120
                 ? $this->_extra->txn->ID()
@@ -131,12 +131,12 @@  discard block
 block discarded – undo
131 131
         }
132 132
 
133 133
         // attendee obj for this registration
134
-        $attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj'])
135
-            ? $this->_extra->registrations[ $registration->ID() ]['att_obj']
134
+        $attendee = isset($this->_extra->registrations[$registration->ID()]['att_obj'])
135
+            ? $this->_extra->registrations[$registration->ID()]['att_obj']
136 136
             : null;
137 137
 
138
-        if (! $attendee instanceof EE_Attendee) {
139
-            $msg     = esc_html__(
138
+        if ( ! $attendee instanceof EE_Attendee) {
139
+            $msg = esc_html__(
140 140
                 'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.',
141 141
                 'event_espresso'
142 142
             );
Please login to merge, or discard this patch.
Indentation   +188 added lines, -188 removed lines patch added patch discarded remove patch
@@ -15,192 +15,192 @@
 block discarded – undo
15 15
  */
16 16
 class EE_Attendee_Shortcodes extends EE_Shortcodes
17 17
 {
18
-    /**
19
-     * hold all extra data.
20
-     *
21
-     * @var array
22
-     */
23
-    protected $_extra;
24
-
25
-
26
-    /**
27
-     * EE_Attendee_Shortcodes constructor.
28
-     */
29
-    public function __construct()
30
-    {
31
-        parent::__construct();
32
-    }
33
-
34
-
35
-    protected function _init_props()
36
-    {
37
-        $this->label       = esc_html__('Attendee Shortcodes', 'event_espresso');
38
-        $this->description = esc_html__('All shortcodes specific to attendee related data', 'event_espresso');
39
-        $this->_shortcodes = [
40
-            '[FNAME]'                          => esc_html__('First Name of an attendee.', 'event_espresso'),
41
-            '[LNAME]'                          => esc_html__('Last Name of an attendee.', 'event_espresso'),
42
-            '[ATTENDEE_EMAIL]'                 => esc_html__('Email address for the attendee.', 'event_espresso'),
43
-            '[EDIT_ATTENDEE_LINK]'             => esc_html__(
44
-                'Edit Registration Link (typically you\'d only use this for messages going to event administrators)',
45
-                'event_espresso'
46
-            ),
47
-            '[REGISTRATION_ID]'                => esc_html__(
48
-                'Unique Registration ID for the registration',
49
-                'event_espresso'
50
-            ),
51
-            '[REGISTRATION_CODE]'              => esc_html__(
52
-                'Unique Registration Code for the registration',
53
-                'event_espresso'
54
-            ),
55
-            '[REGISTRATION_STATUS_ID]'         => esc_html__(
56
-                'Parses to the registration status for the attendee',
57
-                'event_espresso'
58
-            ),
59
-            '[REGISTRATION_STATUS_LABEL]'      => esc_html__(
60
-                'Parses to the status label for the registrant',
61
-                'event_espresso'
62
-            ),
63
-            '[REGISTRATION_TOTAL_AMOUNT_PAID]' => esc_html__(
64
-                'Parses to the total amount paid for this registration.',
65
-                'event_espresso'
66
-            ),
67
-            '[FRONTEND_EDIT_REG_LINK]'         => esc_html__(
68
-                'Generates a link for the given registration to edit this registration details on the frontend.',
69
-                'event_espresso'
70
-            ),
71
-            '[PHONE_NUMBER]'                   => esc_html__(
72
-                'The Phone Number for the Registration.',
73
-                'event_espresso'
74
-            ),
75
-            '[ADDRESS]'                        => esc_html__('The Address for the Registration', 'event_espresso'),
76
-            '[ADDRESS2]'                       => esc_html__(
77
-                'Whatever was in the address 2 field for the registration.',
78
-                'event_espresso'
79
-            ),
80
-            '[CITY]'                           => esc_html__('The city for the registration.', 'event_espresso'),
81
-            '[ZIP_PC]'                         => esc_html__(
82
-                'The ZIP (or Postal) Code for the Registration.',
83
-                'event_espresso'
84
-            ),
85
-            '[ADDRESS_STATE]'                  => esc_html__(
86
-                'The state/province for the registration.',
87
-                'event_espresso'
88
-            ),
89
-            '[COUNTRY]'                        => esc_html__('The country for the registration.', 'event_espresso'),
90
-        ];
91
-    }
92
-
93
-
94
-    /**
95
-     * handles shortcode parsing
96
-     *
97
-     * @access protected
98
-     * @param string $shortcode the shortcode to be parsed.
99
-     * @return string
100
-     * @throws EE_Error
101
-     * @throws ReflectionException
102
-     */
103
-    protected function _parser($shortcode)
104
-    {
105
-
106
-
107
-        $this->_extra = ! empty($this->_extra_data) && $this->_extra_data['data'] instanceof EE_Messages_Addressee
108
-            ? $this->_extra_data['data']
109
-            : null;
110
-
111
-        // incoming object should only be a registration object.
112
-        $registration = ! $this->_data instanceof EE_Registration
113
-            ? null
114
-            : $this->_data;
115
-
116
-        if (! $registration instanceof EE_Registration) {
117
-            // let's attempt to get the txn_id for the error message.
118
-            $txn_id  = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction
119
-                ? $this->_extra->txn->ID()
120
-                : esc_html__('Unknown', 'event_espresso');
121
-            $msg     = esc_html__(
122
-                'There is no EE_Registration object in the data sent to the EE_Attendee Shortcode Parser for the messages system.',
123
-                'event_espresso'
124
-            );
125
-            $dev_msg = sprintf(
126
-                esc_html__('The transaction ID for this request is: %s', 'event_espresso'),
127
-                $txn_id
128
-            );
129
-            throw new EE_Error("{$msg}||{$msg} {$dev_msg}");
130
-        }
131
-
132
-        // attendee obj for this registration
133
-        $attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj'])
134
-            ? $this->_extra->registrations[ $registration->ID() ]['att_obj']
135
-            : null;
136
-
137
-        if (! $attendee instanceof EE_Attendee) {
138
-            $msg     = esc_html__(
139
-                'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.',
140
-                'event_espresso'
141
-            );
142
-            $dev_msg = sprintf(
143
-                esc_html__('The registration ID for this request is: %s', 'event_espresso'),
144
-                $registration->ID()
145
-            );
146
-            throw new EE_Error("{$msg}||{$msg} {$dev_msg}");
147
-        }
148
-
149
-        switch ($shortcode) {
150
-            case '[FNAME]':
151
-                return $attendee->fname();
152
-
153
-            case '[LNAME]':
154
-                return $attendee->lname();
155
-
156
-            case '[ATTENDEE_EMAIL]':
157
-                return $attendee->email();
158
-
159
-            case '[EDIT_ATTENDEE_LINK]':
160
-                return $registration->get_admin_edit_url();
161
-
162
-            case '[REGISTRATION_CODE]':
163
-                return $registration->reg_code();
164
-
165
-            case '[REGISTRATION_ID]':
166
-                return $registration->ID();
167
-
168
-            case '[FRONTEND_EDIT_REG_LINK]':
169
-                return $registration->edit_attendee_information_url();
170
-
171
-            case '[PHONE_NUMBER]':
172
-                return $attendee->phone();
173
-
174
-            case '[ADDRESS]':
175
-                return $attendee->address();
176
-
177
-            case '[ADDRESS2]':
178
-                return $attendee->address2();
179
-
180
-            case '[CITY]':
181
-                return $attendee->city();
182
-
183
-            case '[ZIP_PC]':
184
-                return $attendee->zip();
185
-
186
-            case '[ADDRESS_STATE]':
187
-                $state_obj = $attendee->state_obj();
188
-                return $state_obj instanceof EE_State ? $state_obj->name() : '';
189
-
190
-            case '[COUNTRY]':
191
-                $country_obj = $attendee->country_obj();
192
-                return $country_obj instanceof EE_Country ? $country_obj->name() : '';
193
-
194
-            case '[REGISTRATION_STATUS_ID]':
195
-                return $registration->status_ID();
196
-
197
-            case '[REGISTRATION_STATUS_LABEL]':
198
-                return $registration->pretty_status();
199
-
200
-            case '[REGISTRATION_TOTAL_AMOUNT_PAID]':
201
-                return $registration->pretty_paid();
202
-        }
203
-
204
-        return '';
205
-    }
18
+	/**
19
+	 * hold all extra data.
20
+	 *
21
+	 * @var array
22
+	 */
23
+	protected $_extra;
24
+
25
+
26
+	/**
27
+	 * EE_Attendee_Shortcodes constructor.
28
+	 */
29
+	public function __construct()
30
+	{
31
+		parent::__construct();
32
+	}
33
+
34
+
35
+	protected function _init_props()
36
+	{
37
+		$this->label       = esc_html__('Attendee Shortcodes', 'event_espresso');
38
+		$this->description = esc_html__('All shortcodes specific to attendee related data', 'event_espresso');
39
+		$this->_shortcodes = [
40
+			'[FNAME]'                          => esc_html__('First Name of an attendee.', 'event_espresso'),
41
+			'[LNAME]'                          => esc_html__('Last Name of an attendee.', 'event_espresso'),
42
+			'[ATTENDEE_EMAIL]'                 => esc_html__('Email address for the attendee.', 'event_espresso'),
43
+			'[EDIT_ATTENDEE_LINK]'             => esc_html__(
44
+				'Edit Registration Link (typically you\'d only use this for messages going to event administrators)',
45
+				'event_espresso'
46
+			),
47
+			'[REGISTRATION_ID]'                => esc_html__(
48
+				'Unique Registration ID for the registration',
49
+				'event_espresso'
50
+			),
51
+			'[REGISTRATION_CODE]'              => esc_html__(
52
+				'Unique Registration Code for the registration',
53
+				'event_espresso'
54
+			),
55
+			'[REGISTRATION_STATUS_ID]'         => esc_html__(
56
+				'Parses to the registration status for the attendee',
57
+				'event_espresso'
58
+			),
59
+			'[REGISTRATION_STATUS_LABEL]'      => esc_html__(
60
+				'Parses to the status label for the registrant',
61
+				'event_espresso'
62
+			),
63
+			'[REGISTRATION_TOTAL_AMOUNT_PAID]' => esc_html__(
64
+				'Parses to the total amount paid for this registration.',
65
+				'event_espresso'
66
+			),
67
+			'[FRONTEND_EDIT_REG_LINK]'         => esc_html__(
68
+				'Generates a link for the given registration to edit this registration details on the frontend.',
69
+				'event_espresso'
70
+			),
71
+			'[PHONE_NUMBER]'                   => esc_html__(
72
+				'The Phone Number for the Registration.',
73
+				'event_espresso'
74
+			),
75
+			'[ADDRESS]'                        => esc_html__('The Address for the Registration', 'event_espresso'),
76
+			'[ADDRESS2]'                       => esc_html__(
77
+				'Whatever was in the address 2 field for the registration.',
78
+				'event_espresso'
79
+			),
80
+			'[CITY]'                           => esc_html__('The city for the registration.', 'event_espresso'),
81
+			'[ZIP_PC]'                         => esc_html__(
82
+				'The ZIP (or Postal) Code for the Registration.',
83
+				'event_espresso'
84
+			),
85
+			'[ADDRESS_STATE]'                  => esc_html__(
86
+				'The state/province for the registration.',
87
+				'event_espresso'
88
+			),
89
+			'[COUNTRY]'                        => esc_html__('The country for the registration.', 'event_espresso'),
90
+		];
91
+	}
92
+
93
+
94
+	/**
95
+	 * handles shortcode parsing
96
+	 *
97
+	 * @access protected
98
+	 * @param string $shortcode the shortcode to be parsed.
99
+	 * @return string
100
+	 * @throws EE_Error
101
+	 * @throws ReflectionException
102
+	 */
103
+	protected function _parser($shortcode)
104
+	{
105
+
106
+
107
+		$this->_extra = ! empty($this->_extra_data) && $this->_extra_data['data'] instanceof EE_Messages_Addressee
108
+			? $this->_extra_data['data']
109
+			: null;
110
+
111
+		// incoming object should only be a registration object.
112
+		$registration = ! $this->_data instanceof EE_Registration
113
+			? null
114
+			: $this->_data;
115
+
116
+		if (! $registration instanceof EE_Registration) {
117
+			// let's attempt to get the txn_id for the error message.
118
+			$txn_id  = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction
119
+				? $this->_extra->txn->ID()
120
+				: esc_html__('Unknown', 'event_espresso');
121
+			$msg     = esc_html__(
122
+				'There is no EE_Registration object in the data sent to the EE_Attendee Shortcode Parser for the messages system.',
123
+				'event_espresso'
124
+			);
125
+			$dev_msg = sprintf(
126
+				esc_html__('The transaction ID for this request is: %s', 'event_espresso'),
127
+				$txn_id
128
+			);
129
+			throw new EE_Error("{$msg}||{$msg} {$dev_msg}");
130
+		}
131
+
132
+		// attendee obj for this registration
133
+		$attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj'])
134
+			? $this->_extra->registrations[ $registration->ID() ]['att_obj']
135
+			: null;
136
+
137
+		if (! $attendee instanceof EE_Attendee) {
138
+			$msg     = esc_html__(
139
+				'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.',
140
+				'event_espresso'
141
+			);
142
+			$dev_msg = sprintf(
143
+				esc_html__('The registration ID for this request is: %s', 'event_espresso'),
144
+				$registration->ID()
145
+			);
146
+			throw new EE_Error("{$msg}||{$msg} {$dev_msg}");
147
+		}
148
+
149
+		switch ($shortcode) {
150
+			case '[FNAME]':
151
+				return $attendee->fname();
152
+
153
+			case '[LNAME]':
154
+				return $attendee->lname();
155
+
156
+			case '[ATTENDEE_EMAIL]':
157
+				return $attendee->email();
158
+
159
+			case '[EDIT_ATTENDEE_LINK]':
160
+				return $registration->get_admin_edit_url();
161
+
162
+			case '[REGISTRATION_CODE]':
163
+				return $registration->reg_code();
164
+
165
+			case '[REGISTRATION_ID]':
166
+				return $registration->ID();
167
+
168
+			case '[FRONTEND_EDIT_REG_LINK]':
169
+				return $registration->edit_attendee_information_url();
170
+
171
+			case '[PHONE_NUMBER]':
172
+				return $attendee->phone();
173
+
174
+			case '[ADDRESS]':
175
+				return $attendee->address();
176
+
177
+			case '[ADDRESS2]':
178
+				return $attendee->address2();
179
+
180
+			case '[CITY]':
181
+				return $attendee->city();
182
+
183
+			case '[ZIP_PC]':
184
+				return $attendee->zip();
185
+
186
+			case '[ADDRESS_STATE]':
187
+				$state_obj = $attendee->state_obj();
188
+				return $state_obj instanceof EE_State ? $state_obj->name() : '';
189
+
190
+			case '[COUNTRY]':
191
+				$country_obj = $attendee->country_obj();
192
+				return $country_obj instanceof EE_Country ? $country_obj->name() : '';
193
+
194
+			case '[REGISTRATION_STATUS_ID]':
195
+				return $registration->status_ID();
196
+
197
+			case '[REGISTRATION_STATUS_LABEL]':
198
+				return $registration->pretty_status();
199
+
200
+			case '[REGISTRATION_TOTAL_AMOUNT_PAID]':
201
+				return $registration->pretty_paid();
202
+		}
203
+
204
+		return '';
205
+	}
206 206
 }
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Attendee_List_Shortcodes.lib.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
         $att_result    = '';
160 160
         $registrations =
161 161
             isset($this->_extra_data['data']->tickets)
162
-                ? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs']
162
+                ? $this->_extra_data['data']->tickets[$ticket->ID()]['reg_objs']
163 163
                 : [];
164 164
 
165 165
         // each attendee in this case should be an attendee object.
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
     private function _get_registrations_from_event(EE_Event $event)
186 186
     {
187 187
         return isset($this->_extra_data['data']->events)
188
-            ? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs']
188
+            ? $this->_extra_data['data']->events[$event->ID()]['reg_objs']
189 189
             : [];
190 190
     }
191 191
 }
Please login to merge, or discard this patch.
Indentation   +163 added lines, -163 removed lines patch added patch discarded remove patch
@@ -18,167 +18,167 @@
 block discarded – undo
18 18
  */
19 19
 class EE_Attendee_List_Shortcodes extends EE_Shortcodes
20 20
 {
21
-    protected function _init_props()
22
-    {
23
-        $this->label       = esc_html__('Attendee List Shortcodes', 'event_espresso');
24
-        $this->description = esc_html__('All shortcodes specific to attendee lists', 'event_espresso');
25
-        $this->_shortcodes = [
26
-            '[ATTENDEE_LIST]' => esc_html__('Will output a list of attendees', 'event_espresso'),
27
-        ];
28
-    }
29
-
30
-
31
-    /**
32
-     * @param string $shortcode
33
-     * @return string
34
-     * @throws EE_Error
35
-     * @throws ReflectionException
36
-     */
37
-    protected function _parser($shortcode)
38
-    {
39
-        switch ($shortcode) {
40
-            case '[ATTENDEE_LIST]':
41
-                return $this->_get_attendee_list();
42
-        }
43
-        return '';
44
-    }
45
-
46
-
47
-    /**
48
-     * figure out what the incoming data is and then return the appropriate parsed value.
49
-     *
50
-     * @return string
51
-     * @throws EE_Error
52
-     * @throws ReflectionException
53
-     */
54
-    private function _get_attendee_list()
55
-    {
56
-        $this->_validate_list_requirements();
57
-
58
-        if ($this->_data['data'] instanceof EE_Messages_Addressee) {
59
-            return $this->_get_attendee_list_for_main();
60
-        }
61
-        if ($this->_data['data'] instanceof EE_Event) {
62
-            return $this->_get_attendee_list_for_event();
63
-        }
64
-        if ($this->_data['data'] instanceof EE_Ticket) {
65
-            return $this->_get_registration_list_for_ticket();
66
-        }
67
-        // prevent recursive loop
68
-        return '';
69
-    }
70
-
71
-
72
-    /**
73
-     * This returns the parsed attendee list for main template;
74
-     */
75
-    private function _get_attendee_list_for_main()
76
-    {
77
-        $valid_shortcodes = ['attendee', 'event_list', 'ticket_list', 'question_list', 'recipient_details'];
78
-        $template         = $this->_data['template'];
79
-        $data             = $this->_data['data'];
80
-        $attendees        = '';
81
-
82
-
83
-        // now we need to loop through the attendee list and send data to the EE_Parser helper.
84
-        foreach ($data->reg_objs as $registration) {
85
-            $attendees .= $this->_shortcode_helper->parse_attendee_list_template(
86
-                $template,
87
-                $registration,
88
-                $valid_shortcodes,
89
-                $this->_extra_data
90
-            );
91
-        }
92
-
93
-        return $attendees;
94
-    }
95
-
96
-
97
-    /**
98
-     * return parsed list of attendees for an event
99
-     *
100
-     * @return string
101
-     * @throws EE_Error
102
-     * @throws ReflectionException
103
-     */
104
-    private function _get_attendee_list_for_event()
105
-    {
106
-        $valid_shortcodes = ['attendee', 'ticket_list', 'question_list', 'recipient_details'];
107
-        $template         = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list'])
108
-            ? $this->_data['template']['attendee_list']
109
-            : $this->_extra_data['template']['attendee_list'];
110
-        $event            = $this->_data['data'];
111
-
112
-        // let's remove any existing [EVENT_LIST] shortcode from the attendee list template so that we don't get recursion.
113
-        $template = str_replace('[EVENT_LIST]', '', $template);
114
-
115
-        // here we're setting up the attendees for the attendee_list template for THIS event.
116
-        $att_result    = '';
117
-        $registrations = $this->_get_registrations_from_event($event);
118
-
119
-        // each attendee in this case should be an attendee object.
120
-        foreach ($registrations as $registration) {
121
-            $att_result .= $this->_shortcode_helper->parse_attendee_list_template(
122
-                $template,
123
-                $registration,
124
-                $valid_shortcodes,
125
-                $this->_extra_data
126
-            );
127
-        }
128
-
129
-        return $att_result;
130
-    }
131
-
132
-
133
-    /**
134
-     * return parsed list of attendees for a ticket
135
-     *
136
-     * @return string
137
-     */
138
-    private function _get_registration_list_for_ticket()
139
-    {
140
-        $valid_shortcodes = ['attendee', 'event_list', 'question_list', 'recipient_details'];
141
-        $template         = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list'])
142
-            ? $this->_data['template']['attendee_list']
143
-            : $this->_extra_data['template']['attendee_list'];
144
-        $ticket           = $this->_data['data'];
145
-
146
-        // let's remove any existing [TICKET_LIST] (or related) shortcode from the attendee list template so that we don't get recursion.
147
-        $template = str_replace('[TICKET_LIST]', '', $template);
148
-        $template = str_replace('[RECIPIENT_TICKET_LIST]', '', $template);
149
-        $template = str_replace('[PRIMARY_REGISTRANT_TICKET_LIST]', '', $template);
150
-
151
-        // here we're setting up the attendees for the attendee_list template for THIS ticket.
152
-        $att_result    = '';
153
-        $registrations =
154
-            isset($this->_extra_data['data']->tickets)
155
-                ? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs']
156
-                : [];
157
-
158
-        // each attendee in this case should be an attendee object.
159
-        foreach ($registrations as $registration) {
160
-            $att_result .= $this->_shortcode_helper->parse_attendee_list_template(
161
-                $template,
162
-                $registration,
163
-                $valid_shortcodes,
164
-                $this->_extra_data
165
-            );
166
-        }
167
-
168
-        return $att_result;
169
-    }
170
-
171
-
172
-    /**
173
-     * @param EE_Event $event
174
-     * @return array|mixed
175
-     * @throws EE_Error
176
-     * @throws ReflectionException
177
-     */
178
-    private function _get_registrations_from_event(EE_Event $event)
179
-    {
180
-        return isset($this->_extra_data['data']->events)
181
-            ? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs']
182
-            : [];
183
-    }
21
+	protected function _init_props()
22
+	{
23
+		$this->label       = esc_html__('Attendee List Shortcodes', 'event_espresso');
24
+		$this->description = esc_html__('All shortcodes specific to attendee lists', 'event_espresso');
25
+		$this->_shortcodes = [
26
+			'[ATTENDEE_LIST]' => esc_html__('Will output a list of attendees', 'event_espresso'),
27
+		];
28
+	}
29
+
30
+
31
+	/**
32
+	 * @param string $shortcode
33
+	 * @return string
34
+	 * @throws EE_Error
35
+	 * @throws ReflectionException
36
+	 */
37
+	protected function _parser($shortcode)
38
+	{
39
+		switch ($shortcode) {
40
+			case '[ATTENDEE_LIST]':
41
+				return $this->_get_attendee_list();
42
+		}
43
+		return '';
44
+	}
45
+
46
+
47
+	/**
48
+	 * figure out what the incoming data is and then return the appropriate parsed value.
49
+	 *
50
+	 * @return string
51
+	 * @throws EE_Error
52
+	 * @throws ReflectionException
53
+	 */
54
+	private function _get_attendee_list()
55
+	{
56
+		$this->_validate_list_requirements();
57
+
58
+		if ($this->_data['data'] instanceof EE_Messages_Addressee) {
59
+			return $this->_get_attendee_list_for_main();
60
+		}
61
+		if ($this->_data['data'] instanceof EE_Event) {
62
+			return $this->_get_attendee_list_for_event();
63
+		}
64
+		if ($this->_data['data'] instanceof EE_Ticket) {
65
+			return $this->_get_registration_list_for_ticket();
66
+		}
67
+		// prevent recursive loop
68
+		return '';
69
+	}
70
+
71
+
72
+	/**
73
+	 * This returns the parsed attendee list for main template;
74
+	 */
75
+	private function _get_attendee_list_for_main()
76
+	{
77
+		$valid_shortcodes = ['attendee', 'event_list', 'ticket_list', 'question_list', 'recipient_details'];
78
+		$template         = $this->_data['template'];
79
+		$data             = $this->_data['data'];
80
+		$attendees        = '';
81
+
82
+
83
+		// now we need to loop through the attendee list and send data to the EE_Parser helper.
84
+		foreach ($data->reg_objs as $registration) {
85
+			$attendees .= $this->_shortcode_helper->parse_attendee_list_template(
86
+				$template,
87
+				$registration,
88
+				$valid_shortcodes,
89
+				$this->_extra_data
90
+			);
91
+		}
92
+
93
+		return $attendees;
94
+	}
95
+
96
+
97
+	/**
98
+	 * return parsed list of attendees for an event
99
+	 *
100
+	 * @return string
101
+	 * @throws EE_Error
102
+	 * @throws ReflectionException
103
+	 */
104
+	private function _get_attendee_list_for_event()
105
+	{
106
+		$valid_shortcodes = ['attendee', 'ticket_list', 'question_list', 'recipient_details'];
107
+		$template         = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list'])
108
+			? $this->_data['template']['attendee_list']
109
+			: $this->_extra_data['template']['attendee_list'];
110
+		$event            = $this->_data['data'];
111
+
112
+		// let's remove any existing [EVENT_LIST] shortcode from the attendee list template so that we don't get recursion.
113
+		$template = str_replace('[EVENT_LIST]', '', $template);
114
+
115
+		// here we're setting up the attendees for the attendee_list template for THIS event.
116
+		$att_result    = '';
117
+		$registrations = $this->_get_registrations_from_event($event);
118
+
119
+		// each attendee in this case should be an attendee object.
120
+		foreach ($registrations as $registration) {
121
+			$att_result .= $this->_shortcode_helper->parse_attendee_list_template(
122
+				$template,
123
+				$registration,
124
+				$valid_shortcodes,
125
+				$this->_extra_data
126
+			);
127
+		}
128
+
129
+		return $att_result;
130
+	}
131
+
132
+
133
+	/**
134
+	 * return parsed list of attendees for a ticket
135
+	 *
136
+	 * @return string
137
+	 */
138
+	private function _get_registration_list_for_ticket()
139
+	{
140
+		$valid_shortcodes = ['attendee', 'event_list', 'question_list', 'recipient_details'];
141
+		$template         = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list'])
142
+			? $this->_data['template']['attendee_list']
143
+			: $this->_extra_data['template']['attendee_list'];
144
+		$ticket           = $this->_data['data'];
145
+
146
+		// let's remove any existing [TICKET_LIST] (or related) shortcode from the attendee list template so that we don't get recursion.
147
+		$template = str_replace('[TICKET_LIST]', '', $template);
148
+		$template = str_replace('[RECIPIENT_TICKET_LIST]', '', $template);
149
+		$template = str_replace('[PRIMARY_REGISTRANT_TICKET_LIST]', '', $template);
150
+
151
+		// here we're setting up the attendees for the attendee_list template for THIS ticket.
152
+		$att_result    = '';
153
+		$registrations =
154
+			isset($this->_extra_data['data']->tickets)
155
+				? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs']
156
+				: [];
157
+
158
+		// each attendee in this case should be an attendee object.
159
+		foreach ($registrations as $registration) {
160
+			$att_result .= $this->_shortcode_helper->parse_attendee_list_template(
161
+				$template,
162
+				$registration,
163
+				$valid_shortcodes,
164
+				$this->_extra_data
165
+			);
166
+		}
167
+
168
+		return $att_result;
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param EE_Event $event
174
+	 * @return array|mixed
175
+	 * @throws EE_Error
176
+	 * @throws ReflectionException
177
+	 */
178
+	private function _get_registrations_from_event(EE_Event $event)
179
+	{
180
+		return isset($this->_extra_data['data']->events)
181
+			? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs']
182
+			: [];
183
+	}
184 184
 }
Please login to merge, or discard this patch.
core/domain/services/admin/privacy/policy/privacy_policy.template.php 2 patches
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -7,10 +7,10 @@  discard block
 block discarded – undo
7 7
 ?>
8 8
 <h2><?php esc_html_e('Event Registration Data', 'event_espresso'); ?></h2>
9 9
 <p><?php
10
-    esc_html_e(
11
-        'We collect information about you during event registration. This information may include but is not limited to:',
12
-        'event_espresso'
13
-    ); ?></p>
10
+	esc_html_e(
11
+		'We collect information about you during event registration. This information may include but is not limited to:',
12
+		'event_espresso'
13
+	); ?></p>
14 14
 <ul>
15 15
     <li><?php esc_html_e('Your names', 'event_espresso'); ?></li>
16 16
     <li><?php esc_html_e('Billing address', 'event_espresso'); ?></li>
@@ -18,16 +18,16 @@  discard block
 block discarded – undo
18 18
     <li><?php esc_html_e('Email address', 'event_espresso'); ?></li>
19 19
     <li><?php esc_html_e('Phone number', 'event_espresso'); ?></li>
20 20
     <li><?php
21
-        esc_html_e(
22
-            'Location and traffic data (including partial IP address and browser type)',
23
-            'event_espresso'
24
-        ); ?>
21
+		esc_html_e(
22
+			'Location and traffic data (including partial IP address and browser type)',
23
+			'event_espresso'
24
+		); ?>
25 25
     </li>
26 26
     <li><?php
27
-        esc_html_e(
28
-            'Any other details that might be requested from you for the purpose of processing your registration or ticket purchase',
29
-            'event_espresso'
30
-        ); ?>
27
+		esc_html_e(
28
+			'Any other details that might be requested from you for the purpose of processing your registration or ticket purchase',
29
+			'event_espresso'
30
+		); ?>
31 31
     </li>
32 32
 </ul>
33 33
 
@@ -36,101 +36,101 @@  discard block
 block discarded – undo
36 36
     <li><?php esc_html_e('Send you important account/purchase/service information.', 'event_espresso'); ?></li>
37 37
     <li><?php esc_html_e('Respond to your queries, refund requests, or complaints.', 'event_espresso'); ?></li>
38 38
     <li><?php
39
-        esc_html_e(
40
-            'Process payments and prevent fraudulent transactions. We do this on the basis of our legitimate business interests.',
41
-            'event_espresso'
42
-        ); ?></li>
39
+		esc_html_e(
40
+			'Process payments and prevent fraudulent transactions. We do this on the basis of our legitimate business interests.',
41
+			'event_espresso'
42
+		); ?></li>
43 43
     <li><?php
44
-        esc_html_e(
45
-            'Set up and administer your account, provide technical and customer support, and to verify your identity.',
46
-            'event_espresso'
47
-        ); ?></li>
44
+		esc_html_e(
45
+			'Set up and administer your account, provide technical and customer support, and to verify your identity.',
46
+			'event_espresso'
47
+		); ?></li>
48 48
 </ul>
49 49
 
50 50
 <?php if (! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?>
51 51
     <h2><?php esc_html_e('Billing Information', 'event_espresso'); ?> </h2>
52 52
     <?php
53
-    // if onsite or offsite payment methods are active
54
-    if (! empty($active_onsite_payment_methods)) { ?>
53
+	// if onsite or offsite payment methods are active
54
+	if (! empty($active_onsite_payment_methods)) { ?>
55 55
         <p><?php
56
-            esc_html_e(
57
-                'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.',
58
-                'event_espresso'
59
-            ); ?></p>
56
+			esc_html_e(
57
+				'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.',
58
+				'event_espresso'
59
+			); ?></p>
60 60
         <p><?php
61
-            printf(
62
-                esc_html_x(
63
-                    'Please see the privacy policy of %1$s.',
64
-                    'Please see the privacy policy of PayPal Pro',
65
-                    'event_espresso'
66
-                ),
67
-                implode(
68
-                    ', ',
69
-                    array_merge(
70
-                        $active_onsite_payment_methods,
71
-                        $active_offsite_payment_methods
72
-                    )
73
-                )
74
-            ); ?></p>
61
+			printf(
62
+				esc_html_x(
63
+					'Please see the privacy policy of %1$s.',
64
+					'Please see the privacy policy of PayPal Pro',
65
+					'event_espresso'
66
+				),
67
+				implode(
68
+					', ',
69
+					array_merge(
70
+						$active_onsite_payment_methods,
71
+						$active_offsite_payment_methods
72
+					)
73
+				)
74
+			); ?></p>
75 75
         <p><?php
76
-            esc_html_e(
77
-                'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).',
78
-                'event_espresso'
79
-            ); ?></p>
76
+			esc_html_e(
77
+				'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).',
78
+				'event_espresso'
79
+			); ?></p>
80 80
     <?php } elseif (! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?>
81 81
         <p><?php
82
-            printf(
83
-                esc_html_x(
84
-                    'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of %1$s.',
85
-                    'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of PayPal Pro.',
86
-                    'event_espresso'
87
-                ),
88
-                implode(', ', $active_offsite_payment_methods)
89
-            ); ?></p>
82
+			printf(
83
+				esc_html_x(
84
+					'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of %1$s.',
85
+					'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of PayPal Pro.',
86
+					'event_espresso'
87
+				),
88
+				implode(', ', $active_offsite_payment_methods)
89
+			); ?></p>
90 90
     <?php } ?>
91 91
     <h2><?php esc_html_e('Payment Logging', 'event_espresso'); ?></h2>
92 92
     <p><?php
93
-        esc_html_e(
94
-            'Site administrators may keep a log of communications with the payment processors in order to verify payments are being processed correctly. These logs are automatically deleted after a week.',
95
-            'event_espresso'
96
-        ); ?></p>
93
+		esc_html_e(
94
+			'Site administrators may keep a log of communications with the payment processors in order to verify payments are being processed correctly. These logs are automatically deleted after a week.',
95
+			'event_espresso'
96
+		); ?></p>
97 97
 <?php } ?>
98 98
 
99 99
 <h2><?php esc_html_e('Event Registration Cookies', 'event_espresso'); ?></h2>
100 100
 <p><?php
101
-    printf(
102
-        esc_html_x(
103
-            'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts %1$s.',
104
-            'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts 2 hours.',
105
-            'event_espresso'
106
-        ),
107
-        $session_lifespan
108
-    ); ?></p>
101
+	printf(
102
+		esc_html_x(
103
+			'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts %1$s.',
104
+			'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts 2 hours.',
105
+			'event_espresso'
106
+		),
107
+		$session_lifespan
108
+	); ?></p>
109 109
 
110 110
 <h2><?php esc_html_e('Email History Data', 'event_espresso'); ?></h2>
111 111
 <p><?php
112
-    esc_html_e(
113
-        'We keep a record of the emails sent to you. This is to ensure communication is successfully sent and its information is accurate.',
114
-        'event_espresso'
115
-    ); ?></p>
112
+	esc_html_e(
113
+		'We keep a record of the emails sent to you. This is to ensure communication is successfully sent and its information is accurate.',
114
+		'event_espresso'
115
+	); ?></p>
116 116
 
117 117
 <h2><?php esc_html_e('Event Check-In Record', 'event_espresso'); ?></h2>
118 118
 <p><?php
119
-    esc_html_e(
120
-        'When you attend an event, an event manager may record the time you check in or out of the event.',
121
-        'event_espresso'
122
-    ); ?></p>
119
+	esc_html_e(
120
+		'When you attend an event, an event manager may record the time you check in or out of the event.',
121
+		'event_espresso'
122
+	); ?></p>
123 123
 
124 124
 <h2><?php esc_html_e('Event Registration Data Retention', 'event_espresso'); ?></h2>
125 125
 <p><?php
126
-    esc_html_e(
127
-        'Personal data is stored at least until the date of the event, and may be kept indefinitely in case of future registrations.',
128
-        'event_espresso'
129
-    ); ?></p>
126
+	esc_html_e(
127
+		'Personal data is stored at least until the date of the event, and may be kept indefinitely in case of future registrations.',
128
+		'event_espresso'
129
+	); ?></p>
130 130
 
131 131
 <h2><?php esc_html_e('Event Registration Data Erasure and Export', 'event_espresso'); ?></h2>
132 132
 <p><?php
133
-    esc_html_e(
134
-        'You have the right to request your personal data be sent to you electronically, and the right to request your registration data be erased after the event. To do so, please contact the event manager or site administrator.',
135
-        'event_espresso'
136
-    ); ?></p>
133
+	esc_html_e(
134
+		'You have the right to request your personal data be sent to you electronically, and the right to request your registration data be erased after the event. To do so, please contact the event manager or site administrator.',
135
+		'event_espresso'
136
+	); ?></p>
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -47,11 +47,11 @@  discard block
 block discarded – undo
47 47
         ); ?></li>
48 48
 </ul>
49 49
 
50
-<?php if (! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?>
50
+<?php if ( ! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?>
51 51
     <h2><?php esc_html_e('Billing Information', 'event_espresso'); ?> </h2>
52 52
     <?php
53 53
     // if onsite or offsite payment methods are active
54
-    if (! empty($active_onsite_payment_methods)) { ?>
54
+    if ( ! empty($active_onsite_payment_methods)) { ?>
55 55
         <p><?php
56 56
             esc_html_e(
57 57
                 'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.',
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
                 'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).',
78 78
                 'event_espresso'
79 79
             ); ?></p>
80
-    <?php } elseif (! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?>
80
+    <?php } elseif ( ! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?>
81 81
         <p><?php
82 82
             printf(
83 83
                 esc_html_x(
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/loop-espresso_events.php 2 patches
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -11,48 +11,48 @@
 block discarded – undo
11 11
  * @version     4+
12 12
  */
13 13
 if (have_posts()) :
14
-    if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
14
+	if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
15 15
         <header class="page-header">
16 16
             <h1 class="page-title">
17 17
                 <?php
18
-                if (is_day()) :
19
-                    printf(esc_html__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
-                elseif (is_month()) :
21
-                    printf(
22
-                        esc_html__('Events This Month: %s', 'event_espresso'),
23
-                        get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
-                    );
25
-                elseif (is_year()) :
26
-                    printf(
27
-                        esc_html__('Events This Year: %s', 'event_espresso'),
28
-                        get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
-                    );
30
-                else :
31
-                    echo apply_filters(
32
-                        'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
-                        esc_html__('Upcoming Events', 'event_espresso')
34
-                    );
35
-                endif;
36
-                ?>
18
+				if (is_day()) :
19
+					printf(esc_html__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
+				elseif (is_month()) :
21
+					printf(
22
+						esc_html__('Events This Month: %s', 'event_espresso'),
23
+						get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
+					);
25
+				elseif (is_year()) :
26
+					printf(
27
+						esc_html__('Events This Year: %s', 'event_espresso'),
28
+						get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
+					);
30
+				else :
31
+					echo apply_filters(
32
+						'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
+						esc_html__('Upcoming Events', 'event_espresso')
34
+					);
35
+				endif;
36
+				?>
37 37
             </h1>
38 38
 
39 39
         </header><!-- .page-header -->
40 40
 
41 41
         <?php
42
-    endif;
43
-    // allow other stuff
44
-    do_action('AHEE__archive_espresso_events_template__before_loop');
45
-    // Start the Loop.
46
-    while (have_posts()) : the_post();
47
-        // Include the post TYPE-specific template for the content.
48
-        espresso_get_template_part('content', 'espresso_events-shortcode');
49
-    endwhile;
50
-    // Previous/next page navigation.
51
-    espresso_pagination();
52
-    // allow moar other stuff
53
-    do_action('AHEE__archive_espresso_events_template__after_loop');
42
+	endif;
43
+	// allow other stuff
44
+	do_action('AHEE__archive_espresso_events_template__before_loop');
45
+	// Start the Loop.
46
+	while (have_posts()) : the_post();
47
+		// Include the post TYPE-specific template for the content.
48
+		espresso_get_template_part('content', 'espresso_events-shortcode');
49
+	endwhile;
50
+	// Previous/next page navigation.
51
+	espresso_pagination();
52
+	// allow moar other stuff
53
+	do_action('AHEE__archive_espresso_events_template__after_loop');
54 54
 else :
55
-    // If no content, include the "No posts found" template.
56
-    espresso_get_template_part('content', 'none');
55
+	// If no content, include the "No posts found" template.
56
+	espresso_get_template_part('content', 'none');
57 57
 endif;
58 58
 
Please login to merge, or discard this patch.
Braces   +6 added lines, -2 removed lines patch added patch discarded remove patch
@@ -27,11 +27,13 @@  discard block
 block discarded – undo
27 27
                         esc_html__('Events This Year: %s', 'event_espresso'),
28 28
                         get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29 29
                     );
30
-                else :
30
+                else {
31
+                	:
31 32
                     echo apply_filters(
32 33
                         'FHEE__archive_espresso_events_template__upcoming_events_h1',
33 34
                         esc_html__('Upcoming Events', 'event_espresso')
34 35
                     );
36
+                }
35 37
                 endif;
36 38
                 ?>
37 39
             </h1>
@@ -51,8 +53,10 @@  discard block
 block discarded – undo
51 53
     espresso_pagination();
52 54
     // allow moar other stuff
53 55
     do_action('AHEE__archive_espresso_events_template__after_loop');
54
-else :
56
+else {
57
+	:
55 58
     // If no content, include the "No posts found" template.
56 59
     espresso_get_template_part('content', 'none');
60
+}
57 61
 endif;
58 62
 
Please login to merge, or discard this patch.