wp_privacy_process_personal_data_export_page

The timeline below displays how wordpress function wp_privacy_process_personal_data_export_page has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 5.7

/**
 * Intercept personal data exporter page Ajax responses in order to assemble the personal data export file.
 *
 * @since 4.9.6
 *
 * @see 'wp_privacy_personal_data_export_page'
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default Ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request.
    $request = wp_get_user_request($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging personal data to export.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $accumulated_data = get_post_meta($request_id, '_export_data_raw', true);
        if ($accumulated_data) {
            $export_data = $accumulated_data;
        }
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = count($exporters) === $exporter_index;
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        $group_description = '';
        if (!empty($export_datum['group_description'])) {
            $group_description = $export_datum['group_description'];
        }
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'group_description' => $group_description, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $exports_url = wp_privacy_exports_url();
        $export_file_name = get_post_meta($request_id, '_export_file_name', true);
        $export_file_url = $exports_url . $export_file_name;
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 5.6

/**
 * Intercept personal data exporter page Ajax responses in order to assemble the personal data export file.
 *
 * @since 4.9.6
 *
 * @see 'wp_privacy_personal_data_export_page'
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default Ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request.
    $request = wp_get_user_request($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging user privacy exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $accumulated_data = get_post_meta($request_id, '_export_data_raw', true);
        if ($accumulated_data) {
            $export_data = $accumulated_data;
        }
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = count($exporters) === $exporter_index;
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        $group_description = '';
        if (!empty($export_datum['group_description'])) {
            $group_description = $export_datum['group_description'];
        }
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'group_description' => $group_description, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $exports_url = wp_privacy_exports_url();
        $export_file_name = get_post_meta($request_id, '_export_file_name', true);
        $export_file_url = $exports_url . $export_file_name;
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 5.5

/**
 * Intercept personal data exporter page Ajax responses in order to assemble the personal data export file.
 *
 * @since 4.9.6
 *
 * @see 'wp_privacy_personal_data_export_page'
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default Ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request.
    $request = wp_get_user_request($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = count($exporters) === $exporter_index;
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        $group_description = '';
        if (!empty($export_datum['group_description'])) {
            $group_description = $export_datum['group_description'];
        }
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'group_description' => $group_description, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $exports_url = wp_privacy_exports_url();
        $export_file_name = get_post_meta($request_id, '_export_file_name', true);
        $export_file_url = $exports_url . $export_file_name;
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 5.4

/**
 * Intercept personal data exporter page Ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default Ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request.
    $request = wp_get_user_request($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = count($exporters) === $exporter_index;
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        $group_description = '';
        if (!empty($export_datum['group_description'])) {
            $group_description = $export_datum['group_description'];
        }
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'group_description' => $group_description, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 5.3

/**
 * Intercept personal data exporter page Ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default Ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request data.
    $request = wp_get_user_request_data($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = $exporter_index === count($exporters);
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        $group_description = '';
        if (!empty($export_datum['group_description'])) {
            $group_description = $export_datum['group_description'];
        }
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'group_description' => $group_description, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 5.2

/**
 * Intercept personal data exporter page ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request data.
    $request = wp_get_user_request_data($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = $exporter_index === count($exporters);
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
        // Update the request to completed state when the export email is sent.
        _wp_privacy_completed_request($request_id);
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    return $response;
}

WordPress Version: 9.7

/**
 * Intercept personal data exporter page ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request data.
    $request = wp_get_user_request_data($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = $exporter_index === count($exporters);
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    // Update the request to completed state.
    _wp_privacy_completed_request($request_id);
    return $response;
}

WordPress Version: 9.6

/**
 * Intercept personal data exporter page ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request data.
    $request = wp_get_user_request_data($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = $exporter_index === count($exporters);
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    // Generate the export file from the collected, grouped personal data.
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    // Update the request to completed state.
    _wp_privacy_completed_request($request_id);
    return $response;
}

WordPress Version: .10

/**
 * Intercept personal data exporter page ajax responses in order to assemble the personal data export file.
 * @see wp_privacy_personal_data_export_page
 * @since 4.9.6
 *
 * @param array  $response        The response from the personal data exporter for the given page.
 * @param int    $exporter_index  The index of the personal data exporter. Begins at 1.
 * @param string $email_address   The email address of the user whose personal data this is.
 * @param int    $page            The page of personal data for this exporter. Begins at 1.
 * @param int    $request_id      The request ID for this personal data export.
 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
 * @param string $exporter_key    The slug (key) of the exporter.
 * @return array The filtered response.
 */
