Files
medicalalert-web-reloaded/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session.php
2024-02-16 16:58:08 +00:00

323 lines
6.3 KiB
PHP

<?php
/**
* Individual session object.
*
* @package WPNPS
*/
namespace Pantheon_Sessions;
/**
* Individual session object.
*/
class Session {
/**
* Any sessions stored statically.
*
* @var array
*/
private static $sessions = [];
/**
* Any secure sessions stored statically.
*
* @var array
*/
private static $secure_sessions = [];
/**
* Session id.
*
* @var string
*/
private $sid;
/**
* Session data.
*
* @var array
*/
private $data;
/**
* Session user id.
*
* @var integer
*/
private $user_id;
/**
* Get a session based on its ID.
*
* @param string $sid Session id.
* @return Session|false
*/
public static function get_by_sid( $sid ) {
global $wpdb;
if ( ! $sid ) {
return false;
}
$wpdb = self::restore_wpdb_if_null( $wpdb );
$column_name = self::get_session_id_column();
$table_name = $wpdb->pantheon_sessions;
// phpcs:ignore
$session_row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE {$column_name}=%s", $sid ) );
if ( ! $session_row ) {
return false;
}
return new Session( $session_row->$column_name, $session_row->data, $session_row->user_id );
}
/**
* Create a database entry for this session
*
* @param string $sid Session id.
* @return Session
*/
public static function create_for_sid( $sid ) {
global $wpdb;
$wpdb = self::restore_wpdb_if_null( $wpdb );
$insert_data = [
'session_id' => $sid,
'user_id' => (int) get_current_user_id(),
];
if ( function_exists( 'is_ssl' ) && is_ssl() ) {
$insert_data['secure_session_id'] = $sid;
}
$wpdb->insert( $wpdb->pantheon_sessions, $insert_data );
return self::get_by_sid( $sid );
}
/**
* Instantiates a session object.
*
* @param string $sid Session id.
* @param mixed $data Any session data.
* @param integer $user_id User id for the session.
*/
private function __construct( $sid, $data, $user_id ) {
$this->sid = $sid;
$this->data = $data;
$this->user_id = $user_id;
}
/**
* Get this session's ID
*
* @return string
*/
public function get_id() {
return $this->sid;
}
/**
* Get this session's data
*
* @return mixed
*/
public function get_data() {
return maybe_unserialize( $this->data );
}
/**
* Get this session's user id.
*
* @return integer
*/
public function get_user_id() {
return (int) $this->user_id;
}
/**
* Set the user id for this session.
*
* @param integer $user_id User id.
*/
public function set_user_id( $user_id ) {
global $wpdb;
$wpdb = self::restore_wpdb_if_null( $wpdb );
$this->user_id = (int) $user_id;
$wpdb->update(
$wpdb->pantheon_sessions,
[
'user_id' => $this->user_id,
],
[ self::get_session_id_column() => $this->get_id() ]
);
}
/**
* Set the session's data
*
* @param mixed $data Session data.
*/
public function set_data( $data ) {
global $wpdb;
if ( $data === $this->get_data() ) {
return;
}
if ( ! isset( $_SERVER['REMOTE_ADDR'] ) ) {
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
}
$wpdb = self::restore_wpdb_if_null( $wpdb );
$wpdb->update(
$wpdb->pantheon_sessions,
[
'user_id' => (int) get_current_user_id(),
'datetime' => gmdate( 'Y-m-d H:i:s' ),
'ip_address' => self::get_client_ip_server(),
'data' => maybe_serialize( $data ),
],
[ self::get_session_id_column() => $this->get_id() ]
);
$this->data = maybe_serialize( $data );
}
/**
* Get the clients ip address
*
* @return string
*/
public static function get_client_ip_server() {
// Set default.
$ip_address = apply_filters( 'pantheon_sessions_client_ip_default', '127.0.0.1' );
$ip_source = null;
$keys = [
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
];
$ip_filter_flags = apply_filters( 'pantheon_sessions_client_ip_filter_flags', FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE );
foreach ( $keys as $key ) {
if ( array_key_exists( $key, $_SERVER )
&& $_SERVER[ $key ]
) {
$_ip_address = $_SERVER[ $key ];
if ( false !== strpos( $_ip_address, ',' ) ) {
$_ip_address = trim( strstr( $_ip_address, ',', true ) );
}
if ( false === filter_var( $_ip_address, FILTER_VALIDATE_IP, $ip_filter_flags ) ) {
continue;
}
$ip_address = $_ip_address;
$ip_source = $key;
break;
}
}
return apply_filters(
'pantheon_sessions_client_ip',
preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip_address ),
$ip_source
);
}
/**
* Destroy this session
*/
public function destroy() {
global $wpdb;
$wpdb = self::restore_wpdb_if_null( $wpdb );
$wpdb->delete( $wpdb->pantheon_sessions, [ self::get_session_id_column() => $this->get_id() ] );
// Reset $_SESSION to prevent a new session from being started.
$_SESSION = [];
$this->delete_cookies();
}
/**
* Restores $wpdb database connection if missing.
*
* @param mixed $wpdb Existing global.
* @return object
*/
public static function restore_wpdb_if_null( $wpdb ) {
if ( $wpdb instanceof \wpdb ) {
return $wpdb;
}
$dbuser = defined( 'DB_USER' ) ? DB_USER : '';
$dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : '';
$dbname = defined( 'DB_NAME' ) ? DB_NAME : '';
$dbhost = defined( 'DB_HOST' ) ? DB_HOST : '';
return new \wpdb( $dbuser, $dbpassword, $dbname, $dbhost );
}
/**
* Delete session cookies
*/
private function delete_cookies() {
// Cookies don't exist on CLI.
if ( self::is_cli() ) {
return;
}
$session_name = session_name();
$cookies = [
$session_name,
substr( $session_name, 1 ),
'S' . $session_name,
];
foreach ( $cookies as $cookie_name ) {
if ( ! isset( $_COOKIE[ $cookie_name ] ) ) {
continue;
}
$params = session_get_cookie_params();
setcookie( $cookie_name, '', $_SERVER['REQUEST_TIME'] - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly'] );
unset( $_COOKIE[ $cookie_name ] );
}
}
/**
* Is this request via CLI?
*
* @return bool
*/
private static function is_cli() {
return 'cli' === PHP_SAPI;
}
/**
* Get the session ID column name
*
* @return string
*/
private static function get_session_id_column() {
if ( is_ssl() ) {
return 'secure_session_id';
} else {
return 'session_id';
}
}
}