diff --git a/src/wp-admin/includes/privacy-tools.php b/src/wp-admin/includes/privacy-tools.php index aa2f856e84..efe46cce32 100644 --- a/src/wp-admin/includes/privacy-tools.php +++ b/src/wp-admin/includes/privacy-tools.php @@ -493,6 +493,57 @@ function wp_privacy_send_personal_data_export_email( $request_id ) { $expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS ); $expiration_date = date_i18n( get_option( 'date_format' ), time() + $expiration ); + $export_file_url = get_post_meta( $request_id, '_export_file_url', true ); + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + $site_url = home_url(); + + /** + * Filters the recipient of the personal data export email notification. + * Should be used with great caution to avoid sending the data export link to wrong emails. + * + * @since 5.3.0 + * + * @param string $request_email The email address of the notification recipient. + * @param WP_User_Request $request The request that is initiating the notification. + */ + $request_email = apply_filters( 'wp_privacy_personal_data_email_to', $request->email, $request ); + + $email_data = array( + 'request' => $request, + 'expiration' => $expiration, + 'expiration_date' => $expiration_date, + 'message_recipient' => $request_email, + 'export_file_url' => $export_file_url, + 'sitename' => $site_name, + 'siteurl' => $site_url, + ); + + /* translators: Personal data export notification email subject. %s: Site title. */ + $subject = sprintf( __( '[%s] Personal Data Export' ), $site_name ); + + /** + * Filters the subject of the email sent when an export request is completed. + * + * @since 5.3.0 + * + * @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 int $expiration The time in seconds until the export file expires. + * @type string $expiration_date The localized date and time when the export file expires. + * @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 `wp_privacy_personal_data_email_to` filter. + * @type string $export_file_url The export file URL. + * @type string $sitename The site name sending the mail. + * @type string $siteurl The site URL sending the mail. + * } + */ + $subject = apply_filters( 'wp_privacy_personal_data_email_subject', $subject, $site_name, $email_data ); + /* translators: Do not translate EXPIRATION, LINK, SITENAME, SITEURL: those are placeholders. */ $email_text = __( 'Howdy, @@ -519,32 +570,32 @@ All at ###SITENAME### * ###SITEURL### The URL to the site. * * @since 4.9.6 + * @since 5.3.0 Introduced the `$email_data` array. * - * @param string $email_text Text in the email. - * @param int $request_id The request ID for this personal data export. + * @param string $email_text Text in the email. + * @param int $request_id The request ID for this personal data export. + * @param array $email_data { + * Data relating to the account action email. + * + * @type WP_User_Request $request User request object. + * @type int $expiration The time in seconds until the export file expires. + * @type string $expiration_date The localized date and time when the export file expires. + * @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 `wp_privacy_personal_data_email_to` filter. + * @type string $export_file_url The export file URL. + * @type string $sitename The site name sending the mail. + * @type string $siteurl The site URL sending the mail. */ - $content = apply_filters( 'wp_privacy_personal_data_email_content', $email_text, $request_id ); - - $email_address = $request->email; - $export_file_url = get_post_meta( $request_id, '_export_file_url', true ); - $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - $site_url = home_url(); + $content = apply_filters( 'wp_privacy_personal_data_email_content', $email_text, $request_id, $email_data ); $content = str_replace( '###EXPIRATION###', $expiration_date, $content ); $content = str_replace( '###LINK###', esc_url_raw( $export_file_url ), $content ); - $content = str_replace( '###EMAIL###', $email_address, $content ); + $content = str_replace( '###EMAIL###', $request_email, $content ); $content = str_replace( '###SITENAME###', $site_name, $content ); $content = str_replace( '###SITEURL###', esc_url_raw( $site_url ), $content ); - $mail_success = wp_mail( - $email_address, - sprintf( - /* translators: Personal data export notification email subject. %s: Site title. */ - __( '[%s] Personal Data Export' ), - $site_name - ), - $content - ); + $mail_success = wp_mail( $request_email, $subject, $content ); if ( $switched_locale ) { restore_previous_locale(); diff --git a/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php b/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php index 268ecb8d96..13ee61a59d 100644 --- a/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php +++ b/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php @@ -174,6 +174,58 @@ class Tests_Privacy_WpPrivacySendPersonalDataExportEmail extends WP_UnitTestCase return 1513632600 - time(); } + /** + * The email address of the recipient of the personal data export notification should be filterable. + * + * @ticket 46303 + */ + public function test_email_address_of_recipient_should_be_filterable() { + add_filter( 'wp_privacy_personal_data_email_to', array( $this, 'filter_email_address' ) ); + wp_privacy_send_personal_data_export_email( self::$request_id ); + + $mailer = tests_retrieve_phpmailer_instance(); + + $this->assertSame( 'modified-' . self::$requester_email, $mailer->get_recipient( 'to' )->address ); + } + + /** + * Filter callback that modifies the email address of the recipient of the personal data export notification. + * + * @since 5.3.0 + * + * @param string $user_email The email address of the notification recipient. + * @return string $user_email The modified email address of the notification recipient. + */ + public function filter_email_address( $user_email ) { + return 'modified-' . $user_email; + } + + /** + * The email subject of the personal data export notification should be filterable. + * + * @ticket 46303 + */ + public function test_email_subject_should_be_filterable() { + add_filter( 'wp_privacy_personal_data_email_subject', array( $this, 'filter_email_subject' ) ); + wp_privacy_send_personal_data_export_email( self::$request_id ); + + $mailer = tests_retrieve_phpmailer_instance(); + + $this->assertSame( 'Modified subject', $mailer->get_sent()->subject ); + } + + /** + * Filter callback that modifies the email subject of the data erasure fulfillment notification. + * + * @since 5.3.0 + * + * @param string $subject The email subject. + * @return string $subject The email subject. + */ + public function filter_email_subject( $subject ) { + return 'Modified subject'; + } + /** * The email content should be filterable. * @@ -200,6 +252,47 @@ class Tests_Privacy_WpPrivacySendPersonalDataExportEmail extends WP_UnitTestCase return 'Custom content for request ID: ' . $request_id; } + /** + * The email content should be filterable using the $email_data + * + * @ticket 46303 + */ + public function test_email_content_should_be_filterable_using_email_data() { + add_filter( 'wp_privacy_personal_data_email_content', array( $this, 'modify_email_content_with_email_data' ), 10, 3 ); + wp_privacy_send_personal_data_export_email( self::$request_id ); + + $site_url = home_url(); + $mailer = tests_retrieve_phpmailer_instance(); + $this->assertContains( 'Custom content using the $site_url of $email_data: ' . $site_url, $mailer->get_sent()->body ); + } + + /** + * Filter callback that modifies the text of the email by using the $email_data sent with a personal data export file. + * + * @since 5.3.0 + * + * @param string $email_text Text in the email. + * @param int $request_id The request ID for this personal data export. + * @param array $email_data { + * Data relating to the account action email. + * + * @type WP_User_Request $request User request object. + * @type int $expiration The time in seconds until the export file expires. + * @type string $expiration_date The localized date and time when the export file expires. + * @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 `wp_privacy_personal_data_email_to` filter. + * @type string $export_file_url The export file URL. + * @type string $sitename The site name sending the mail. + * @type string $siteurl The site URL sending the mail. + * } + * + * @return string $email_text Text in the email. + */ + public function modify_email_content_with_email_data( $email_text, $request_id, $email_data ) { + return 'Custom content using the $site_url of $email_data: ' . $email_data['siteurl']; + } + /** * The function should respect the user locale settings when the site uses the default locale. *