| 1 | <?php
|
|---|
| 2 |
|
|---|
| 3 | add_action( 'plugins_loaded', function() {
|
|---|
| 4 | global $wpdb;
|
|---|
| 5 | $wpdb->sessions = $wpdb->base_prefix . 'sessions';
|
|---|
| 6 | /*
|
|---|
| 7 | CREATE TABLE `wp_sessions` (
|
|---|
| 8 | `verifier` char(64) NOT NULL,
|
|---|
| 9 | `user_id` bigint(20) NOT NULL,
|
|---|
| 10 | `ua` varchar(400) NOT NULL,
|
|---|
| 11 | `ip` varchar(45) NOT NULL,
|
|---|
| 12 | `expiration` int(10) NOT NULL,
|
|---|
| 13 | `start` int(10) NOT NULL,
|
|---|
| 14 | PRIMARY KEY (`verifier`),
|
|---|
| 15 | KEY `user_id` (`user_id`)
|
|---|
| 16 | )
|
|---|
| 17 | */
|
|---|
| 18 |
|
|---|
| 19 | add_filter( 'attach_session_information', function( $info ) {
|
|---|
| 20 | $info['ip'] = $_SERVER['REMOTE_ADDR'];
|
|---|
| 21 | $info['ua'] = $_SERVER['HTTP_USER_AGENT'];
|
|---|
| 22 | $info['start'] = time();
|
|---|
| 23 | return $info;
|
|---|
| 24 | });
|
|---|
| 25 |
|
|---|
| 26 | add_filter( 'session_token_manager', function() {
|
|---|
| 27 | return 'Global_Table_Session_Tokens';
|
|---|
| 28 | });
|
|---|
| 29 | });
|
|---|
| 30 |
|
|---|
| 31 | /**
|
|---|
| 32 | * Class for managing a user's session tokens.
|
|---|
| 33 | */
|
|---|
| 34 | class Global_Table_Session_Tokens extends WP_Session_Tokens {
|
|---|
| 35 |
|
|---|
| 36 | /**
|
|---|
| 37 | * Get all sessions of a user.
|
|---|
| 38 | *
|
|---|
| 39 | * @since 4.0.0
|
|---|
| 40 | *
|
|---|
| 41 | * @return array
|
|---|
| 42 | */
|
|---|
| 43 | public function get_sessions() {
|
|---|
| 44 | global $wpdb;
|
|---|
| 45 | $_sessions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->sessions WHERE user_id = %d", $this->user_id ), ARRAY_A );
|
|---|
| 46 | if ( ! is_array( $_sessions ) ) {
|
|---|
| 47 | return array();
|
|---|
| 48 | }
|
|---|
| 49 |
|
|---|
| 50 | $sessions = array();
|
|---|
| 51 | foreach ( $_sessions as $session ) {
|
|---|
| 52 | $verifier = $session['verifier'];
|
|---|
| 53 | unset( $session['user_id'], $session['verifier'] );
|
|---|
| 54 | $sessions[ $verifier ] = $session;
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | return $sessions;
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | /**
|
|---|
| 61 | * Update a user's sessions.
|
|---|
| 62 | *
|
|---|
| 63 | * @since 4.0.0
|
|---|
| 64 | *
|
|---|
| 65 | * @param array $sessions
|
|---|
| 66 | */
|
|---|
| 67 | protected function update_sessions( $sessions ) {
|
|---|
| 68 | global $wpdb;
|
|---|
| 69 | if ( ! $sessions ) {
|
|---|
| 70 | $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->sessions WHERE user_id = %d", $this->user_id ) );
|
|---|
| 71 | return;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| 74 | $current_sessions = $this->get_sessions();
|
|---|
| 75 |
|
|---|
| 76 | // Find all sessions not yet in the DB that need to be added.
|
|---|
| 77 | $new_sessions = array_diff_key( $sessions, $current_sessions );
|
|---|
| 78 |
|
|---|
| 79 | // This class doesn't implement session updates (like "last logged in").
|
|---|
| 80 | // $changed_sessions = array_diff_assoc( ... )
|
|---|
| 81 |
|
|---|
| 82 | // Find all sessions we need to delete, either due to destruction or expiration.
|
|---|
| 83 | // Alternatively, we could set an expired flag, and keep it for auditing purposes.
|
|---|
| 84 | $to_delete = array();
|
|---|
| 85 | $time = time();
|
|---|
| 86 | foreach ( $current_sessions as $current_verifier => $current_session ) {
|
|---|
| 87 | if ( ! isset( $sessions[ $current_verifier ] ) ) {
|
|---|
| 88 | $to_delete[] = $current_verifier;
|
|---|
| 89 | } elseif ( $current_session['expiration'] < $time ) {
|
|---|
| 90 | $to_delete[] = $current_verifier;
|
|---|
| 91 | }
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| 94 | $to_delete = "'" . implode( "', '", esc_sql( $to_delete ) ) . "'";
|
|---|
| 95 | $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->sessions WHERE user_id = %d AND verifier IN ($to_delete)", $this->user_id ) );
|
|---|
| 96 |
|
|---|
| 97 | foreach ( $new_sessions as $verifier => $new_session ) {
|
|---|
| 98 | $new_session['verifier'] = $verifier;
|
|---|
| 99 | $new_session['user_id'] = $this->user_id;
|
|---|
| 100 | $wpdb->insert( $wpdb->sessions, $new_session );
|
|---|
| 101 | }
|
|---|
| 102 | }
|
|---|
| 103 | }
|
|---|