From 55028d653384650af242a24d3d51ac7e02bd95ba Mon Sep 17 00:00:00 2001 From: iFlair Date: Wed, 3 Dec 2025 12:55:52 +0530 Subject: [PATCH] Fix: biographical info not erased during personal data erasure (#64282) --- src/wp-includes/default-filters.php | 1 + src/wp-includes/user.php | 95 +++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 68dccd979f2fe..0ae6d65bac516 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -444,6 +444,7 @@ add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_comment_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_media_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_user_personal_data_exporter', 1 ); +add_filter( 'wp_privacy_personal_data_erasers', 'wp_register_user_personal_data_eraser', 1 ); add_filter( 'wp_privacy_personal_data_erasers', 'wp_register_comment_personal_data_eraser' ); add_action( 'init', 'wp_schedule_delete_old_privacy_export_files' ); add_action( 'wp_privacy_delete_old_export_files', 'wp_privacy_delete_old_export_files' ); diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 0e491d666087a..cbb937a3ee237 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -4165,6 +4165,101 @@ static function ( $item ) use ( $reserved_names ) { ); } +/** +* Registers the personal data eraser for users. +* +* @since 6.7.0 +* +* @param array $erasers An array of personal data erasers. +* @return array An array of personal data erasers. +*/ +function wp_register_user_personal_data_eraser( $erasers ) { + $erasers['wordpress-user'] = array( + 'eraser_friendly_name' => __( 'WordPress User' ), + 'callback' => 'wp_user_personal_data_eraser', + ); + + return $erasers; +} + +/** +* Erases core user profile data for a personal data erasure request. +* +* @since 6.7.0 +* +* @param string $email_address The user's email address. +* @param int $page Unused. Part of the eraser signature. +* @return array { +* Data removal results. +* +* @type bool $items_removed Whether items were actually removed. +* @type bool $items_retained Whether items were retained. +* @type string[] $messages An array of messages about retained items. +* @type bool $done Whether the eraser is finished. +* } +*/ +function wp_user_personal_data_eraser( $email_address, $page = 1 ) { + $response = array( + 'items_removed' => false, + 'items_retained' => false, + 'messages' => array(), + 'done' => true, + ); + + $email_address = trim( $email_address ); + + if ( empty( $email_address ) ) { + return $response; + } + + $user = get_user_by( 'email', $email_address ); + + if ( ! $user instanceof WP_User ) { + return $response; + } + + $user_id = $user->ID; + + $meta_keys_to_erase = array( 'description' ); + + /** + * Filters the list of user meta keys removed during a personal data erasure request. + * + * @since 6.7.0 + * + * @param string[] $meta_keys_to_erase User meta keys slated for deletion. + * @param WP_User $user The user whose data is being erased. + */ + $meta_keys_to_erase = apply_filters( 'wp_privacy_user_personal_data_eraser_meta_keys', $meta_keys_to_erase, $user ); + + foreach ( $meta_keys_to_erase as $meta_key ) { + $meta_key = sanitize_key( $meta_key ); + + if ( '' === $meta_key ) { + continue; + } + + if ( ! metadata_exists( 'user', $user_id, $meta_key ) ) { + continue; + } + + $deleted = delete_user_meta( $user_id, $meta_key ); + + if ( $deleted ) { + $response['items_removed'] = true; + } else { + $response['items_retained'] = true; + $response['messages'][] = sprintf( + /* translators: %s: User meta key. */ + __( 'User meta "%s" could not be erased.' ), + $meta_key + ); + } + } + + return $response; +} + /** * Updates log when privacy request is confirmed. *