';
/* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- paginate_links() is a core function returning its own escaped markup; base comes from add_query_arg() and current/total are ints. */
echo paginate_links([
'base' => add_query_arg('paged', '%#%'),
'format' => '',
'current' => $paged,
'total' => $pages,
]);
echo '
';
}
?>
!Fields::is_silent($f)));
$title = sanitize_file_name(get_the_title($form_id) ?: 'form-' . $form_id);
nocache_headers();
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $title . '-' . gmdate('Ymd') . '.csv"');
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- php://output is the HTTP response stream, not the file system, and WP_Filesystem cannot write to it.
$out = fopen('php://output', 'w');
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- As above: this writes to the response stream. The bytes are a UTF-8 BOM, without which Excel misreads a UTF-8 CSV.
fwrite($out, "\xEF\xBB\xBF");
$head = [__('Time', 'aumframe')];
foreach ($cols as $c) {
$head[] = $c['label'] ?: $c['id'];
}
$head[] = __('Source page', 'aumframe');
$head[] = __('Source URL', 'aumframe');
fputcsv($out, $head);
// Fetched in batches rather than reading tens of thousands of enquiries into memory at once
$offset = 0;
while (true) {
$rows = Inbox::query($form_id, 500, $offset);
if (!$rows) {
break;
}
foreach ($rows as $e) {
$data = json_decode((string) $e['data'], true) ?: [];
$line = [mysql2date('Y-m-d H:i', $e['created_at'])];
foreach ($cols as $c) {
$line[] = Fields::display_value($c, $data[$c['id']] ?? '');
}
$line[] = $e['source_id'] ? (get_the_title((int) $e['source_id']) ?: '') : '';
$line[] = $e['source_url'];
fputcsv($out, $line);
}
$offset += 500;
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- As above: this closes the php://output response stream.
fclose($out);
exit;
}
}