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;
}