PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.12.2
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.12.2
1.8.13.1 1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 All 212 releases
charitable / includes / libraries / wp-session / class-wp-session.php

class-wp-session.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.12.2, at includes/libraries/wp-session/class-wp-session.php

243 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WordPress session managment.
4 *
5 * Standardizes WordPress session data using database-backed options for storage.
6 * for storing user session information.
7 *
8 * @package WordPress
9 * @subpackage Session
10 * @since 3.7.0
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 /**
19 * WordPress Session class for managing user session data.
20 *
21 * @package WordPress
22 * @since 3.7.0
23 */
24 final class WP_Session extends Recursive_ArrayAccess { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- This is a bundled library class. Changing it would break existing functionality.
25 /**
26 * ID of the current session.
27 *
28 * @var string
29 */
30 public $session_id;
31
32 /**
33 * Unix timestamp when session expires.
34 *
35 * @var int
36 */
37 protected $expires;
38
39 /**
40 * Unix timestamp indicating when the expiration time needs to be reset.
41 *
42 * @var int
43 */
44 protected $exp_variant;
45
46 /**
47 * Singleton instance.
48 *
49 * @var WP_Session
50 */
51 private static $instance;
52
53 /**
54 * Retrieve the current session instance.
55 *
56 * @return WP_Session
57 */
58 public static function get_instance() {
59 if ( ! isset( self::$instance ) ) {
60 self::$instance = new self();
61 }
62
63 return self::$instance;
64 }
65
66 /**
67 * Default constructor.
68 * Will rebuild the session collection from the given session ID if it exists. Otherwise, will
69 * create a new session with that ID.
70 *
71 * @param $session_id
72 */
73 protected function __construct() {
74 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Cookie data, handled by stripslashes and sanitized by preg_replace below
75 if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) {
76 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Cookie data, sanitized by preg_replace below
77 $cookie = stripslashes( wp_unslash( $_COOKIE[WP_SESSION_COOKIE] ) );
78 $cookie_crumbs = explode( '||', $cookie );
79
80 $this->session_id = preg_replace("/[^A-Za-z0-9_]/", '', $cookie_crumbs[0] );
81 $this->expires = absint( $cookie_crumbs[1] );
82 $this->exp_variant = absint( $cookie_crumbs[2] );
83
84 // Update the session expiration if we're past the variant time
85 if ( time() > $this->exp_variant ) {
86 $this->set_expiration();
87 delete_option( "_wp_session_expires_{$this->session_id}" );
88 add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
89 }
90
91 $this->read_data();
92 } else {
93 $this->session_id = '';
94 $this->container = array();
95 }
96 }
97
98 /**
99 * Set both the expiration time and the expiration variant.
100 *
101 * If the current time is below the variant, we don't update the session's expiration time. If it's
102 * greater than the variant, then we update the expiration time in the database. This prevents
103 * writing to the database on every page load for active sessions and only updates the expiration
104 * time if we're nearing when the session actually expires.
105 *
106 * By default, the expiration time is set to 30 minutes.
107 * By default, the expiration variant is set to 24 minutes.
108 *
109 * As a result, the session expiration time - at a maximum - will only be written to the database once
110 * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by
111 * the browser, and the old session will be queued for deletion by the garbage collector.
112 *
113 * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
114 * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
115 */
116 protected function set_expiration() {
117 $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a bundled library hook. Changing it would break existing functionality.
118 $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a bundled library hook. Changing it would break existing functionality.
119 }
120
121 /**
122 * Set the session cookie
123 *
124 * @uses apply_filters Calls `wp_session_cookie_secure` to set the $secure parameter of setcookie()
125 * @uses apply_filters Calls `wp_session_cookie_httponly` to set the $httponly parameter of setcookie()
126 */
127 protected function set_cookie() {
128 $secure = apply_filters( 'wp_session_cookie_secure', false ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a bundled library hook. Changing it would break existing functionality.
129 $httponly = apply_filters( 'wp_session_cookie_httponly', false ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a bundled library hook. Changing it would break existing functionality.
130 setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant,
131 $this->expires,
132 COOKIEPATH,
133 COOKIE_DOMAIN,
134 $secure,
135 $httponly
136 );
137 }
138
139 /**
140 * Read data from a transient for the current session.
141 *
142 * Automatically resets the expiration time for the session transient to some time in the future.
143 *
144 * @return array
145 */
146 protected function read_data() {
147 $this->container = get_option( "_wp_session_{$this->session_id}", array() );
148
149 return $this->container;
150 }
151
152 /**
153 * Write the data from the current session to the data storage system.
154 */
155 public function write_data() {
156 /* Nothing has changed. */
157 if ( ! $this->dirty ) {
158 return;
159 }
160
161 if ( empty( $this->container ) ) {
162 delete_option( "_wp_session_{$this->session_id}" );
163 delete_option( "_wp_session_expires_{$this->session_id}" );
164 return;
165 }
166
167 if ( false === get_option( "_wp_session_{$this->session_id}" ) ) {
168 add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
169 add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
170 } else {
171 delete_option( "_wp_session_{$this->session_id}" );
172 add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
173 }
174 }
175
176 /**
177 * Output the current container contents as a JSON-encoded string.
178 *
179 * @return string
180 */
181 public function json_out() {
182 return wp_json_encode( $this->container );
183 }
184
185 /**
186 * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
187 *
188 * @param string $data
189 *
190 * @return bool
191 */
192 public function json_in( $data ) {
193 $array = json_decode( $data );
194
195 if ( is_array( $array ) ) {
196 $this->container = $array;
197 return true;
198 }
199
200 return false;
201 }
202
203 /**
204 * Regenerate the current session's ID.
205 *
206 * @param bool $delete_old Flag whether or not to delete the old session data from the server.
207 */
208 public function regenerate_id( $delete_old = false ) {
209 if ( $delete_old ) {
210 delete_option( "_wp_session_{$this->session_id}" );
211 }
212
213 $this->session_id = WP_Session_Utils::generate_id();
214
215 $this->set_cookie();
216 }
217
218 /**
219 * Check if a session has been initialized.
220 *
221 * @return bool
222 */
223 public function session_started() {
224 return !!self::$instance;
225 }
226
227 /**
228 * Return the read-only cache expiration value.
229 *
230 * @return int
231 */
232 public function cache_expiration() {
233 return $this->expires;
234 }
235
236 /**
237 * Flushes all session variables.
238 */
239 public function reset() {
240 $this->container = array();
241 }
242 }
243