From 6ca484f40e0f67e3873bfea557405bb413bd3833 Mon Sep 17 00:00:00 2001 From: Erick Hitter <git-contrib@ethitter.com> Date: Sat, 9 Jul 2022 17:42:24 -0700 Subject: [PATCH] On activation and deactivation, clean up tokens in previous storage Fixes #2 --- inc/class-activation-deactivation-hooks.php | 93 +++++++++++++++++++++ redis-user-session-storage.php | 3 + 2 files changed, 96 insertions(+) create mode 100644 inc/class-activation-deactivation-hooks.php diff --git a/inc/class-activation-deactivation-hooks.php b/inc/class-activation-deactivation-hooks.php new file mode 100644 index 0000000..d83f17c --- /dev/null +++ b/inc/class-activation-deactivation-hooks.php @@ -0,0 +1,93 @@ +<?php +/** + * Plugin activation hooks to migrate and clean up data. + * + * @package Redis_User_Session_Storage + */ + +namespace Redis_User_Session_Storage; + +/** + * Class Activation_Deactivation_Hooks. + */ +final class Activation_Deactivation_Hooks { + /** + * Cron hook for usermeta session cleanup. + * + * @var string + */ + private $cron_hook = 'redis_user_session_storage_clean_usermeta_storage'; + + /** + * Activation_Hooks constructor. + * + * @param string $plugin_file Path to plugin's main file. + */ + public function __construct( $plugin_file ) { + register_activation_hook( + $plugin_file, + array( $this, 'clean_usermeta_storage' ) + ); + + register_deactivation_hook( + $plugin_file, + array( $this, 'clean_redis_storage' ) + ); + + add_action( + $this->cron_hook, + array( $this, 'do_scheduled_cleanup' ) + ); + } + + /** + * Remove all sessions from usermeta on activation. + * + * @return void + */ + public function clean_usermeta_storage() { + wp_schedule_single_event( + time() + 600, + 'redis_user_session_storage_clean_usermeta_storage' + ); + } + + /** + * Remove session data from usermeta using cron to avoid excessive load. + * + * While this could use `WP_User_Meta_Session_Tokens::drop_sessions()`, this + * approach is safer for large sites. + * + * @return void + */ + public function do_scheduled_cleanup() { + global $wpdb; + + $this->clean_usermeta_storage(); + + $key = 'session_tokens'; + + $count = $wpdb->get_var( + "SELECT COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '$key'" + ); + + if ( ! $count ) { + wp_clear_scheduled_hook( $this->cron_hook ); + } + + $wpdb->query( + "DELETE FROM $wpdb->usermeta WHERE meta_key = '$key' LIMIT 500" + ); + } + + /** + * Remove all sessions from Redis on deactivation. + * + * @return void + */ + public function clean_redis_storage() { + wp_clear_scheduled_hook( $this->cron_hook ); + + Plugin::drop_sessions(); + } +} diff --git a/redis-user-session-storage.php b/redis-user-session-storage.php index 7aaccbe..d2a9ba5 100644 --- a/redis-user-session-storage.php +++ b/redis-user-session-storage.php @@ -47,6 +47,9 @@ function load() { } require_once __DIR__ . '/inc/class-plugin.php'; + require_once __DIR__ . '/inc/class-activation-deactivation-hooks.php'; + + new Activation_Deactivation_Hooks( __FILE__ ); // Hooked at 9 in case old plugin is also active. add_filter( -- GitLab