WordPress.org

Make WordPress Core

Ticket #20276: sessions-table.php

File sessions-table.php, 2.8 KB (added by nacin, 5 years ago)
Line 
1<?php
2
3add_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 */
34class 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}