PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.3.4
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.3.4
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 1.7.0.9 1.8.0 All 210 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.3.4, at includes/libraries/wp-session/class-wp-session.php

314 lines 7.7 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' ) ) exit;
15
16 /**
17 * WordPress Session class for managing user session data.
18 *
19 * @package WordPress
20 * @since 3.7.0
21 */
22 final class WP_Session extends Recursive_ArrayAccess implements Iterator, Countable {
23 /**
24 * ID of the current session.
25 *
26 * @var string
27 */
28 public $session_id;
29
30 /**
31 * Unix timestamp when session expires.
32 *
33 * @var int
34 */
35 protected $expires;
36
37 /**
38 * Unix timestamp indicating when the expiration time needs to be reset.
39 *
40 * @var int
41 */
42 protected $exp_variant;
43
44 /**
45 * Singleton instance.
46 *
47 * @var bool|WP_Session
48 */
49 private static $instance = false;
50
51 /**
52 * Retrieve the current session instance.
53 *
54 * @param bool $session_id Session ID from which to populate data.
55 *
56 * @return bool|WP_Session
57 */
58 public static function get_instance() {
59 if ( ! 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 * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
73 */
74 protected function __construct() {
75 if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) {
76 $cookie = stripslashes( $_COOKIE[WP_SESSION_COOKIE] );
77 $cookie_crumbs = explode( '||', $cookie );
78
79 $this->session_id = $cookie_crumbs[0];
80 $this->expires = $cookie_crumbs[1];
81 $this->exp_variant = $cookie_crumbs[2];
82
83 // Update the session expiration if we're past the variant time
84 if ( time() > $this->exp_variant ) {
85 $this->set_expiration();
86 delete_option( "_wp_session_expires_{$this->session_id}" );
87 add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
88 }
89 } else {
90 $this->session_id = $this->generate_id();
91 $this->set_expiration();
92 }
93
94 $this->read_data();
95
96 $this->set_cookie();
97
98 }
99
100 /**
101 * Set both the expiration time and the expiration variant.
102 *
103 * If the current time is below the variant, we don't update the session's expiration time. If it's
104 * greater than the variant, then we update the expiration time in the database. This prevents
105 * writing to the database on every page load for active sessions and only updates the expiration
106 * time if we're nearing when the session actually expires.
107 *
108 * By default, the expiration time is set to 30 minutes.
109 * By default, the expiration variant is set to 24 minutes.
110 *
111 * As a result, the session expiration time - at a maximum - will only be written to the database once
112 * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by
113 * the browser, and the old session will be queued for deletion by the garbage collector.
114 *
115 * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
116 * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
117 */
118 protected function set_expiration() {
119 $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 );
120 $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
121 }
122
123 /**
124 * Set the session cookie
125 */
126 protected function set_cookie() {
127 @setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN );
128 }
129
130 /**
131 * Generate a cryptographically strong unique ID for the session token.
132 *
133 * @return string
134 */
135 protected function generate_id() {
136 require_once( ABSPATH . 'wp-includes/class-phpass.php');
137 $hasher = new PasswordHash( 8, false );
138
139 return md5( $hasher->get_random_bytes( 32 ) );
140 }
141
142 /**
143 * Read data from a transient for the current session.
144 *
145 * Automatically resets the expiration time for the session transient to some time in the future.
146 *
147 * @return array
148 */
149 protected function read_data() {
150 $this->container = get_option( "_wp_session_{$this->session_id}", array() );
151
152 return $this->container;
153 }
154
155 /**
156 * Write the data from the current session to the data storage system.
157 */
158 public function write_data() {
159 $option_key = "_wp_session_{$this->session_id}";
160
161 // Only write the collection to the DB if it's changed.
162 if ( $this->dirty ) {
163 if ( false === get_option( $option_key ) ) {
164 add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
165 add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
166 } else {
167 delete_option( "_wp_session_{$this->session_id}" );
168 add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
169 }
170 }
171 }
172
173 /**
174 * Output the current container contents as a JSON-encoded string.
175 *
176 * @return string
177 */
178 public function json_out() {
179 return json_encode( $this->container );
180 }
181
182 /**
183 * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
184 *
185 * @param string $data
186 *
187 * @return bool
188 */
189 public function json_in( $data ) {
190 $array = json_decode( $data );
191
192 if ( is_array( $array ) ) {
193 $this->container = $array;
194 return true;
195 }
196
197 return false;
198 }
199
200 /**
201 * Regenerate the current session's ID.
202 *
203 * @param bool $delete_old Flag whether or not to delete the old session data from the server.
204 */
205 public function regenerate_id( $delete_old = false ) {
206 if ( $delete_old ) {
207 delete_option( "_wp_session_{$this->session_id}" );
208 }
209
210 $this->session_id = $this->generate_id();
211
212 $this->set_cookie();
213 }
214
215 /**
216 * Check if a session has been initialized.
217 *
218 * @return bool
219 */
220 public function session_started() {
221 return !!self::$instance;
222 }
223
224 /**
225 * Return the read-only cache expiration value.
226 *
227 * @return int
228 */
229 public function cache_expiration() {
230 return $this->expires;
231 }
232
233 /**
234 * Flushes all session variables.
235 */
236 public function reset() {
237 $this->container = array();
238 }
239
240 /*****************************************************************/
241 /* Iterator Implementation */
242 /*****************************************************************/
243
244 /**
245 * Current position of the array.
246 *
247 * @link http://php.net/manual/en/iterator.current.php
248 *
249 * @return mixed
250 */
251 public function current() {
252 return current( $this->container );
253 }
254
255 /**
256 * Key of the current element.
257 *
258 * @link http://php.net/manual/en/iterator.key.php
259 *
260 * @return mixed
261 */
262 public function key() {
263 return key( $this->container );
264 }
265
266 /**
267 * Move the internal point of the container array to the next item
268 *
269 * @link http://php.net/manual/en/iterator.next.php
270 *
271 * @return void
272 */
273 public function next() {
274 next( $this->container );
275 }
276
277 /**
278 * Rewind the internal point of the container array.
279 *
280 * @link http://php.net/manual/en/iterator.rewind.php
281 *
282 * @return void
283 */
284 public function rewind() {
285 reset( $this->container );
286 }
287
288 /**
289 * Is the current key valid?
290 *
291 * @link http://php.net/manual/en/iterator.rewind.php
292 *
293 * @return bool
294 */
295 public function valid() {
296 return $this->offsetExists( $this->key() );
297 }
298
299 /*****************************************************************/
300 /* Countable Implementation */
301 /*****************************************************************/
302
303 /**
304 * Get the count of elements in the container array.
305 *
306 * @link http://php.net/manual/en/countable.count.php
307 *
308 * @return int
309 */
310 public function count() {
311 return count( $this->container );
312 }
313 }
314