: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
'group_description' => __( 'User’s location data used for the Community Events in the WordPress Events and News dashboard widget.' ),
'item_id' => "community-events-location-{$user->ID}",
'data' => $location_data_to_export,
if ( isset( $user_meta['session_tokens'] ) ) {
$session_tokens = maybe_unserialize( $user_meta['session_tokens'][0] );
$session_tokens_props_to_export = array(
'expiration' => __( 'Expiration' ),
'ua' => __( 'User Agent' ),
'login' => __( 'Last Login' ),
foreach ( $session_tokens as $token_key => $session_token ) {
$session_tokens_data_to_export = array();
foreach ( $session_tokens_props_to_export as $key => $name ) {
if ( ! empty( $session_token[ $key ] ) ) {
$value = $session_token[ $key ];
if ( in_array( $key, array( 'expiration', 'login' ), true ) ) {
$value = date_i18n( 'F d, Y H:i A', $value );
$session_tokens_data_to_export[] = array(
$data_to_export[] = array(
'group_id' => 'session-tokens',
'group_label' => __( 'Session Tokens' ),
'group_description' => __( 'User’s Session Tokens data.' ),
'item_id' => "session-tokens-{$user->ID}-{$token_key}",
'data' => $session_tokens_data_to_export,
'data' => $data_to_export,
* Updates log when privacy request is confirmed.
* @param int $request_id ID of the request.
function _wp_privacy_account_request_confirmed( $request_id ) {
$request = wp_get_user_request( $request_id );
if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) {
update_post_meta( $request_id, '_wp_user_request_confirmed_timestamp', time() );
'post_status' => 'request-confirmed',
* Notifies the site administrator via email when a request is confirmed.
* Without this, the admin would have to manually check the site to see if any
* action was needed on their part yet.
* @param int $request_id The ID of the request.
function _wp_privacy_send_request_confirmation_notification( $request_id ) {
$request = wp_get_user_request( $request_id );
if ( ! ( $request instanceof WP_User_Request ) || 'request-confirmed' !== $request->status ) {
$already_notified = (bool) get_post_meta( $request_id, '_wp_admin_notified', true );
if ( $already_notified ) {
if ( 'export_personal_data' === $request->action_name ) {
$manage_url = admin_url( 'export-personal-data.php' );
} elseif ( 'remove_personal_data' === $request->action_name ) {
$manage_url = admin_url( 'erase-personal-data.php' );
$action_description = wp_user_request_action_description( $request->action_name );
* Filters the recipient of the data request confirmation notification.
* In a Multisite environment, this will default to the email address of the
* network admin because, by default, single site admins do not have the
* capabilities required to process requests. Some networks may wish to
* delegate those capabilities to a single-site admin, or a dedicated person
* responsible for managing privacy requests.
* @param string $admin_email The email address of the notification recipient.
* @param WP_User_Request $request The request that is initiating the notification.
$admin_email = apply_filters( 'user_request_confirmed_email_to', get_site_option( 'admin_email' ), $request );
'user_email' => $request->email,
'description' => $action_description,
'manage_url' => $manage_url,
'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
'admin_email' => $admin_email,
/* translators: Privacy data request confirmed notification email subject. 1: Site title, 2: Name of the confirmed action. */
__( '[%1$s] Action Confirmed: %2$s' ),
* Filters the subject of the user request confirmation email.
* @param string $subject The email subject.
* @param string $sitename The name of the site.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $user_email The email address confirming a request
* @type string $description Description of the action being performed so the user knows what the email is for.
* @type string $manage_url The link to click manage privacy requests of this type.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
* @type string $admin_email The administrator email receiving the mail.
$subject = apply_filters( 'user_request_confirmed_email_subject', $subject, $email_data['sitename'], $email_data );
/* translators: Do not translate SITENAME, USER_EMAIL, DESCRIPTION, MANAGE_URL, SITEURL; those are placeholders. */
A user data privacy request has been confirmed on ###SITENAME###:
Request: ###DESCRIPTION###
You can view and manage these data privacy requests here:
* Filters the body of the user request confirmation email.
* The email is sent to an administrator when a user request is confirmed.
* The following strings have a special meaning and will get replaced dynamically:
* ###SITENAME### The name of the site.
* ###USER_EMAIL### The user email for the request.
* ###DESCRIPTION### Description of the action being performed so the user knows what the email is for.
* ###MANAGE_URL### The URL to manage requests.
* ###SITEURL### The URL to the site.
* @deprecated 5.8.0 Use {@see 'user_request_confirmed_email_content'} instead.
* For user erasure fulfillment email content
* use {@see 'user_erasure_fulfillment_email_content'} instead.
* @param string $content The email content.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $user_email The email address confirming a request
* @type string $description Description of the action being performed
* so the user knows what the email is for.
* @type string $manage_url The link to click manage privacy requests of this type.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
* @type string $admin_email The administrator email receiving the mail.
$content = apply_filters_deprecated(
'user_confirmed_action_email_content',
array( $content, $email_data ),
/* translators: 1 & 2: Deprecation replacement options. */
'user_request_confirmed_email_content',
'user_erasure_fulfillment_email_content'
* Filters the body of the user request confirmation email.
* The email is sent to an administrator when a user request is confirmed.
* The following strings have a special meaning and will get replaced dynamically:
* ###SITENAME### The name of the site.
* ###USER_EMAIL### The user email for the request.
* ###DESCRIPTION### Description of the action being performed so the user knows what the email is for.
* ###MANAGE_URL### The URL to manage requests.
* ###SITEURL### The URL to the site.
* @param string $content The email content.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $user_email The email address confirming a request
* @type string $description Description of the action being performed so the user knows what the email is for.
* @type string $manage_url The link to click manage privacy requests of this type.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
* @type string $admin_email The administrator email receiving the mail.
$content = apply_filters( 'user_request_confirmed_email_content', $content, $email_data );
$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
$content = str_replace( '###USER_EMAIL###', $email_data['user_email'], $content );
$content = str_replace( '###DESCRIPTION###', $email_data['description'], $content );
$content = str_replace( '###MANAGE_URL###', sanitize_url( $email_data['manage_url'] ), $content );
$content = str_replace( '###SITEURL###', sanitize_url( $email_data['siteurl'] ), $content );
* Filters the headers of the user request confirmation email.
* @param string|array $headers The email headers.
* @param string $subject The email subject.
* @param string $content The email content.
* @param int $request_id The request ID.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $user_email The email address confirming a request
* @type string $description Description of the action being performed so the user knows what the email is for.
* @type string $manage_url The link to click manage privacy requests of this type.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
* @type string $admin_email The administrator email receiving the mail.
$headers = apply_filters( 'user_request_confirmed_email_headers', $headers, $subject, $content, $request_id, $email_data );
$email_sent = wp_mail( $email_data['admin_email'], $subject, $content, $headers );
update_post_meta( $request_id, '_wp_admin_notified', true );
* Notifies the user when their erasure request is fulfilled.
* Without this, the user would never know if their data was actually erased.
* @param int $request_id The privacy request post ID associated with this request.
function _wp_privacy_send_erasure_fulfillment_notification( $request_id ) {
$request = wp_get_user_request( $request_id );
if ( ! ( $request instanceof WP_User_Request ) || 'request-completed' !== $request->status ) {
$already_notified = (bool) get_post_meta( $request_id, '_wp_user_notified', true );
if ( $already_notified ) {
// Localize message content for user; fallback to site default for visitors.
if ( ! empty( $request->user_id ) ) {
$switched_locale = switch_to_user_locale( $request->user_id );
$switched_locale = switch_to_locale( get_locale() );
* Filters the recipient of the data erasure fulfillment notification.
* @param string $user_email The email address of the notification recipient.
* @param WP_User_Request $request The request that is initiating the notification.
$user_email = apply_filters( 'user_erasure_fulfillment_email_to', $request->email, $request );
'message_recipient' => $user_email,
'privacy_policy_url' => get_privacy_policy_url(),
'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
/* translators: Erasure request fulfilled notification email subject. %s: Site title. */
__( '[%s] Erasure Request Fulfilled' ),
* Filters the subject of the email sent when an erasure request is completed.
* @deprecated 5.8.0 Use {@see 'user_erasure_fulfillment_email_subject'} instead.
* @param string $subject The email subject.
* @param string $sitename The name of the site.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $message_recipient The address that the email will be sent to. Defaults
* to the value of `$request->email`, but can be changed
* by the `user_erasure_fulfillment_email_to` filter.
* @type string $privacy_policy_url Privacy policy URL.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
$subject = apply_filters_deprecated(
'user_erasure_complete_email_subject',
array( $subject, $email_data['sitename'], $email_data ),
'user_erasure_fulfillment_email_subject'
* Filters the subject of the email sent when an erasure request is completed.
* @param string $subject The email subject.
* @param string $sitename The name of the site.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $message_recipient The address that the email will be sent to. Defaults
* to the value of `$request->email`, but can be changed
* by the `user_erasure_fulfillment_email_to` filter.
* @type string $privacy_policy_url Privacy policy URL.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
$subject = apply_filters( 'user_erasure_fulfillment_email_subject', $subject, $email_data['sitename'], $email_data );
/* translators: Do not translate SITENAME, SITEURL; those are placeholders. */
Your request to erase your personal data on ###SITENAME### has been completed.
If you have any follow-up questions or concerns, please contact the site administrator.
if ( ! empty( $email_data['privacy_policy_url'] ) ) {
/* translators: Do not translate SITENAME, SITEURL, PRIVACY_POLICY_URL; those are placeholders. */
Your request to erase your personal data on ###SITENAME### has been completed.
If you have any follow-up questions or concerns, please contact the site administrator.
For more information, you can also read our privacy policy: ###PRIVACY_POLICY_URL###
* Filters the body of the data erasure fulfillment notification.
* The email is sent to a user when their data erasure request is fulfilled
* The following strings have a special meaning and will get replaced dynamically:
* ###SITENAME### The name of the site.
* ###PRIVACY_POLICY_URL### Privacy policy page URL.
* ###SITEURL### The URL to the site.
* @deprecated 5.8.0 Use {@see 'user_erasure_fulfillment_email_content'} instead.
* For user request confirmation email content
* use {@see 'user_request_confirmed_email_content'} instead.
* @param string $content The email content.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $message_recipient The address that the email will be sent to. Defaults
* to the value of `$request->email`, but can be changed
* by the `user_erasure_fulfillment_email_to` filter.
* @type string $privacy_policy_url Privacy policy URL.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
$content = apply_filters_deprecated(
'user_confirmed_action_email_content',
array( $content, $email_data ),
/* translators: 1 & 2: Deprecation replacement options. */
'user_erasure_fulfillment_email_content',
'user_request_confirmed_email_content'
* Filters the body of the data erasure fulfillment notification.
* The email is sent to a user when their data erasure request is fulfilled
* The following strings have a special meaning and will get replaced dynamically:
* ###SITENAME### The name of the site.
* ###PRIVACY_POLICY_URL### Privacy policy page URL.
* ###SITEURL### The URL to the site.
* @param string $content The email content.
* @param array $email_data {
* Data relating to the account action email.
* @type WP_User_Request $request User request object.
* @type string $message_recipient The address that the email will be sent to. Defaults
* to the value of `$request->email`, but can be changed
* by the `user_erasure_fulfillment_email_to` filter.
* @type string $privacy_policy_url Privacy policy URL.
* @type string $sitename The site name sending the mail.
* @type string $siteurl The site URL sending the mail.
$content = apply_filters( 'user_erasure_fulfillment_email_content', $content, $email_data );
$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
$content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content );
$content = str_replace( '###SITEURL###', sanitize_url( $email_data['siteurl'] ), $content );
* Filters the headers of the data erasure fulfillment notification.