Merged in feature/from-pantheon (pull request #16)
code from pantheon * code from pantheon
This commit is contained in:
138
wp/wp-content/plugins/wp-native-php-sessions/inc/class-admin.php
Normal file
138
wp/wp-content/plugins/wp-native-php-sessions/inc/class-admin.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* Controller for backend functionality.
|
||||
*
|
||||
* @package WPNPS
|
||||
*/
|
||||
|
||||
namespace Pantheon_Sessions;
|
||||
|
||||
/**
|
||||
* Controller for backend functionality.
|
||||
*/
|
||||
class Admin {
|
||||
|
||||
/**
|
||||
* Copy of the singleton instance.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Name of capability required to perform actions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $capability = 'manage_options';
|
||||
|
||||
/**
|
||||
* Gets a copy of the singleton instance.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! isset( self::$instance ) ) {
|
||||
self::$instance = new Admin();
|
||||
self::$instance->setup_actions();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load admin actions
|
||||
*/
|
||||
private function setup_actions() {
|
||||
|
||||
add_action( 'admin_menu', [ $this, 'action_admin_menu' ] );
|
||||
add_action( 'wp_ajax_pantheon_clear_session', [ $this, 'handle_clear_session' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the admin menu
|
||||
*/
|
||||
public function action_admin_menu() {
|
||||
|
||||
add_management_page( __( 'Pantheon Sessions', 'wp-native-php-sessions' ), __( 'Sessions', 'wp-native-php-sessions' ), self::$capability, 'pantheon-sessions', [ $this, 'handle_page' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the admin page
|
||||
*/
|
||||
public function handle_page() {
|
||||
global $wpdb;
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
require_once __DIR__ . '/class-list-table.php';
|
||||
|
||||
echo '<div class="wrap">';
|
||||
|
||||
echo '<div>';
|
||||
$query_args = [
|
||||
'action' => 'pantheon_clear_session',
|
||||
'nonce' => wp_create_nonce( 'pantheon_clear_session' ),
|
||||
'session' => 'all',
|
||||
];
|
||||
if ( $wpdb->get_var( "SELECT COUNT(session_id) FROM $wpdb->pantheon_sessions" ) ) {
|
||||
echo '<a class="button pantheon-clear-all-sessions" style="float:right; margin-top: 9px;" href="' . esc_url( add_query_arg( $query_args, admin_url( 'admin-ajax.php' ) ) ) . '">' . esc_html__( 'Clear All', 'wp-native-php-sessions' ) . '</a>';
|
||||
}
|
||||
echo '<h2>' . esc_html__( 'Pantheon Sessions', 'wp-native-php-sessions' ) . '</h2>';
|
||||
if ( isset( $_GET['message'] ) && in_array( $_GET['message'], [ 'delete-all-session', 'delete-session' ], true ) ) {
|
||||
if ( 'delete-all-session' === $_GET['message'] ) {
|
||||
$message = __( 'Cleared all sessions.', 'wp-native-php-sessions' );
|
||||
} elseif ( 'delete-session' === $_GET['message'] ) {
|
||||
$message = __( 'Session cleared.', 'wp-native-php-sessions' );
|
||||
}
|
||||
echo '<div id="message" class="updated"><p>' . esc_html( $message ) . '</p></div>';
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
$wp_list_table = new List_Table();
|
||||
$wp_list_table->prepare_items();
|
||||
$wp_list_table->display();
|
||||
|
||||
echo '</div>';
|
||||
|
||||
add_action( 'admin_footer', [ $this, 'action_admin_footer' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to clear all sessions
|
||||
*/
|
||||
public function handle_clear_session() {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! current_user_can( self::$capability ) || ! wp_verify_nonce( $_GET['nonce'], 'pantheon_clear_session' ) ) {
|
||||
wp_die( esc_html__( "You don't have permission to do this.", 'wp-native-php-sessions' ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['session'] ) && 'all' === $_GET['session'] ) {
|
||||
$wpdb->query( "DELETE FROM $wpdb->pantheon_sessions" );
|
||||
$message = 'delete-all-session';
|
||||
} else {
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->pantheon_sessions WHERE session_id=%s", sanitize_text_field( $_GET['session'] ) ) );
|
||||
$message = 'delete-session';
|
||||
}
|
||||
wp_safe_redirect( add_query_arg( 'message', $message, wp_get_referer() ) );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stuff that needs to go in the footer
|
||||
*/
|
||||
public function action_admin_footer() {
|
||||
?>
|
||||
<script>
|
||||
(function($){
|
||||
$(document).ready(function(){
|
||||
$('.pantheon-clear-all-sessions').on('click', function( e ){
|
||||
if ( ! confirm( '<?php esc_html_e( 'Are you sure you want to clear all active sessions?', 'wp-native-php-sessions' ); ?>') ) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
}(jQuery))
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* CLI interface to interact with Pantheon sessions.
|
||||
*
|
||||
* @package WPNPS
|
||||
*/
|
||||
|
||||
namespace Pantheon_Sessions;
|
||||
|
||||
use WP_CLI;
|
||||
|
||||
/**
|
||||
* Interact with Pantheon Sessions
|
||||
*/
|
||||
class CLI_Command extends \WP_CLI_Command {
|
||||
|
||||
/**
|
||||
* List all registered sessions.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, csv, json, count, ids. Default: table
|
||||
*
|
||||
* @subcommand list
|
||||
*/
|
||||
public function list_( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! PANTHEON_SESSIONS_ENABLED ) {
|
||||
WP_CLI::error( 'Pantheon Sessions is currently disabled.' );
|
||||
}
|
||||
|
||||
$defaults = [
|
||||
'format' => 'table',
|
||||
'fields' => 'session_id,user_id,datetime,ip_address,data',
|
||||
];
|
||||
$assoc_args = array_merge( $defaults, $assoc_args );
|
||||
|
||||
$sessions = [];
|
||||
foreach ( new \WP_CLI\Iterators\Query( "SELECT * FROM {$wpdb->pantheon_sessions} ORDER BY datetime DESC" ) as $row ) {
|
||||
$sessions[] = $row;
|
||||
}
|
||||
|
||||
\WP_CLI\Utils\Format_Items( $assoc_args['format'], $sessions, $assoc_args['fields'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more sessions.
|
||||
*
|
||||
* [<session-id>...]
|
||||
* : One or more session IDs
|
||||
*
|
||||
* [--all]
|
||||
* : Delete all sessions.
|
||||
*
|
||||
* @subcommand delete
|
||||
*/
|
||||
public function delete( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! PANTHEON_SESSIONS_ENABLED ) {
|
||||
WP_CLI::error( 'Pantheon Sessions is currently disabled.' );
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['all'] ) ) {
|
||||
$args = $wpdb->get_col( "SELECT session_id FROM {$wpdb->pantheon_sessions}" );
|
||||
if ( empty( $args ) ) {
|
||||
WP_CLI::warning( 'No sessions to delete.' );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $args as $session_id ) {
|
||||
$session = \Pantheon_Sessions\Session::get_by_sid( $session_id );
|
||||
if ( $session ) {
|
||||
$session->destroy();
|
||||
WP_CLI::log( sprintf( 'Session destroyed: %s', $session_id ) );
|
||||
} else {
|
||||
WP_CLI::warning( sprintf( "Session doesn't exist: %s", $session_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id as primary key in the Native PHP Sessions plugin table.
|
||||
*
|
||||
* @subcommand add-index
|
||||
*/
|
||||
public function add_index( $args, $assoc_args ) {
|
||||
$pantheon_session = new \Pantheon_Sessions();
|
||||
$resume_point = isset( $assoc_args['start_point'] ) ? $assoc_args['start_point'] : 0;
|
||||
$pantheon_session->add_index( $resume_point );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes the creation of a primary key by deleting the old data.
|
||||
*
|
||||
* @subcommand primary-key-finalize
|
||||
*/
|
||||
public function primary_key_finalize( $args, $assoc_args ) {
|
||||
$pantheon_session = new \Pantheon_Sessions();
|
||||
$resume_point = isset( $assoc_args['start_point'] ) ? $assoc_args['start_point'] : 0;
|
||||
$pantheon_session->primary_key_finalize( $resume_point );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts addition of primary key.
|
||||
*
|
||||
* @subcommand primary-key-revert
|
||||
*/
|
||||
public function primary_key_revert( $args, $assoc_args ) {
|
||||
$pantheon_session = new \Pantheon_Sessions();
|
||||
$resume_point = isset( $assoc_args['start_point'] ) ? $assoc_args['start_point'] : 0;
|
||||
$pantheon_session->primary_key_revert( $resume_point );
|
||||
}
|
||||
}
|
||||
|
||||
\WP_CLI::add_command( 'pantheon session', '\Pantheon_Sessions\CLI_Command' );
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* List table for displaying all sessions.
|
||||
*
|
||||
* @package WPNPS
|
||||
*/
|
||||
|
||||
namespace Pantheon_Sessions;
|
||||
|
||||
/**
|
||||
* List table for displaying all sessions.
|
||||
*/
|
||||
class List_Table extends \WP_List_Table {
|
||||
|
||||
/**
|
||||
* Prepare the items for the list table
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $wpdb;
|
||||
|
||||
$columns = $this->get_columns();
|
||||
$hidden = [];
|
||||
$sortable = [];
|
||||
$this->_column_headers = [ $columns, $hidden, $sortable ];
|
||||
|
||||
$per_page = 20;
|
||||
$paged = ( isset( $_GET['paged'] ) ) ? (int) $_GET['paged'] : 1;
|
||||
$offset = $per_page * ( $paged - 1 );
|
||||
|
||||
$this->items = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->pantheon_sessions ORDER BY datetime DESC LIMIT %d,%d", $offset, $per_page ) );
|
||||
$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->pantheon_sessions" );
|
||||
|
||||
$this->set_pagination_args(
|
||||
[
|
||||
'total_items' => $total_items,
|
||||
'per_page' => $per_page,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Message for no items found
|
||||
*/
|
||||
public function no_items() {
|
||||
esc_html_e( 'No sessions found.', 'wp-native-php-sessions' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columns in the list table
|
||||
*/
|
||||
public function get_columns() {
|
||||
return [
|
||||
'session_id' => __( 'Session ID', 'wp-native-php-sessions' ),
|
||||
'user_id' => __( 'User ID', 'wp-native-php-sessions' ),
|
||||
'ip_address' => __( 'IP Address', 'wp-native-php-sessions' ),
|
||||
'datetime' => __( 'Last Active', 'wp-native-php-sessions' ),
|
||||
'data' => __( 'Data', 'wp-native-php-sessions' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a column value
|
||||
*
|
||||
* @param object $item Session to display.
|
||||
* @param string $column_name Name of the column.
|
||||
*/
|
||||
public function column_default( $item, $column_name ) {
|
||||
if ( 'data' === $column_name ) {
|
||||
return '<code>' . esc_html( $item->data ) . '</code>';
|
||||
} elseif ( 'session_id' === $column_name ) {
|
||||
$query_args = [
|
||||
'action' => 'pantheon_clear_session',
|
||||
'nonce' => wp_create_nonce( 'pantheon_clear_session' ),
|
||||
'session' => $item->session_id,
|
||||
];
|
||||
$actions = [
|
||||
'clear' => '<a href="' . esc_url( add_query_arg( $query_args, admin_url( 'admin-ajax.php' ) ) ) . '">' . esc_html__( 'Clear', 'wp-native-php-sessions' ) . '</a>',
|
||||
];
|
||||
return esc_html( $item->session_id ) . $this->row_actions( $actions );
|
||||
} elseif ( 'datetime' === $column_name ) {
|
||||
// translators: Time ago.
|
||||
return esc_html( sprintf( esc_html__( '%s ago', 'wp-native-php-sessions' ), human_time_diff( strtotime( $item->datetime ) ) ) );
|
||||
} else {
|
||||
return esc_html( $item->$column_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Implementation of 'SessionHandlerInterface' that writes to the database.
|
||||
*
|
||||
* @package WPNPS
|
||||
*/
|
||||
|
||||
namespace Pantheon_Sessions;
|
||||
|
||||
use Pantheon_Sessions\Session;
|
||||
|
||||
/**
|
||||
* Implementation of 'SessionHandlerInterface' that writes to the database.
|
||||
*
|
||||
* @package WPNPS
|
||||
*/
|
||||
class Session_Handler implements \SessionHandlerInterface {
|
||||
|
||||
/**
|
||||
* Closes the session.
|
||||
*
|
||||
* @param string $save_path Path to where the session is to be stored.
|
||||
* @param string $session_name Name of the session.
|
||||
* @return boolean
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function open( $save_path, $session_name ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a session to the database.
|
||||
*
|
||||
* @param string $session_id Session id.
|
||||
* @param string $session_data Session data.
|
||||
* @return boolean
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function write( $session_id, $session_data ) {
|
||||
$session = Session::get_by_sid( $session_id );
|
||||
|
||||
if ( ! $session ) {
|
||||
$session = Session::create_for_sid( $session_id );
|
||||
}
|
||||
|
||||
if ( ! $session ) {
|
||||
trigger_error( 'Could not write session to the database. Please check MySQL configuration.', E_USER_WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
$session->set_data( $session_data );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads session data from the database.
|
||||
*
|
||||
* @param string $session_id Session id.
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function read( $session_id ) {
|
||||
// Handle the case of first time visitors and clients that don't store
|
||||
// cookies (eg. web crawlers).
|
||||
$insecure_session_name = substr( session_name(), 1 );
|
||||
if ( empty( $session_id )
|
||||
|| ( ! isset( $_COOKIE[ session_name() ] ) && ! isset( $_COOKIE[ $insecure_session_name ] ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$session = Session::get_by_sid( $session_id );
|
||||
if ( $session ) {
|
||||
return $session->get_data() ?: '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the session.
|
||||
*
|
||||
* @param string $session_id Session id.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function destroy( $session_id ) {
|
||||
$session = Session::get_by_sid( $session_id );
|
||||
if ( ! $session ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session->destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the garbage collection process.
|
||||
*
|
||||
* @param integer $maxlifetime Maximum lifetime in seconds.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function gc( $maxlifetime ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb = Session::restore_wpdb_if_null( $wpdb );
|
||||
|
||||
// Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
|
||||
// value. For example, if you want user sessions to stay in your database
|
||||
// for three weeks before deleting them, you need to set gc_maxlifetime
|
||||
// to '1814400'. At that value, only after a user doesn't log in after
|
||||
// three weeks (1814400 seconds) will his/her session be removed.
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->pantheon_sessions WHERE `datetime` <= %s ", gmdate( 'Y-m-d H:i:s', time() - $maxlifetime ) ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the session.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function close() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
<?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';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user