diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions.php b/wp/wp-content/mu-plugins/wp-native-php-sessions.php deleted file mode 100755 index 71d2bec5..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions.php +++ /dev/null @@ -1,11 +0,0 @@ - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/assets/js/notices.js b/wp/wp-content/mu-plugins/wp-native-php-sessions/assets/js/notices.js deleted file mode 100644 index f8800149..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/assets/js/notices.js +++ /dev/null @@ -1,11 +0,0 @@ -jQuery(document).ready(function($) { - $(document).on('click', '.notice-dismiss', function() { - $.ajax({ - url: ajaxurl, - type: 'POST', - data: { - action: 'dismiss_notice' - } - }); - }); -}); diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-admin.php b/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-admin.php deleted file mode 100644 index 7df48fb8..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-admin.php +++ /dev/null @@ -1,138 +0,0 @@ -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 '
'; - - echo '
'; - $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 '' . esc_html__( 'Clear All', 'wp-native-php-sessions' ) . ''; - } - echo '

' . esc_html__( 'Pantheon Sessions', 'wp-native-php-sessions' ) . '

'; - 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 '

' . esc_html( $message ) . '

'; - } - echo '
'; - - $wp_list_table = new List_Table(); - $wp_list_table->prepare_items(); - $wp_list_table->display(); - - echo '
'; - - 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() { - ?> - - ] - * : 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. - * - * [...] - * : 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' ); diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-list-table.php b/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-list-table.php deleted file mode 100644 index 05ef4bea..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-list-table.php +++ /dev/null @@ -1,87 +0,0 @@ -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 '' . esc_html( $item->data ) . ''; - } elseif ( 'session_id' === $column_name ) { - $query_args = [ - 'action' => 'pantheon_clear_session', - 'nonce' => wp_create_nonce( 'pantheon_clear_session' ), - 'session' => $item->session_id, - ]; - $actions = [ - 'clear' => '' . esc_html__( 'Clear', 'wp-native-php-sessions' ) . '', - ]; - 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 ); - } - } -} diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session-handler.php b/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session-handler.php deleted file mode 100644 index a04007c3..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session-handler.php +++ /dev/null @@ -1,126 +0,0 @@ -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; - } -} diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session.php b/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session.php deleted file mode 100644 index 71325312..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/inc/class-session.php +++ /dev/null @@ -1,322 +0,0 @@ -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'; - } - } -} diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/pantheon-sessions.php b/wp/wp-content/mu-plugins/wp-native-php-sessions/pantheon-sessions.php deleted file mode 100644 index 2aa67974..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/pantheon-sessions.php +++ /dev/null @@ -1,747 +0,0 @@ -load(); - } - return self::$instance; - } - - /** - * Load the plugin. - */ - private function load() { - - if ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) { - return; - } - - if ( defined( 'DOING_CRON' ) && DOING_CRON ) { - return; - } - - $this->define_constants(); - $this->require_files(); - - if ( PANTHEON_SESSIONS_ENABLED ) { - - $this->setup_database(); - $this->initialize_session_override(); - $this->set_ini_values(); - add_action( 'set_logged_in_cookie', [ __CLASS__, 'action_set_logged_in_cookie' ], 10, 4 ); - add_action( 'clear_auth_cookie', [ __CLASS__, 'action_clear_auth_cookie' ] ); - } - - add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); - add_action( 'wp_ajax_dismiss_notice', [ $this, 'dismiss_notice' ] ); - } - - /** - * Enqueue scripts - */ - public function enqueue_scripts() { - wp_enqueue_script( 'notices', plugins_url( '/assets/js/notices.js', __FILE__ ), [ 'jquery' ], PANTHEON_SESSIONS_VERSION, true ); - } - - /** - * Dismiss the notice when the button is clicked. - */ - public function dismiss_notice() { - $user_id = get_current_user_id(); - update_user_meta( $user_id, 'notice_dismissed', true ); - } - - /** - * Define our constants - */ - private function define_constants() { - - if ( ! defined( 'PANTHEON_SESSIONS_ENABLED' ) ) { - define( 'PANTHEON_SESSIONS_ENABLED', 1 ); - } - } - - /** - * Load required files - */ - private function require_files() { - - if ( defined( 'WP_CLI' ) && WP_CLI ) { - require_once __DIR__ . '/inc/class-cli-command.php'; - } - - if ( is_admin() ) { - require_once __DIR__ . '/inc/class-admin.php'; - $this->admin = Pantheon_Sessions\Admin::get_instance(); - } - } - - /** - * Set the PHP ini settings for the session implementation to work properly - * - * Largely adopted from Drupal 7's implementation - */ - private function set_ini_values() { - - if ( headers_sent() ) { - return; - } - - // If the user specifies the cookie domain, also use it for session name. - if ( defined( 'COOKIE_DOMAIN' ) && constant( 'COOKIE_DOMAIN' ) ) { - $cookie_domain = constant( 'COOKIE_DOMAIN' ); - $session_name = $cookie_domain; - } else { - $session_name = parse_url( home_url(), PHP_URL_HOST ); - $cookie_domain = ltrim( $session_name, '.' ); - // Strip leading periods, www., and port numbers from cookie domain. - if ( strpos( $cookie_domain, 'www.' ) === 0 ) { - $cookie_domain = substr( $cookie_domain, 4 ); - } - $cookie_domain = explode( ':', $cookie_domain ); - $cookie_domain = '.' . $cookie_domain[0]; - } - - // Per RFC 2109, cookie domains must contain at least one dot other than the - // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain. - if ( count( explode( '.', $cookie_domain ) ) > 2 && ! is_numeric( str_replace( '.', '', $cookie_domain ) ) ) { - ini_set( 'session.cookie_domain', $cookie_domain ); - } - // To prevent session cookies from being hijacked, a user can configure the - // SSL version of their website to only transfer session cookies via SSL by - // using PHP's session.cookie_secure setting. The browser will then use two - // separate session cookies for the HTTPS and HTTP versions of the site. So we - // must use different session identifiers for HTTPS and HTTP to prevent a - // cookie collision. - if ( is_ssl() ) { - ini_set( 'session.cookie_secure', true ); - } - $prefix = ini_get( 'session.cookie_secure' ) ? 'SSESS' : 'SESS'; - - session_name( $prefix . substr( hash( 'sha256', $session_name ), 0, 32 ) ); - - // Use session cookies, not transparent sessions that puts the session id in - // the query string. - $use_cookies = '1'; - if ( defined( 'WP_CLI' ) && WP_CLI ) { - $use_cookies = '0'; - } - ini_set( 'session.use_cookies', $use_cookies ); - ini_set( 'session.use_only_cookies', '1' ); - ini_set( 'session.use_trans_sid', '0' ); - // Don't send HTTP headers using PHP's session handler. - // An empty string is used here to disable the cache limiter. - ini_set( 'session.cache_limiter', '' ); - // Use httponly session cookies. Limits use by JavaScripts. - ini_set( 'session.cookie_httponly', '1' ); - // Get cookie lifetime from filters so you can put your custom lifetime. - ini_set( 'session.cookie_lifetime', (int) apply_filters( 'pantheon_session_expiration', 0 ) ); - } - - /** - * Override the default sessions implementation with our own - * - * Largely adopted from Drupal 7's implementation - */ - private function initialize_session_override() { - require_once __DIR__ . '/inc/class-session.php'; - require_once __DIR__ . '/inc/class-session-handler.php'; - $session_handler = new Pantheon_Sessions\Session_Handler(); - if ( PHP_SESSION_ACTIVE !== session_status() ) { - // Check if headers have already been sent. - if ( headers_sent( $file, $line ) ) { - // Output a friendly error message if headers are already sent. - trigger_error( - sprintf( - /* translators: %1s: File path, %2d: Line number */ - __( "Oops! The wp-native-php-sessions plugin couldn't start the session because output has already been sent. This might be caused by PHP throwing errors. Please check the code in %1s on line %2d.", 'wp-native-php-sessions' ), - esc_html( $file ), - esc_html( $line ) - ), - E_USER_WARNING - ); - } else { - session_set_save_handler( $session_handler, false ); - } - } - // Close the session before $wpdb destructs itself. - add_action( 'shutdown', 'session_write_close', 999, 0 ); - } - - /** - * Set up the database - */ - private function setup_database() { - global $wpdb, $table_prefix; - - $table_name = "{$table_prefix}pantheon_sessions"; - $wpdb->pantheon_sessions = $table_name; - $wpdb->tables[] = self::PANTHEON_SESSIONS_TABLE; - - if ( get_option( 'pantheon_session_version' ) ) { - return; - } - - $create_statement = "CREATE TABLE IF NOT EXISTS `{$table_name}` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'An auto-incrementing id to serve as an index.', - `user_id` bigint(20) unsigned NOT NULL COMMENT 'The user_id corresponding to a session, or 0 for anonymous user.', - `session_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'A session ID. The value is generated by plugin''s session handlers.', - `secure_session_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secure session ID. The value is generated by plugin''s session handlers.', - `ip_address` varchar(128) NOT NULL DEFAULT '' COMMENT 'The IP address that last used this session ID.', - `datetime` datetime DEFAULT NULL COMMENT 'The datetime value when this session last requested a page. Old records are purged by PHP automatically.', - `data` mediumblob COMMENT 'The serialized contents of \$_SESSION, an array of name/value pairs that persists across page requests by this session ID. Plugin loads \$_SESSION from here at the start of each request and saves it at the end.', - KEY `session_id` (`session_id`), - KEY `secure_session_id` (`secure_session_id`) - )"; - // phpcs:ignore - $wpdb->query( $create_statement ); - update_option( 'pantheon_session_version', PANTHEON_SESSIONS_VERSION ); - } - - /** - * Sets the user id value to the session when the user logs in. - * - * @param string $logged_in_cookie Cooke name. - * @param integer $expire When the cookie is set to expire. - * @param integer $expiration When the cookie is set to expire. - * @param integer $user_id Id for the logged-in user. - */ - public static function action_set_logged_in_cookie( $logged_in_cookie, $expire, $expiration, $user_id ) { - $session = Session::get_by_sid( session_id() ); - if ( $session ) { - $session->set_user_id( $user_id ); - } - } - - /** - * Clears the user id value from the session when the user logs out. - */ - public static function action_clear_auth_cookie() { - $session = Session::get_by_sid( session_id() ); - if ( $session ) { - $session->set_user_id( 0 ); - } - } - - /** - * Force the plugin to be the first loaded - */ - public static function force_first_load() { - $path = str_replace( WP_PLUGIN_DIR . '/', '', __FILE__ ); - $plugins = get_option( 'active_plugins' ); - if ( $plugins ) { - $key = array_search( $path, $plugins, true ); - if ( $key ) { - array_splice( $plugins, $key, 1 ); - array_unshift( $plugins, $path ); - update_option( 'active_plugins', $plugins ); - } - } - } - - /** - * Checks whether primary keys were set and notifies users if not. - */ - public static function check_native_primary_keys() { - global $wpdb; - $table_name = $wpdb->get_blog_prefix() . self::PANTHEON_SESSIONS_TABLE; - $old_table = $wpdb->get_blog_prefix() . self::BAK_PANTHEON_SESSIONS_TABLE; - $query = "SHOW KEYS FROM {$table_name} WHERE key_name = 'PRIMARY';"; - $is_pantheon = isset( $_ENV['PANTHEON_ENVIRONMENT'] ) ? true : false; - $wp_cli_cmd = $is_pantheon ? 'terminus wp <site>.<env> -- ' : 'wp '; - $cli_add_index = $wp_cli_cmd . 'pantheon session add-index'; - $key_existence = $wpdb->get_results( $query ); - $user_id = get_current_user_id(); - $dismissed = get_user_meta( $user_id, 'notice_dismissed', true ); - - if ( empty( $key_existence ) && ! $dismissed ) { - // If the key doesn't exist, recommend remediation. - ?> -
-

- -

-

- $cli_add_index" ) ); - ?> -

-
- prepare( 'SHOW TABLES LIKE %s', - $wpdb->esc_like( $old_table ) ); - - // Check for table existence and delete if present. - if ( $wpdb->get_var( $query ) == $old_table ) { - $cli_key_finalize = $wp_cli_cmd . 'pantheon session primary-key-finalize'; - $cli_key_revert = $wp_cli_cmd . 'pantheon session primary-key-revert'; - - // If an old table exists but has not been removed, suggest doing so. - ?> -
-

- $cli_key_finalize", "$cli_key_revert" ) ); - ?> -

-
- safe_output( __( 'Single site detected. Beginning processing... \n', 'wp-native-php-sessions' ), 'log' ); - - $this->add_single_index( $wpdb->prefix ); - - $this->safe_output( __( 'Operation complete, please verify that your site is working as expected. When ready, run wp pantheon session primary-key-finalize to clean up old data, or run wp pantheon session primary-key-revert if there were issues.', 'wp-native-php-sessions' ), 'log' ); - - return; - } - - $this->safe_output( __( 'Multisite installation detected. Processing Sites individually...', 'wp-native-php-sessions' ), 'log' ); - - $output = [ - 'no_session_table' => 0, - 'id_column_exists' => 0, - ]; - $site_list = $this->get_all_sites( $start_position ); - $site_count = count( $site_list ); - - for ( $i = $start_position; $i < $site_count; $i++ ) { - // translators: %s is the current blog, and then the array index of the current site. - $this->safe_output( __( 'Processing site %d. In the event of a timeout or error, resume execution starting from this point via "wp pantheon session add-index --start_point=%d". To skip this site if it does not need processing, run "wp pantheon session add-index --start_point=%d".', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ], $i, $i + 1 ] ); - - $blog_prefix = $wpdb->get_blog_prefix( $site_list[ $i ] ); - $output = $this->add_single_index( $blog_prefix, $output, true ); - - // translators: %s is the current site id. - $this->safe_output( __( 'Processing for site %d complete.', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ] ] ); - } - - if ( $output['no_session_table'] != 0 ) { - // translators: %d is the number of sites which did not have a session table. - $this->safe_output( __( '%d site(s) did not have a session table and were skipped. If this was unexpected, please review output.', 'wp-native-php-sessions' ), 'log', [ $output['no_session_table'] ] ); - } - - if ( $output['id_column_exists'] != 0 ) { - // translators: %d is the number of sites which had an ID column already. - $this->safe_output( __( '%d site(s) already had an ID column and were skipped. If this was unexpected, please review output.', 'wp-native-php-sessions' ), 'log', [ $output['id_column_exists'] ] ); - } - - $this->safe_output( __( 'Operation complete, please verify that your site is working as expected. When ready, run wp pantheon session primary-key-finalize to clean up old data, or run wp pantheon session primary-key-revert if there were issues.', 'wp-native-php-sessions' ), 'log' ); - } - - /** - * Retrieves all sites with query batches. - * - * @param int $start_position Starting position of query. - * - * @return array - */ - public function get_all_sites( $start_position ) { - $num_sites = 2; - $sites = ( $start_position == 0 ) ? [] : array_fill( 0, $start_position, null ); - $page = 0; - - while ( true ) { - $offset = ( $page * $num_sites ) + $start_position; - $next_page = get_sites( [ - 'number' => $num_sites, - 'offset' => $offset, - 'fields' => 'ids', - ] ); - - if ( empty( $next_page ) || empty( array_diff( $next_page, $sites ) ) ) { - break; - } - $sites = array_merge( $sites, $next_page ); - - ++$page; - } - - if ( $start_position == 0 ) { - unset( $sites[ $start_position - 1 ] ); - } - return $sites; - } - - /** - * Finalizes the creation of a primary key by deleting the old data. - * - * @param int $start_position Site index to begin from. - */ - public function primary_key_finalize( $start_position ) { - global $wpdb; - - if ( ! is_multisite() ) { - $this->safe_output( __( 'Single site detected. Beginning finalization.', 'wp-native-php-sessions' ), 'log' ); - - $this->primary_key_finalize_single( $wpdb->prefix ); - - $this->safe_output( __( 'Operation complete.', 'wp-native-php-sessions' ), 'log' ); - - return; - } - - $this->safe_output( __( 'Multisite installation detected. Processing sites individually.', 'wp-native-php-sessions' ), 'log' ); - - $site_list = $this->get_all_sites( $start_position ); - $output = [ 'no_old_table' => 0 ]; - $site_count = count( $site_list ); - - for ( $i = $start_position; $i < $site_count; $i++ ) { - // translators: $s is the array index of the current site. - $this->safe_output( __( 'Finalizing site %d. In the event of a timeout or error, resume execution starting from this point via "wp pantheon session primary-key-finalize --start_point=%d". To skip this site if it does not need processing, run "wp pantheon session primary-key-finalize --start_point=%d".', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ], $i, $i + 1 ] ); - - $blog_prefix = $wpdb->get_blog_prefix( $site_list[ $i ] ); - $output = $this->primary_key_finalize_single( $blog_prefix, $output, true ); - - // translators: %s is the current site id. - $this->safe_output( __( 'Finalization of site %d complete.', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ] ] ); - } - - if ( $output['no_old_table'] != 0 ) { - // translators: %d is the number of sites which did not have an old table. - $this->safe_output( __( '%d site(s) did not have an old table to delete and were skipped. If this is not expected, please review output.', 'wp-native-php-sessions' ), 'log', [ $output['no_old_table'] ] ); - } - - $this->safe_output( __( 'Finalization of all sites complete.', 'wp-native-php-sessions' ), 'log' ); - } - - /** - * Finalizes the creation of a primary key by deleting the old data. - * - * @param int $start_position Site index to begin from. - */ - public function primary_key_revert( $start_position ) { - global $wpdb; - - if ( ! is_multisite() ) { - $this->safe_output( __( 'Single site detected. Beginning revert.', 'wp-native-php-sessions' ), 'log' ); - - $this->primary_key_revert_single( $wpdb->prefix ); - - $this->safe_output( __( 'Operation complete.', 'wp-native-php-sessions' ), 'log' ); - - return; - } - - $this->safe_output( __( 'Multisite installation detected. Processing Sites individually.', 'wp-native-php-sessions' ), 'log' ); - - $site_list = $this->get_all_sites( $start_position ); - $output = [ 'no_rollback_table' => 0 ]; - $site_count = count( $site_list ); - - for ( $i = $start_position; $i < $site_count; $i++ ) { - // translators: $s is the array index of the current site. - $this->safe_output( __( 'Processing site %d. In the event of a timeout or error, resume execution starting from this point via "wp pantheon session primary-key-finalize --start_point=%d". To skip this site if it does not need processing, run "wp pantheon session primary-key-finalize --start_point=%d".', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ], $i, $i + 1 ] ); - - $blog_prefix = $wpdb->get_blog_prefix( $site_list[ $i ] ); - $output = $this->primary_key_revert_single( $blog_prefix, $output, true ); - - // translators: %d is the current site id. - $this->safe_output( __( 'Revert of site %d complete.', 'wp-native-php-sessions' ), 'log', [ $site_list[ $i ] ] ); - } - - if ( $output['no_rollback_table'] != 0 ) { - // translators: %d is the number of sites which did not have a rollback table. - $this->safe_output( __( '%d site(s) did not have a table to roll back to and were skipped. If this is not expected, please review output.', 'wp-native-php-sessions' ), 'log', [ $output['no_rollback_table'] ] ); - } - - $this->safe_output( __( 'Revert operation complete.', 'wp-native-php-sessions' ), 'log' ); - } - - /** - * Perform add_index functionality for a single site. - * - * @param string $prefix Database prefix for the blog. - * @param array $output An array of logs/errors which may occur. - * @param bool $multisite Whether the site is a multisite. - */ - public function add_single_index( $prefix, $output = [], $multisite = false ) { - global $wpdb; - $unprefixed_table = self::PANTHEON_SESSIONS_TABLE; - $table = esc_sql( $prefix . $unprefixed_table ); - $temp_clone_table = esc_sql( $prefix . 'sessions_temp_clone' ); - - // If the command has been run multiple times and there is already a - // temp_clone table, drop it. - $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $temp_clone_table ) ); - - if ( $wpdb->get_var( $query ) == $temp_clone_table ) { - $query = "DROP TABLE {$temp_clone_table};"; - $wpdb->query( $query ); - } - - if ( ! PANTHEON_SESSIONS_ENABLED ) { - $this->safe_output( __( 'Pantheon Sessions is currently disabled.', 'wp-native-php-sessions' ), 'error' ); - } - - $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ); - if ( ! $wpdb->get_var( $query ) == $table ) { - $this->safe_output( __( 'This site does not have a pantheon_sessions table, and is being skipped.', 'wp-native-php-sessions' ), 'log' ); - $output['no_session_table'] = isset( $output['no_session_table'] ) ? $output['no_session_table'] + 1 : 1; - - return $output; - } - - // Verify that the ID column/primary key does not already exist. - $query = "SHOW KEYS FROM {$table} WHERE key_name = 'PRIMARY';"; - $key_existence = $wpdb->get_results( $query ); - - // Avoid errors by not attempting to add a column that already exists. - if ( ! empty( $key_existence ) ) { - // If dealing with multisites, it's feasible that some may have the - // column and some may not, so don't stop execution if all that's - // wrong is the key exists on one. - if ( ! $multisite ) { - $type = 'error'; - } else { - $type = 'log'; - } - - $output['id_column_exists'] = isset( $output['id_column_exists'] ) ? $output['id_column_exists'] + 1 : 1; - $this->safe_output( __( 'ID column already exists and does not need to be added to the table.', 'wp-native-php-sessions' ), $type ); - - return $output; - } - - // Alert the user that the action is going to go through. - $this->safe_output( __( 'Primary Key does not exist, resolution starting.', 'wp-native-php-sessions' ), 'log' ); - - $count_query = "SELECT COUNT(*) FROM {$table};"; - $count_total = $wpdb->get_results( $count_query ); - - // Avoid errors when object returns an empty object. - if ( ! empty( $count_total ) ) { - $count_total = $count_total[0]->{'COUNT(*)'}; - } else { - $count_total = 0; - } - - if ( $count_total >= 20000 ) { - // translators: %s is the total number of rows that exist in the pantheon_sessions table. - $this->safe_output( __( 'A total of %s rows exist. To avoid service interruptions, this operation will be run in batches. Any sessions created between now and when operation completes may need to be recreated.', 'wp-native-php-sessions' ), 'log', [ $count_total ] ); - } - // Create temporary table to copy data into in batches. - $query = "CREATE TABLE {$temp_clone_table} LIKE {$table};"; - $wpdb->query( $query ); - $query = "ALTER TABLE {$temp_clone_table} ADD COLUMN id BIGINT AUTO_INCREMENT PRIMARY KEY FIRST"; - $wpdb->query( $query ); - - $batch_size = 20000; - $loops = ceil( $count_total / $batch_size ); - - for ( $i = 0; $i < $loops; $i++ ) { - $offset = $i * $batch_size; - - $query = sprintf( "INSERT INTO {$temp_clone_table} -(user_id, session_id, secure_session_id, ip_address, datetime, data) -SELECT user_id,session_id,secure_session_id,ip_address,datetime,data -FROM %s ORDER BY user_id LIMIT %d OFFSET %d", $table, $batch_size, $offset ); - $results = $wpdb->query( $query ); - $current_results = $results + ( $batch_size * $i ); - - // translators: %1 and %2 are how many rows have been processed out of how many total. - $this->safe_output( __( 'Updated %1$s / %2$s rows. ', 'wp-native-php-sessions' ), 'log', [ $current_results, $count_total ] ); - } - - // Hot swap the old table and the new table, deleting a previous old - // table if necessary. - $old_table = esc_sql( $prefix . 'bak_' . $unprefixed_table ); - $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $old_table ) ); - - if ( $wpdb->get_var( $query ) == $old_table ) { - $query = "DROP TABLE {$old_table};"; - $wpdb->query( $query ); - } - - $query = "ALTER TABLE {$table} RENAME {$old_table};"; - $wpdb->query( $query ); - $query = "ALTER TABLE {$temp_clone_table} RENAME {$table};"; - $wpdb->query( $query ); - - return $output; - } - - /** - * Finalizes the creation of a primary key by deleting the old data. - * - * @param string $prefix Database prefix for the blog. - * @param array $output An array of logs/errors which may occur. - * @param bool $multisite Whether the site is a multisite. - */ - public function primary_key_finalize_single( $prefix = null, $output = [], $multisite = false ) { - global $wpdb; - $table = esc_sql( $prefix . self::BAK_PANTHEON_SESSIONS_TABLE ); - - $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ); - - // Check for table existence and delete if present. - if ( ! $wpdb->get_var( $query ) == $table ) { - // If dealing with multisites, it's feasible that some may have a - // table and some may not, so don't stop execution if it's not found. - if ( ! $multisite ) { - $type = 'error'; - } else { - $output['no_old_table'] = isset( $output['no_old_table'] ) ? $output['no_old_table'] + 1 : 1; - $type = 'log'; - } - - $this->safe_output( __( 'Old table does not exist to be removed.', 'wp-native-php-sessions' ), $type ); - } else { - $query = "DROP TABLE {$table};"; - $wpdb->query( $query ); - - if ( ! $multisite ) { - $this->safe_output( __( 'Old table has been successfully removed.', 'wp-native-php-sessions' ), 'log' ); - } else { - $this->safe_output( __( 'Old table has been successfully removed for this site.', 'wp-native-php-sessions' ), 'log' ); - } - } - - return $output; - } - - /** - * Reverts addition of primary key. - * - * @param string $prefix Database prefix for the blog. - * @param array $output An array of logs/errors which may occur. - * @param bool $multisite Whether the site is a multisite. - */ - public function primary_key_revert_single( $prefix = null, $output = [], $multisite = false ) { - global $wpdb; - $old_clone_table = esc_sql( $prefix . self::BAK_PANTHEON_SESSIONS_TABLE ); - $temp_clone_table = esc_sql( $prefix . self::TEMP_PANTHEON_SESSIONS_TABLE ); - $table = esc_sql( $prefix . self::PANTHEON_SESSIONS_TABLE ); - - // If there is no old table to roll back to, error. - $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $old_clone_table ) ); - - // If dealing with multisites, it's feasible that some may have a - // table and some may not, so don't stop execution if it's not found. - if ( ! $multisite ) { - $type = 'error'; - } else { - $type = 'log'; - } - - if ( ! $wpdb->get_var( $query ) == $old_clone_table ) { - $this->safe_output( __( 'There is no old table to roll back to.', 'wp-native-php-sessions' ), $type ); - $output['no_rollback_table'] = isset( $output['no_rollback_table'] ) ? $output['no_rollback_table'] + 1 : 1; - - return $output; - } - - // Swap old table and new one. - $query = "ALTER TABLE {$table} RENAME {$temp_clone_table};"; - $wpdb->query( $query ); - $query = "ALTER TABLE {$old_clone_table} RENAME {$table};"; - $wpdb->query( $query ); - $this->safe_output( __( 'Rolled back to previous state successfully, dropping corrupt table.', 'wp-native-php-sessions' ), 'log' ); - - // Remove table which did not function. - $query = "DROP TABLE {$temp_clone_table}"; - $wpdb->query( $query ); - $this->safe_output( __( 'Site processing complete.', 'wp-native-php-sessions' ), 'log' ); - - return $output; - } - - /** - * Provide output to users, whether it's being run in WP_CLI or not. - * - * @param string $message Message to be printed. - * @param string $type If message is being printed through WP_CLI, what type of message. - * @param array $variables If sprintf is needed, an array of values. - * - * @return void - */ - protected function safe_output( $message, $type, array $variables = [] ) { - if ( defined( 'WP_CLI' ) && WP_CLI ) { - WP_CLI::$type( vsprintf( $message, $variables ) ); - return; - } - - print "\n" . wp_kses_post( vsprintf( $message, $variables ) ); - - // Calling WP_CLI::error triggers an exit, but we still need to exist even if we don't have WP_CLI available. - if ( $type === 'error' ) { - exit( 1 ); - } - } -} - -/** - * Release the kraken! - * - * @return object - */ -function Pantheon_Sessions() { - return Pantheon_Sessions::get_instance(); -} - -add_action( 'activated_plugin', 'Pantheon_Sessions::force_first_load' ); -add_action( 'admin_notices', 'Pantheon_Sessions::check_native_primary_keys' ); - -Pantheon_Sessions(); diff --git a/wp/wp-content/mu-plugins/wp-native-php-sessions/readme.txt b/wp/wp-content/mu-plugins/wp-native-php-sessions/readme.txt deleted file mode 100644 index 83a5d5a0..00000000 --- a/wp/wp-content/mu-plugins/wp-native-php-sessions/readme.txt +++ /dev/null @@ -1,229 +0,0 @@ -=== WordPress Native PHP Sessions === -Contributors: getpantheon, outlandish josh, mpvanwinkle77, danielbachhuber, andrew.taylor, jazzs3quence, stovak, jspellman, rwagner00 -Tags: comments, sessions -Requires at least: 4.7 -Tested up to: 6.3 -Stable tag: 1.4.3 -Requires PHP: 5.4 -License: GPLv2 or later -License URI: http://www.gnu.org/licenses/gpl-2.0.html - -Use native PHP sessions and stay horizontally scalable. Better living through superior technology. - -== Description == - -[![Build Status](https://travis-ci.org/pantheon-systems/wp-native-php-sessions.svg?branch=master)](https://travis-ci.org/pantheon-systems/wp-native-php-sessions) [![CircleCI](https://circleci.com/gh/pantheon-systems/wp-native-php-sessions/tree/master.svg?style=svg)](https://circleci.com/gh/pantheon-systems/wp-native-php-sessions/tree/master) - -WordPress core does not use PHP sessions, but sometimes they are required by your use-case, a plugin or theme. - -This plugin implements PHP's native session handlers, backed by the WordPress database. This allows plugins, themes, and custom code to safely use PHP `$_SESSION`s in a distributed environment where PHP's default tempfile storage just won't work. - -Note that primary development is on GitHub if you would like to contribute: - -https://github.com/pantheon-systems/wp-native-php-sessions - -== Installation == - -1. Upload to the `/wp-content/plugins/` directory -2. Activate the plugin through the 'Plugins' menu in WordPress - -That's it! - -== Configuration == - -By default the session lifetime is set to 0, which is until the browser is closed. - -To override this use the `pantheon_session_expiration` filter before the WordPress Native PHP Sessions plugin is loaded. For example a small Must-use plugin (a.k.a. mu-plugin) could contain: - - get_data() [[#237(https://github.com/pantheon-systems/wp-native-php-sessions/pull/237)]] (reported [on WordPress.org](https://wordpress.org/support/topic/php-warning-session_start-failed-to-read-session-data-user/)) -* Update CODEOWNERS file [[#239](https://github.com/pantheon-systems/wp-native-php-sessions/pull/239)] -* Fix GPL license in `composer.json` file [[#236](https://github.com/pantheon-systems/wp-native-php-sessions/pull/236)] -* Bump grunt from 1.5.3 to 1.6.1 [[#235](https://github.com/pantheon-systems/wp-native-php-sessions/pull/235)] - -= 1.3.3 (January 25, 2023) = -* Bump version in pantheon-sessions.php [[#234](https://github.com/pantheon-systems/wp-native-php-sessions/pull/234)]. - -= 1.3.2 (January 25, 2023) = -* PHP 8.2 compatibility [[#232](https://github.com/pantheon-systems/wp-native-php-sessions/pull/232)]. -* Bump dealerdirect/phpcodesniffer-composer-installer from 0.7.2 to 1.0.0 [[#229](https://github.com/pantheon-systems/wp-native-php-sessions/pull/229)]. -* Update images for lint and test-behat jobs [[#228](https://github.com/pantheon-systems/wp-native-php-sessions/pull/228)]. - -= 1.3.1 (December 5, 2022) = -* Document session lifetime handling [[#224](https://github.com/pantheon-systems/wp-native-php-sessions/pull/224)]. -* Make dependabot target develop branch [[#226](https://github.com/pantheon-systems/wp-native-php-sessions/pull/226)]. -* Ignore `.wordpress-org` directory [[#223](https://github.com/pantheon-systems/wp-native-php-sessions/pull/223)]. - -= 1.3.0 (November 28th, 2022) = -* Added CONTRIBUTING.MD and GitHub action to automate deployments to wp.org. [[#219](https://github.com/pantheon-systems/wp-native-php-sessions/pull/219)] - -= 1.2.5 (October 28, 2022) = -* Added `#[ReturnTypeWillChange]` where required to silence deprecation warnings in PHP 8.1. [[#216](https://github.com/pantheon-systems/wp-native-php-sessions/pull/216)] - -= 1.2.4 (September 14th, 2021) = -* Increases data blob size from 64k to 16M for new session tables; existing tables will need to manually modify the column if they want to apply this change [[#193](https://github.com/pantheon-systems/wp-native-php-sessions/pull/193)]. - -= 1.2.3 (April 9th, 2021) = -* Assigns the table name to a variable before using in query [[#188](https://github.com/pantheon-systems/wp-native-php-sessions/pull/188)]. - -= 1.2.2 (March 29th, 2021) = -* Includes an auto-incrementing `id` column for replication support [[#187](https://github.com/pantheon-systems/wp-native-php-sessions/pull/187)]. - -= 1.2.1 (September 17th, 2020) = -* Plugin textdomain needs to be the same as the WordPress.org slug [[#169](https://github.com/pantheon-systems/wp-native-php-sessions/pull/169)]. - -= 1.2.0 (May 18th, 2020) = -* Avoids using cookies for sessions when WP-CLI is executing [[#154](https://github.com/pantheon-systems/wp-native-php-sessions/pull/154)]. - -= 1.1.0 (April 23rd, 2020) = -* Avoids initializing PHP sessions when doing cron [[#149](https://github.com/pantheon-systems/wp-native-php-sessions/pull/149)]. - -= 1.0.0 (March 2nd, 2020) = -* Plugin is stable. - -= 0.9.0 (October 14th, 2019) = -* Refactors session callback logic into `Session_Handler` abstraction, fixing PHP notice in PHP 7.3 [[#135](https://github.com/pantheon-systems/wp-native-php-sessions/pull/135)]. - -= 0.8.1 (August 19th, 2019) = -* Fixes handling of 'X-Forwarded-For' header in `get_client_ip_server()` [[#126](https://github.com/pantheon-systems/wp-native-php-sessions/pull/126)]. - -= 0.8.0 (August 13th, 2019) = -* Respects various `HTTP_*` sources for client IP address [[#122](https://github.com/pantheon-systems/wp-native-php-sessions/pull/122)]. - -= 0.7.0 (April 3rd, 2019) = -* Adds a safety check that restores `$wpdb` when it's missing. - -= 0.6.9 (May 15th, 2018) = -* Ensures `_pantheon_session_destroy()` uses a return value. - -= 0.6.8 (May 4th, 2018) = -* Switches to `E_USER_WARNING` instead of `E_WARNING` when triggering errors. - -= 0.6.7 (April 26th, 2018) = -* Disables plugin load when `WP_INSTALLING`, because session table creation breaks installation process. - -= 0.6.6 (March 8th, 2018) = -* Restores session instantiation when WP-CLI is executing, because not doing so causes other problems. - -= 0.6.5 (February 6th, 2018) = -* Disables session instantiation when `defined( 'WP_CLI' ) && WP_CLI` because sessions don't work on CLI. - -= 0.6.4 (October 10th, 2017) = -* Triggers PHP error when plugin fails to write session to database. - -= 0.6.3 (September 29th, 2017) = -* Returns false when we entirely fail to generate a session. - -= 0.6.2 (June 6th, 2017) = -* Syncs session user id when a user logs in and logs out. - -= 0.6.1 (May 25th, 2017) = -* Bug fix: Prevents warning session_write_close() expects exactly 0 parameters, 1 given. - -= 0.6.0 (November 23rd, 2016) = -* Bug fix: Prevents PHP fatal error in `session_write_close()` by running on WordPress' `shutdown` action, before `$wpdb` destructs itself. -* Bug fix: Stores the actual user id in the sessions table, instead of `(bool) $user_id`. - -= 0.5 = -* Compatibility with PHP 7. -* Adds `pantheon_session_expiration` filter to modify session expiration value. - -= 0.4 = -* Adjustment to `session_id()` behavior for wider compatibility -* Using superglobal for REQUEST_TIME as opposed to `time()` - -= 0.3 = -* Fixes issue related to WordPress plugin load order - -= 0.1 = -* Initial release