PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / class-lp-session-handler.php

class-lp-session-handler.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7, at inc/class-lp-session-handler.php

480 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Session_Handler
5 */
6 class LP_Session_Handler implements ArrayAccess {
7
8 /**
9 * @var int $_customer_id
10 */
11 protected $_customer_id;
12
13 /**
14 * @var array $_data
15 */
16 protected $_data = array();
17
18 /**
19 * @var bool $_changed
20 */
21 protected $_changed = false;
22
23 /**
24 * @var string cookie name
25 */
26 private $_cookie;
27
28 /**
29 * @var string session expiration timestamp
30 */
31 private $_session_expiration;
32
33 /**
34 * $var bool Bool based on whether a cookie exists
35 */
36 private $_has_cookie = false;
37
38 /**
39 * @since 3.2.2
40 *
41 * @var bool
42 */
43 private $_has_browser_cookie = true;
44
45 /**
46 * @var string Custom session table name
47 */
48 private $_table;
49
50 /**
51 * @var null
52 */
53 private static $_instance = null;
54
55 /**
56 * __get function.
57 *
58 * @param mixed $key
59 *
60 * @return mixed
61 */
62 public function __get( $key ) {
63 return $this->get( $key );
64 }
65
66 /**
67 * __set function.
68 *
69 * @param mixed $key
70 * @param mixed $value
71 */
72 public function __set( $key, $value ) {
73 // if ( $key === 'order_awaiting_payment' ) {
74
75 // }
76 $this->set( $key, $value );
77 }
78
79 /**
80 * __isset function.
81 *
82 * @param mixed $key
83 *
84 * @return bool
85 */
86 public function __isset( $key ) {
87 return isset( $this->_data[ sanitize_key( $key ) ] );
88 }
89
90 /**
91 * __unset function.
92 *
93 * @param mixed $key
94 */
95 public function __unset( $key ) {
96 if ( isset( $this->_data[ $key ] ) ) {
97 unset( $this->_data[ $key ] );
98 $this->_changed = true;
99 }
100 }
101
102 protected $schedule_id = 'learn-press/clear-expired-session';
103
104 /**
105 * LP_Session_Handler constructor.
106 *
107 * @version 3.2.2
108 */
109 public function __construct() {
110 $this->init();
111 $this->init_hooks();
112 }
113
114 protected function init_hooks() {
115 add_action( 'learn_press_set_cart_cookies', array( $this, 'set_customer_session_cookie' ), 10 );
116 add_action( 'learn_press_cleanup_sessions', array( $this, 'cleanup_sessions' ), 10 );
117 add_action( 'shutdown', array( $this, 'save_data' ), 20 );
118 add_action( 'wp_logout', array( $this, 'destroy_session' ) );
119 //add_action( 'wp', array( $this, 'schedule_event' ) );
120 //add_action( $this->schedule_id, array( $this, 'cleanup_sessions' ), 10 );
121 }
122
123 protected function init() {
124 global $wpdb;
125 $this->_cookie = '_learn_press_session_' . COOKIEHASH;
126 $this->_table = $wpdb->prefix . 'learnpress_sessions';
127
128 // Check cookie ...
129 if ( ! isset( $_COOKIE ) || sizeof( $_COOKIE ) == 0 ) {
130 $this->_has_browser_cookie = false;
131 }
132
133 // ...and user-agent to ensure user a viewing in a web browser
134 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( $_SERVER['HTTP_USER_AGENT'], 'Mozilla' ) === false ) {
135 $this->_has_browser_cookie = false;
136 }
137
138 $cookie = $this->get_session_cookie();
139 if ( $cookie ) {
140 $this->_customer_id = $cookie[0];
141 $this->_session_expiration = $cookie[1];
142 $this->_has_cookie = true;
143 if ( time() > $this->_session_expiration - HOUR_IN_SECONDS ) {
144 $this->set_session_expiration();
145 $this->update_session_timestamp( $this->_customer_id, $this->_session_expiration );
146 }
147 } else {
148 $this->set_session_expiration();
149 $this->_customer_id = $this->generate_customer_id();
150
151 }
152 $this->_data = $this->get_session_data();
153 }
154
155 /*public function schedule_event() {
156 if ( ! wp_next_scheduled( $this->schedule_id ) ) {
157 wp_schedule_event( time(), 'hourly', $this->schedule_id );
158 }
159 }*/
160
161 public function set_customer_session_cookie( $set ) {
162 if ( $set ) {
163 // Set/renew our cookie
164 $to_hash = $this->_customer_id . '|' . $this->_session_expiration;
165 $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
166 $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $cookie_hash;
167 $this->_has_cookie = true;
168
169 // Set the cookie
170 if ( ! isset( $_COOKIE[ $this->_cookie ] ) || $_COOKIE[ $this->_cookie ] !== $cookie_value ) {
171 learn_press_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'learn_press_session_use_secure_cookie', false ), true );
172 }
173 }
174 }
175
176 public function has_cookie() {
177 return $this->_has_cookie && $this->_has_browser_cookie;
178 }
179
180 public function has_session() {
181 return isset( $_COOKIE[ $this->_cookie ] ) || $this->_has_cookie || is_user_logged_in();
182 }
183
184 public function set_session_expiration() {
185 $this->_session_expiration = time() + intval( apply_filters( 'learn_press_session_expiration', 60 * 60 * 48 ) );
186 }
187
188 public function generate_customer_id() {
189 if ( is_user_logged_in() ) {
190 return get_current_user_id();
191 } else {
192 require_once ABSPATH . 'wp-includes/class-phpass.php';
193 $hasher = new PasswordHash( 12, false );
194
195 return md5( $hasher->get_random_bytes( 32 ) );
196 }
197 }
198
199 public function get_session_cookie() {
200
201 if ( empty( $_COOKIE[ $this->_cookie ] ) || ! is_string( $_COOKIE[ $this->_cookie ] ) ) {
202 return false;
203 }
204
205 list( $customer_id, $session_expiration, $cookie_hash ) = explode( '||', $_COOKIE[ $this->_cookie ] );
206
207 $to_hash = $customer_id . '|' . $session_expiration;
208 $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
209
210 // LP_Debug::instance()->add( array(
211 // $this->_customer_id,
212 // $_COOKIE,
213 // $_REQUEST,
214 // $_POST,
215 // $_GET,
216 // $_SERVER
217 // ), 'sessions-cookie' );
218
219 if ( empty( $cookie_hash ) || ! hash_equals( $hash, $cookie_hash ) ) {
220 return false;
221 }
222
223 return array( $customer_id, $session_expiration, $cookie_hash );
224 }
225
226 public function get_session_data() {
227 return $this->has_session() ? (array) $this->get_session( $this->_customer_id, array() ) : array();
228 }
229
230 public function get_cache_prefix( $group = LP_SESSION_CACHE_GROUP ) {
231 $prefix = LP_Object_Cache::get( 'learn_press_' . $group . '_cache_prefix', $group );
232
233 if ( false === $prefix ) {
234 $prefix = 1;
235 LP_Object_Cache::set( 'learn_press_' . $group . '_cache_prefix', $prefix, $group );
236 }
237
238 return 'learn_press_cache_' . $prefix . '_';
239 }
240
241 /**
242 * Increment group cache prefix (invalidates cache).
243 *
244 * @param string $group
245 */
246 public function incr_cache_prefix( $group ) {
247 wp_cache_incr( 'learn_press_' . $group . '_cache_prefix', 1, $group );
248 }
249
250
251 public function save_data() {
252 // var_dump($this->_changed , $this->has_session() , $this->has_cookie() );
253 if ( $this->_changed && $this->has_session() && $this->has_cookie() ) {
254 global $wpdb;
255 $wpdb->replace(
256 $this->_table,
257 array(
258 'session_key' => $this->_customer_id,
259 'session_value' => maybe_serialize( $this->_data ),
260 'session_expiry' => $this->_session_expiration,
261 ),
262 array(
263 '%s',
264 '%s',
265 '%d',
266 )
267 );
268 // LP_Debug::instance()->add( array(
269 // $this->_customer_id,
270 // $_COOKIE,
271 // $_REQUEST,
272 // $_POST,
273 // $_GET,
274 // $_SERVER
275 // ), __FUNCTION__ );
276
277 // Set cache
278 LP_Object_Cache::set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
279
280 // Mark session clean after saving
281 $this->_changed = false;
282 }
283 }
284
285 public function destroy_session() {
286 $id = $this->get( 'temp_user' );
287 if ( $id ) {
288 delete_user_meta( $id, '_lp_expiration' );
289 }
290
291 // Clear cookie
292 learn_press_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, apply_filters( 'learn_press_session_secure_cookie', false ) );
293
294 $this->delete_session( $this->_customer_id );
295
296 // Clear cart
297 $this->set( 'cart', '' );
298 $this->set( 'temp_user', '' );
299
300 // Clear data
301 $this->_data = array();
302 $this->_changed = false;
303 $this->_customer_id = $this->generate_customer_id();
304
305 $logout_redirect_page_id = LP_Settings::get_option( 'logout_redirect_page_id', false );
306 if ( $logout_redirect_page_id ) {
307
308 wp_safe_redirect( get_the_permalink( $logout_redirect_page_id ) );
309 die;
310 }
311 }
312
313 public function cleanup_sessions() {
314 global $wpdb;
315
316 if ( ! defined( 'WP_SETUP_CONFIG' ) && ! defined( 'WP_INSTALLING' ) ) {
317
318 // Delete expired sessions
319 $wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) ); // phpcs:ignore
320
321 // Invalidate cache
322 $this->incr_cache_prefix( LP_SESSION_CACHE_GROUP );
323 }
324 }
325
326 public function get_session( $customer_id, $default = false ) {
327 global $wpdb;
328
329 if ( defined( 'WP_SETUP_CONFIG' ) ) {
330 return false;
331 }
332
333 // Try get it from the cache, it will return false if not present or if object cache not in use
334 $value = LP_Object_Cache::get( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
335 // echo "KEY:" . $this->get_cache_prefix() . $customer_id . "]";
336
337 if ( false === $value && $wpdb->get_var( "SHOW TABLES LIKE '$this->_table'" ) == $this->_table ) {
338 $q = $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id ); // phpcs:ignore
339 $value = $wpdb->get_var( $q );
340
341 if ( is_null( $value ) ) {
342 $value = $default;
343 }
344
345 wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
346 }
347
348 return LP_Helper::maybe_unserialize( $value );
349 }
350
351 public function delete_session( $customer_id ) {
352 global $wpdb;
353
354 wp_cache_delete( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
355
356 $wpdb->delete(
357 $this->_table,
358 array(
359 'session_key' => $customer_id,
360 )
361 );
362 }
363
364 public function update_session_timestamp( $customer_id, $timestamp ) {
365 global $wpdb;
366 $wpdb->update(
367 $this->_table,
368 array(
369 'session_expiry' => $timestamp,
370 ),
371 array(
372 'session_key' => $customer_id,
373 ),
374 array(
375 '%d',
376 )
377 );
378 // LP_Debug::instance()->add( $customer_id, __FUNCTION__ );
379 }
380
381 /**
382 * Remove a value from session by key.
383 *
384 * @param string $key
385 * @param bool $force_change
386 */
387 public function remove( $key, $force_change = false ) {
388 if ( ! array_key_exists( $key, $this->_data ) ) {
389 return;
390 }
391 unset( $this->_data[ $key ] );
392 $this->_changed = true;
393 if ( $force_change ) {
394 $this->save_data();
395 }
396 }
397
398 /**
399 * Get session value.
400 *
401 * @param string $key
402 * @param mixed $default
403 *
404 * @return mixed|null
405 */
406 public function get( $key, $default = null ) {
407 $key = sanitize_key( $key );
408
409 return isset( $this->_data[ $key ] ) ? LP_Helper::maybe_unserialize( $this->_data[ $key ] ) : $default;
410 }
411
412 /**
413 * Set session value.
414 *
415 * @param string $key
416 * @param mixed $value
417 * @param bool $force_change
418 */
419 public function set( $key, $value, $force_change = false ) {
420 if ( $value !== $this->get( $key ) ) {
421 $this->_data[ sanitize_key( $key ) ] = maybe_serialize( $value );
422 $this->_changed = true;
423
424 if ( $force_change ) {
425 $this->save_data();
426 }
427 }
428 }
429
430 public function get_customer_id() {
431 return $this->_customer_id;
432 }
433
434 public function get_session_expiration() {
435 return $this->_session_expiration;
436 }
437
438 public static function instance() {
439 if ( ! self::$_instance ) {
440 self::$_instance = new self();
441 }
442
443 return self::$_instance;
444 }
445
446 public function offsetExists( $offset ) {
447 return array_key_exists( $offset, $this->_data );
448 }
449
450 public function offsetGet( $offset ) {
451 return $this->get( $offset );
452 }
453
454 public function offsetUnset( $offset ) {
455 $this->remove( $offset );
456 }
457
458 public function offsetSet( $offset, $value ) {
459 $this->set( $offset, $value );
460 }
461 }
462
463 /**
464 * @param $key
465 * @param null $default
466 *
467 * @return array|string
468 */
469 function learn_press_session_get( $key, $default = null ) {
470 return LP_Session_Handler::instance()->get( $key, $default );
471 }
472
473 /**
474 * @param $key
475 * @param $value
476 */
477 function learn_press_session_set( $key, $value ) {
478 LP_Session_Handler::instance()->set( $key, $value );
479 }
480