Current File : /home/escuelai/public_html/wp-content/plugins/learnpress/inc/class-lp-session-handler.php |
<?php
/**
* Class LP_Session_Handler
*
* Only set COOKIE for user guest
*/
class LP_Session_Handler {
/**
* @var string $_customer_id
*/
public $_customer_id = '';
/**
* @var array $_data
*/
protected $_data = array();
/**
* @var bool $_changed
*/
protected $_changed = false;
/**
* @var string cookie name
*/
private $_cookie = 'lp_session_guest';
/**
* @var int session expiration timestamp
*/
private $_session_expiration = 0;
/**
* @var null
*/
private static $_instance = null;
/**
* LP_Session_Handler constructor.
*
* @version 3.2.2
*/
protected function __construct() {
$this->init_hooks();
if ( is_admin() ) {
return;
}
$this->init();
}
protected function init_hooks() {
add_action( 'wp_login', [ $this, 'handle_when_user_login_success' ], 10, 2 );
add_action( 'wp_logout', array( $this, 'destroy_session' ) );
}
/**
* Set COOKIE for only user guest
* Set data: customer_id, session_expiration
*
* @return self
* @since 3.0.0
* @version 4.0.3
* @modify Tungnx
*/
protected function init(): LP_Session_Handler {
$expire_time_for_guest = DAY_IN_SECONDS;
$expire_time_for_user = 6 * DAY_IN_SECONDS;
// Set data for user Guest.
if ( ! is_user_logged_in() ) { // Generate data and set cookie for guest
$this->set_session_expiration( $expire_time_for_guest );
if ( LP_Settings::is_store_ip_customer() ) {
$this->_customer_id = LP_Helper::get_client_ip();
} else { // Store data in COOKIE
$cookie = $this->get_cookie_data();
// If cookie exists, set data from cookie for guest
if ( empty( $cookie ) ) {
// Create new cookie and session for user Guest.
$this->_customer_id = apply_filters( 'lp/cookie/guest-id', 'g-' . uniqid() );
$this->set_customer_session_cookie();
} else {
$this->_customer_id = $cookie;
}
}
} else { // Set data for user logged.
$this->set_session_expiration( $expire_time_for_user );
$this->_customer_id = get_current_user_id();
}
// Get session data from DB.
$this->_data = $this->get_session_data();
return $this;
}
/**
* Handle when user logged in.
*
* @param $user_name
* @param $user
*
* @return void
*/
public function handle_when_user_login_success( $user_name, $user ) {
// Remove COOKIE for user guest.
learn_press_remove_cookie( $this->_cookie );
/**
* Must set wp_set_current_user to get_current_user_id and is_user_logged_in work correctly.
* Because WP note must do that.
* Read more @see wp_signon
* If version WP after run correctly, remove wp_set_current_user.
*/
wp_set_current_user( $user->ID );
$user_id = get_current_user_id();
/**
* Delete session of user guest before.
*/
if ( $user_id ) {
$customer_id = $this->get_customer_id();
$user_before = get_user_by( 'ID', $customer_id );
if ( ! $user_before ) {
$this->delete_session( $customer_id );
}
$this->_customer_id = $user_id;
}
}
/**
* Set cookie for user guest.
*
* @return LP_Session_Handler
*/
public function set_customer_session_cookie(): LP_Session_Handler {
// Set the cookie
if ( ! isset( $_COOKIE[ $this->_cookie ] ) ) {
learn_press_setcookie( $this->_cookie, $this->_customer_id, $this->_session_expiration );
}
return $this;
}
/**
* Set session expiration.
*
* @param int $duration
*
* @return LP_Session_Handler
*/
public function set_session_expiration( int $duration = 0 ): LP_Session_Handler {
$this->_session_expiration = time() + $duration;
return $this;
}
/**
* Get cookie of guest.
*
* @return string
*/
public function get_cookie_data(): string {
if ( empty( $_COOKIE[ $this->_cookie ] ) || ! is_string( $_COOKIE[ $this->_cookie ] ) ) {
return '';
}
return $_COOKIE[ $this->_cookie ];
}
/**
* Get session data
*
* @return array
*/
public function get_session_data(): array {
if ( is_user_logged_in() ) {
$customer_id = get_current_user_id();
} else {
$customer_id = $this->get_customer_id();
}
return (array) $this->get_session_by_customer_id( (string) $customer_id );
}
/**
* Save session data to the database.
*
* @return bool
* @version 4.0.1
* @since 3.0.0
*/
public function save_data(): bool {
$res = false;
try {
$lp_session_db = LP_Sessions_DB::getInstance();
// Check exists on DB.
$filter = new LP_Session_filter();
$filter->collection = $lp_session_db->tb_lp_sessions;
$filter->field_count = 'session_id';
$filter->limit = 1;
$filter->where[] = $lp_session_db->wpdb->prepare( 'AND session_key = %s', $this->_customer_id );
$get = $lp_session_db->execute( $filter );
$data = [
'session_key' => (string) $this->_customer_id,
'session_value' => maybe_serialize( $this->_data ),
'session_expiry' => $this->_session_expiration,
];
if ( ! empty( $get ) ) {
// Update
$lp_session_db->wpdb->update(
$lp_session_db->tb_lp_sessions,
$data,
[ 'session_key' => $this->_customer_id ],
[ '%s', '%s', '%d' ],
[ '%s' ]
);
} else {
// Insert
$lp_session_db->wpdb->insert(
$lp_session_db->tb_lp_sessions,
$data,
[ '%s', '%s', '%d' ]
);
}
// Clear cache.
LP_Session_Cache::instance()->clear( $this->_customer_id );
$res = true;
} catch ( Throwable $e ) {
error_log( $e->getMessage() );
}
return $res;
}
/**
* Destroy session.
*/
public function destroy_session() {
// Clear cookie.
if ( ! empty( $this->_cookie ) ) {
learn_press_remove_cookie( $this->_cookie );
}
// Clear session expire.
$this->cleanup_sessions_expire();
$logout_redirect_page_id = LP_Settings::get_option( 'logout_redirect_page_id' );
if ( $logout_redirect_page_id ) {
wp_safe_redirect( get_the_permalink( $logout_redirect_page_id ) );
die;
}
}
/**
* Clear session expired.
*
* @return bool
*/
public function cleanup_sessions_expire(): bool {
$res = true;
$lp_session_db = LP_Sessions_DB::getInstance();
try {
// Get session expired.
$filter_get = new LP_Session_Filter();
$filter_get->where[] = $lp_session_db->wpdb->prepare( 'AND session_expiry < %d', time() );
$sessions = $lp_session_db->get_sessions( $filter_get );
// Clear cache.
foreach ( $sessions as $session ) {
LP_Session_Cache::instance()->clear( $session->session_key );
}
// Delete session expired.
$filter = new LP_Session_Filter();
$filter->collection = $lp_session_db->tb_lp_sessions;
$filter->where[] = $lp_session_db->wpdb->prepare( 'AND session_expiry < %d', time() );
$lp_session_db->delete_execute( $filter );
} catch ( Throwable $e ) {
$res = false;
error_log( $e->getMessage() );
}
return $res;
}
/**
* Get session on DB.
*
* @param string $customer_id
*
* @return false|mixed|string
* @Todo - Tungnx should handle data when save type json instead serialize.
*/
public function get_session_by_customer_id( string $customer_id = '' ) {
$lp_session_db = LP_Sessions_DB::getInstance();
$session = [];
try {
// Get cache.
$session_cache = LP_Session_Cache::instance();
$key_cache = $customer_id;
$session = $session_cache->get_cache( $key_cache );
if ( $session !== false ) {
return $session;
}
$filter = new LP_Session_Filter();
$filter->session_key = $customer_id;
$filter->only_fields = [ 'session_key', 'session_value' ];
$filter->field_count = 'session_key';
$filter->run_query_count = false;
$filter->limit = 1;
$res = $lp_session_db->get_sessions( $filter );
if ( ! empty( $res ) ) {
$session = $res[0]->session_value;
}
$session = LP_Helper::maybe_unserialize( $session );
// Set cache.
$session_cache->set_cache( $key_cache, $session );
} catch ( Throwable $e ) {
error_log( $e->getMessage() );
}
return $session;
}
/**
* Delete session by customer_id on DB.
*
* @param string $customer_id
*
* @return bool
*/
public function delete_session( string $customer_id ): bool {
global $wpdb;
$rs = true;
try {
$wpdb->delete(
LP_Sessions_DB::getInstance()->tb_lp_sessions,
[ 'session_key' => $customer_id ],
[ '%s' ]
);
// Clear cache.
LP_Session_Cache::instance()->clear( $customer_id );
} catch ( Throwable $e ) {
$rs = false;
error_log( $e->getMessage() );
}
return $rs;
}
/**
* Get session value.
*
* @param string $key
* @param mixed $default
*
* @return mixed|null
*/
public function get( string $key, $default = null ) {
return isset( $this->_data[ $key ] ) ? LP_Helper::maybe_unserialize( $this->_data[ $key ] ) : $default;
}
/**
* Set session value.
*
* @param string $key
* @param mixed $value
* @param bool $force_change
*/
public function set( string $key, $value, bool $force_change = false ) {
$this->_data[ sanitize_key( $key ) ] = maybe_serialize( $value );
if ( $force_change ) {
$this->save_data();
}
}
/**
* Remove a value from session by key.
*
* @param string $key
* @param bool $force_change
*/
public function remove( string $key, bool $force_change = false ) {
if ( ! array_key_exists( $key, $this->_data ) ) {
return;
}
unset( $this->_data[ $key ] );
if ( $force_change ) {
$this->save_data();
}
}
/**
* Get customer id.
*/
public function get_customer_id(): string {
return (string) $this->_customer_id;
}
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
}
/**
* @param $key
* @param null $default
*
* @return array|string
*/
function learn_press_session_get( $key, $default = null ) {
return LP_Session_Handler::instance()->get( $key, $default );
}
/**
* @param $key
* @param $value
*/
function learn_press_session_set( $key, $value ) {
LP_Session_Handler::instance()->set( $key, $value );
}