diff --git a/includes/class-accepted-actions.php b/includes/class-accepted-actions.php index bf4071d8..3457883a 100644 --- a/includes/class-accepted-actions.php +++ b/includes/class-accepted-actions.php @@ -35,6 +35,7 @@ class Accepted_Actions { 'donation_new' => 'Donation_New', 'donation_subscription_cancelled' => 'Donation_Subscription_Cancelled', 'network_user_updated' => 'User_Updated', + 'network_user_deleted' => 'User_Deleted', 'newspack_network_woo_membership_updated' => 'Woocommerce_Membership_Updated', 'network_manual_sync_user' => 'User_Manually_Synced', 'network_nodes_synced' => 'Nodes_Synced', @@ -53,6 +54,7 @@ class Accepted_Actions { 'donation_new', 'donation_subscription_cancelled', 'network_user_updated', + 'network_user_deleted', 'newspack_network_woo_membership_updated', 'network_manual_sync_user', 'network_nodes_synced', diff --git a/includes/class-data-listeners.php b/includes/class-data-listeners.php index 6468c612..e4d31079 100644 --- a/includes/class-data-listeners.php +++ b/includes/class-data-listeners.php @@ -36,6 +36,7 @@ public static function register_listeners() { Data_Events::register_listener( 'woocommerce_subscription_status_changed', 'newspack_node_subscription_changed', [ __CLASS__, 'item_changed' ] ); Data_Events::register_listener( 'woocommerce_order_status_changed', 'newspack_node_order_changed', [ __CLASS__, 'item_changed' ] ); Data_Events::register_listener( 'newspack_network_user_updated', 'network_user_updated', [ __CLASS__, 'user_updated' ] ); + Data_Events::register_listener( 'delete_user', 'network_user_deleted', [ __CLASS__, 'user_deleted' ] ); Data_Events::register_listener( 'newspack_network_nodes_synced', 'network_nodes_synced', [ __CLASS__, 'nodes_synced' ] ); } @@ -87,6 +88,28 @@ public static function user_updated( $user_data ) { return $user_data; } + /** + * Filters the user data for the event being triggered + * + * @param int $id ID of the user to delete. + * @param int|null $reassign ID of the user to reassign posts and links to. + * Default null, for no reassignment. + * @param WP_User $user WP_User object of the user to delete. + * @return array + */ + public static function user_deleted( $id, $reassign, $user ) { + $should_delete = apply_filters( 'newspack_network_process_user_deleted', true, $user->user_email ); + if ( ! $should_delete ) { + Debugger::log( 'User deletion with email: ' . $user->user_email . ' was skipped due to filter use.' ); + return; + } + // Prevent deletion-related changes triggering a 'network_user_updated' event. + User_Update_Watcher::$enabled = false; + return [ + 'email' => $user->user_email, + ]; + } + /** * Filters the nodes data for the event being triggered * diff --git a/includes/incoming-events/class-user-deleted.php b/includes/incoming-events/class-user-deleted.php new file mode 100644 index 00000000..64de6a12 --- /dev/null +++ b/includes/incoming-events/class-user-deleted.php @@ -0,0 +1,75 @@ +process_user_deleted(); + } + + /** + * Process event in Node + * + * @return void + */ + public function process_in_node() { + $this->process_user_deleted(); + } + + /** + * Process user deleted + * + * @return void + */ + public function process_user_deleted() { + $email = $this->get_email(); + Debugger::log( 'Processing user deletion with email: ' . $email ); + if ( ! $email ) { + return; + } + $user = get_user_by( 'email', $email ); + if ( ! $user ) { + Debugger::log( sprintf( 'User to be deleted not found by email: %s, skipping.', $email ) ); + return; + } + + // Ensure this is a reader. + if ( ! \Newspack\Reader_Activation::is_user_reader( $user ) ) { + Debugger::log( sprintf( 'User %s is not a reader, skipping deletion.', $email ) ); + return; + } + + /** Make sure `wp_delete_user()` is available. */ + require_once ABSPATH . 'wp-admin/includes/user.php'; + + // Don't broadcast this deletion on the network. + add_filter( 'newspack_network_process_user_deleted', '__return_false' ); + // Prevent deletion-related changes triggering a 'network_user_updated' event. + \Newspack_Network\User_Update_Watcher::$enabled = false; + // Delete the user. + $result = \wp_delete_user( $user->ID ); + remove_filter( 'newspack_network_process_user_deleted', '__return_false' ); + + if ( $result ) { + Debugger::log( sprintf( 'User %s deleted.', $email ) ); + } else { + Debugger::log( sprintf( 'User %s could not be deleted.', $email ) ); + } + } +}