@@ -4328,10 +4328,10 @@ function wp_ajax_edit_theme_plugin_file() {
43284328}
43294329
43304330function wp_ajax_wp_privacy_export_personal_data () {
4331- // check_ajax_referer( 'wp-privacy-export-personal-data', 'security' );
4331+ check_ajax_referer ( 'wp-privacy-export-personal-data ' , 'security ' );
43324332
43334333 if ( ! current_user_can ( 'manage_options ' ) ) {
4334- wp_send_json_error ( ' access denied ' );
4334+ wp_send_json_error ( __ ( ' Error: Invalid request. ' ) );
43354335 }
43364336
43374337 $ email_address = sanitize_text_field ( $ _POST ['email ' ] );
@@ -4341,7 +4341,7 @@ function wp_ajax_wp_privacy_export_personal_data() {
43414341 /**
43424342 * Filters the array of exporter callbacks.
43434343 *
4344- * @since 4.9.5.
4344+ * @since 4.9.6
43454345 *
43464346 * @param array $args {
43474347 * An array of callable exporters of personal data. Default empty array.
@@ -4429,7 +4429,7 @@ function wp_ajax_wp_privacy_export_personal_data() {
44294429 *
44304430 * Allows the export response to be consumed by destinations in addition to Ajax.
44314431 *
4432- * @since 4.9.5
4432+ * @since 4.9.6
44334433 *
44344434 * @param array $response The personal data for the given exporter and page.
44354435 * @param int $exporter_index The index of the exporter that provided this data.
@@ -4443,3 +4443,197 @@ function wp_ajax_wp_privacy_export_personal_data() {
44434443
44444444 wp_send_json_success ( $ response );
44454445}
4446+
4447+ /**
4448+ * Ajax handler for erasing personal data.
4449+ *
4450+ * @since 4.9.6
4451+ */
4452+ function wp_ajax_wp_privacy_erase_personal_data () {
4453+ $ request_id = (int ) $ _POST ['id ' ];
4454+
4455+ if ( empty ( $ request_id ) ) {
4456+ wp_send_json_error ( __ ( 'Error: Invalid request ID. ' ) );
4457+ }
4458+
4459+ if ( ! current_user_can ( 'delete_users ' ) ) {
4460+ wp_send_json_error ( __ ( 'Error: Invalid request. ' ) );
4461+ }
4462+
4463+ check_ajax_referer ( 'wp-privacy-erase-personal-data- ' . $ request_id , 'security ' );
4464+
4465+ // Find the request CPT
4466+ $ request = get_post ( $ request_id );
4467+ if ( 'user_remove_request ' !== $ request ->post_type ) {
4468+ wp_send_json_error ( __ ( 'Error: Invalid request ID. ' ) );
4469+ }
4470+
4471+ $ email_address = get_post_meta ( $ request_id , '_user_email ' , true );
4472+
4473+ if ( ! is_email ( $ email_address ) ) {
4474+ wp_send_json_error ( __ ( 'Error: Invalid email address in request. ' ) );
4475+ }
4476+
4477+ $ eraser_index = (int ) $ _POST ['eraser ' ];
4478+ $ page = (int ) $ _POST ['page ' ];
4479+
4480+ /**
4481+ * Filters the array of personal data eraser callbacks.
4482+ *
4483+ * @since 4.9.6
4484+ *
4485+ * @param array $args {
4486+ * An array of callable erasers of personal data. Default empty array.
4487+ * [
4488+ * callback string Callable eraser that accepts an email address and
4489+ * a page and returns an array with the number of items
4490+ * removed, the number of items retained and any messages
4491+ * from the eraser, as well as if additional pages are
4492+ * available.
4493+ * eraser_friendly_name string Translated user facing friendly name for the eraser.
4494+ * ]
4495+ * }
4496+ */
4497+ $ erasers = apply_filters ( 'wp_privacy_personal_data_erasers ' , array () );
4498+
4499+ // Do we have any registered erasers?
4500+ if ( 0 < count ( $ erasers ) ) {
4501+ if ( $ eraser_index < 1 ) {
4502+ wp_send_json_error ( __ ( 'Error: Eraser index cannot be less than one. ' ) );
4503+ }
4504+
4505+ if ( $ eraser_index > count ( $ erasers ) ) {
4506+ wp_send_json_error ( __ ( 'Error: Eraser index is out of range. ' ) );
4507+ }
4508+
4509+ if ( $ page < 1 ) {
4510+ wp_send_json_error ( __ ( 'Error: Page index cannot be less than one. ' ) );
4511+ }
4512+
4513+ $ index = $ eraser_index - 1 ; // Convert to zero based for eraser index
4514+ $ eraser = $ erasers [ $ index ];
4515+ if ( ! is_array ( $ eraser ) ) {
4516+ wp_send_json_error (
4517+ sprintf (
4518+ __ ( 'Error: Expected an array describing the eraser at index %d. ' ),
4519+ $ eraser_index
4520+ )
4521+ );
4522+ }
4523+ if ( ! array_key_exists ( 'callback ' , $ eraser ) ) {
4524+ wp_send_json_error (
4525+ sprintf (
4526+ __ ( 'Error: Eraser array at index %d does not include a callback. ' ),
4527+ $ eraser_index
4528+ )
4529+ );
4530+ }
4531+ if ( ! is_callable ( $ eraser ['callback ' ] ) ) {
4532+ wp_send_json_error (
4533+ sprintf (
4534+ __ ( 'Error: Eraser callback at index %d is not a valid callback. ' ),
4535+ $ eraser_index
4536+ )
4537+ );
4538+ }
4539+ if ( ! array_key_exists ( 'eraser_friendly_name ' , $ eraser ) ) {
4540+ wp_send_json_error (
4541+ sprintf (
4542+ __ ( 'Error: Eraser array at index %d does not include a friendly name. ' ),
4543+ $ eraser_index
4544+ )
4545+ );
4546+ }
4547+
4548+ $ callback = $ erasers [ $ index ]['callback ' ];
4549+ $ eraser_friendly_name = $ erasers [ $ index ]['eraser_friendly_name ' ];
4550+
4551+ $ response = call_user_func ( $ callback , $ email_address , $ page );
4552+ if ( is_wp_error ( $ response ) ) {
4553+ wp_send_json_error ( $ response );
4554+ }
4555+
4556+ if ( ! is_array ( $ response ) ) {
4557+ wp_send_json_error (
4558+ sprintf (
4559+ __ ( 'Error: Did not receive array from %s eraser (index %d). ' ),
4560+ $ eraser_friendly_name ,
4561+ $ eraser_index
4562+ )
4563+ );
4564+ }
4565+ if ( ! array_key_exists ( 'num_items_removed ' , $ response ) ) {
4566+ wp_send_json_error (
4567+ sprintf (
4568+ __ ( 'Error: Expected num_items_removed key in response array from %s eraser (index %d). ' ),
4569+ $ eraser_friendly_name ,
4570+ $ eraser_index
4571+ )
4572+ );
4573+ }
4574+ if ( ! array_key_exists ( 'num_items_retained ' , $ response ) ) {
4575+ wp_send_json_error (
4576+ sprintf (
4577+ __ ( 'Error: Expected num_items_retained key in response array from %s eraser (index %d). ' ),
4578+ $ eraser_friendly_name ,
4579+ $ eraser_index
4580+ )
4581+ );
4582+ }
4583+ if ( ! array_key_exists ( 'messages ' , $ response ) ) {
4584+ wp_send_json_error (
4585+ sprintf (
4586+ __ ( 'Error: Expected messages key in response array from %s eraser (index %d). ' ),
4587+ $ eraser_friendly_name ,
4588+ $ eraser_index
4589+ )
4590+ );
4591+ }
4592+ if ( ! is_array ( $ response ['messages ' ] ) ) {
4593+ wp_send_json_error (
4594+ sprintf (
4595+ __ ( 'Error: Expected messages key to reference an array in response array from %s eraser (index %d). ' ),
4596+ $ eraser_friendly_name ,
4597+ $ eraser_index
4598+ )
4599+ );
4600+ }
4601+ if ( ! array_key_exists ( 'done ' , $ response ) ) {
4602+ wp_send_json_error (
4603+ sprintf (
4604+ __ ( 'Error: Expected done flag in response array from %s eraser (index %d). ' ),
4605+ $ eraser_friendly_name ,
4606+ $ eraser_index
4607+ )
4608+ );
4609+ }
4610+ } else {
4611+ // No erasers, so we're done
4612+ $ response = array (
4613+ 'num_items_removed ' => 0 ,
4614+ 'num_items_retained ' => 0 ,
4615+ 'messages ' => array (),
4616+ 'done ' => true ,
4617+ );
4618+ }
4619+
4620+ /**
4621+ * Filters a page of personal data eraser data.
4622+ *
4623+ * Allows the erasure response to be consumed by destinations in addition to Ajax.
4624+ *
4625+ * @since 4.9.6
4626+ *
4627+ * @param array $response The personal data for the given exporter and page.
4628+ * @param int $exporter_index The index of the exporter that provided this data.
4629+ * @param string $email_address The email address associated with this personal data.
4630+ * @param int $page The zero-based page for this response.
4631+ * @param int $request_id The privacy request post ID associated with this request.
4632+ */
4633+ $ response = apply_filters ( 'wp_privacy_personal_data_erasure_page ' , $ response , $ eraser_index , $ email_address , $ page , $ request_id );
4634+ if ( is_wp_error ( $ response ) ) {
4635+ wp_send_json_error ( $ response );
4636+ }
4637+
4638+ wp_send_json_success ( $ response );
4639+ }
0 commit comments