function wp_privacy_process_personal_data_export_page($response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key)
{
    /* Do some simple checks on the shape of the response from the exporter.
     * If the exporter response is malformed, don't attempt to consume it - let it
     * pass through to generate a warning to the user by default ajax processing.
     */
    if (!is_array($response)) {
        return $response;
    }
    if (!array_key_exists('done', $response)) {
        return $response;
    }
    if (!array_key_exists('data', $response)) {
        return $response;
    }
    if (!is_array($response['data'])) {
        return $response;
    }
    // Get the request data.
    $request = wp_get_user_request_data($request_id);
    if (!$request || 'export_personal_data' !== $request->action_name) {
        wp_send_json_error(__('Invalid request ID when merging exporter data.'));
    }
    $export_data = array();
    // First exporter, first page? Reset the report data accumulation array.
    if (1 === $exporter_index && 1 === $page) {
        update_post_meta($request_id, '_export_data_raw', $export_data);
    } else {
        $export_data = get_post_meta($request_id, '_export_data_raw', true);
    }
    // Now, merge the data from the exporter response into the data we have accumulated already.
    $export_data = array_merge($export_data, $response['data']);
    update_post_meta($request_id, '_export_data_raw', $export_data);
    // If we are not yet on the last page of the last exporter, return now.
    /** This filter is documented in wp-admin/includes/ajax-actions.php */
    $exporters = apply_filters('wp_privacy_personal_data_exporters', array());
    $is_last_exporter = $exporter_index === count($exporters);
    $exporter_done = $response['done'];
    if (!$is_last_exporter || !$exporter_done) {
        return $response;
    }
    // Last exporter, last page - let's prepare the export file.
    // First we need to re-organize the raw data hierarchically in groups and items.
    $groups = array();
    foreach ((array) $export_data as $export_datum) {
        $group_id = $export_datum['group_id'];
        $group_label = $export_datum['group_label'];
        if (!array_key_exists($group_id, $groups)) {
            $groups[$group_id] = array('group_label' => $group_label, 'items' => array());
        }
        $item_id = $export_datum['item_id'];
        if (!array_key_exists($item_id, $groups[$group_id]['items'])) {
            $groups[$group_id]['items'][$item_id] = array();
        }
        $old_item_data = $groups[$group_id]['items'][$item_id];
        $merged_item_data = array_merge($export_datum['data'], $old_item_data);
        $groups[$group_id]['items'][$item_id] = $merged_item_data;
    }
    // Then save the grouped data into the request.
    delete_post_meta($request_id, '_export_data_raw');
    update_post_meta($request_id, '_export_data_grouped', $groups);
    /**
     * Generate the export file from the collected, grouped personal data.
     *
     * @since 4.9.6
     *
     * @param int $request_id The export request ID.
     */
    do_action('wp_privacy_personal_data_export_file', $request_id);
    // Clear the grouped data now that it is no longer needed.
    delete_post_meta($request_id, '_export_data_grouped');
    // If the destination is email, send it now.
    if ($send_as_email) {
        $mail_success = wp_privacy_send_personal_data_export_email($request_id);
        if (is_wp_error($mail_success)) {
            wp_send_json_error($mail_success->get_error_message());
        }
    } else {
        // Modify the response to include the URL of the export file so the browser can fetch it.
        $export_file_url = get_post_meta($request_id, '_export_file_url', true);
        if (!empty($export_file_url)) {
            $response['url'] = $export_file_url;
        }
    }
    // Update the request to completed state.
    _wp_privacy_completed_request($request_id);
    return $response;
}