WordPress Version: 6.4
/**
* Handles erasing personal data via AJAX.
*
* @since 4.9.6
*/
function wp_ajax_wp_privacy_erase_personal_data()
{
if (empty($_POST['id'])) {
wp_send_json_error(__('Missing request ID.'));
}
$request_id = (int) $_POST['id'];
if ($request_id < 1) {
wp_send_json_error(__('Invalid request ID.'));
}
// Both capabilities are required to avoid confusion, see `_wp_personal_data_removal_page()`.
if (!current_user_can('erase_others_personal_data') || !current_user_can('delete_users')) {
wp_send_json_error(__('Sorry, you are not allowed to perform this action.'));
}
check_ajax_referer('wp-privacy-erase-personal-data-' . $request_id, 'security');
// Get the request.
$request = wp_get_user_request($request_id);
if (!$request || 'remove_personal_data' !== $request->action_name) {
wp_send_json_error(__('Invalid request type.'));
}
$email_address = $request->email;
if (!is_email($email_address)) {
wp_send_json_error(__('Invalid email address in request.'));
}
if (!isset($_POST['eraser'])) {
wp_send_json_error(__('Missing eraser index.'));
}
$eraser_index = (int) $_POST['eraser'];
if (!isset($_POST['page'])) {
wp_send_json_error(__('Missing page index.'));
}
$page = (int) $_POST['page'];
/**
* Filters the array of personal data eraser callbacks.
*
* @since 4.9.6
*
* @param array $args {
* An array of callable erasers of personal data. Default empty array.
*
* @type array ...$0 {
* Array of personal data exporters.
*
* @type callable $callback Callable eraser that accepts an email address and a page
* number, and returns an array with boolean values for
* whether items were removed or retained and any messages
* from the eraser, as well as if additional pages are
* available.
* @type string $exporter_friendly_name Translated user facing friendly name for the eraser.
* }
* }
*/
$erasers = apply_filters('wp_privacy_personal_data_erasers', array());
// Do we have any registered erasers?
if (0 < count($erasers)) {
if ($eraser_index < 1) {
wp_send_json_error(__('Eraser index cannot be less than one.'));
}
if ($eraser_index > count($erasers)) {
wp_send_json_error(__('Eraser index is out of range.'));
}
if ($page < 1) {
wp_send_json_error(__('Page index cannot be less than one.'));
}
$eraser_keys = array_keys($erasers);
$eraser_key = $eraser_keys[$eraser_index - 1];
$eraser = $erasers[$eraser_key];
if (!is_array($eraser)) {
/* translators: %d: Eraser array index. */
wp_send_json_error(sprintf(__('Expected an array describing the eraser at index %d.'), $eraser_index));
}
if (!array_key_exists('eraser_friendly_name', $eraser)) {
/* translators: %d: Eraser array index. */
wp_send_json_error(sprintf(__('Eraser array at index %d does not include a friendly name.'), $eraser_index));
}
$eraser_friendly_name = $eraser['eraser_friendly_name'];
if (!array_key_exists('callback', $eraser)) {
wp_send_json_error(sprintf(
/* translators: %s: Eraser friendly name. */
__('Eraser does not include a callback: %s.'),
esc_html($eraser_friendly_name)
));
}
if (!is_callable($eraser['callback'])) {
wp_send_json_error(sprintf(
/* translators: %s: Eraser friendly name. */
__('Eraser callback is not valid: %s.'),
esc_html($eraser_friendly_name)
));
}
$callback = $eraser['callback'];
$response = call_user_func($callback, $email_address, $page);
if (is_wp_error($response)) {
wp_send_json_error($response);
}
if (!is_array($response)) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Did not receive array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
if (!array_key_exists('items_removed', $response)) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Expected items_removed key in response array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
if (!array_key_exists('items_retained', $response)) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Expected items_retained key in response array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
if (!array_key_exists('messages', $response)) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Expected messages key in response array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
if (!is_array($response['messages'])) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Expected messages key to reference an array in response array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
if (!array_key_exists('done', $response)) {
wp_send_json_error(sprintf(
/* translators: 1: Eraser friendly name, 2: Eraser array index. */
__('Expected done flag in response array from %1$s eraser (index %2$d).'),
esc_html($eraser_friendly_name),
$eraser_index
));
}
} else {
// No erasers, so we're done.
$eraser_key = '';
$response = array('items_removed' => false, 'items_retained' => false, 'messages' => array(), 'done' => true);
}
/**
* Filters a page of personal data eraser data.
*
* Allows the erasure response to be consumed by destinations in addition to Ajax.
*
* @since 4.9.6
*
* @param array $response {
* The personal data for the given exporter and page number.
*
* @type bool $items_removed Whether items were actually removed or not.
* @type bool $items_retained Whether items were retained or not.
* @type string[] $messages An array of messages to add to the personal data export file.
* @type bool $done Whether the eraser is finished or not.
* }
* @param int $eraser_index The index of the eraser that provided this data.
* @param string $email_address The email address associated with this personal data.
* @param int $page The page number for this response.
* @param int $request_id The privacy request post ID associated with this request.
* @param string $eraser_key The key (slug) of the eraser that provided this data.
*/
$response = apply_filters('wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id, $eraser_key);
if (is_wp_error($response)) {
wp_send_json_error($response);
}
wp_send_json_success($response);
}