Skip to content

Commit cdb7416

Browse files
committed
Export CSV
1 parent 1257a70 commit cdb7416

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

assets/vue/components/subscribers/SubscriberDirectory.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
</button>
3232
<button
3333
class="flex-[3] sm:flex-none px-4 py-2 bg-ext-wf1 hover:bg-ext-wf3 text-white text-sm font-medium rounded-lg flex items-center justify-center gap-2 transition-colors"
34+
@click="exportSubscribers"
3435
>
3536
<BaseIcon name="download" class="w-4 h-4" />
3637
<span class="flex items-center whitespace-nowrap">Export CSV</span>
@@ -203,4 +204,12 @@ const handleFilterChange = (filterId) => {
203204
currentFilter.value = filterId || 'all'
204205
fetchSubscribers()
205206
}
207+
208+
const exportSubscribers = () => {
209+
const url = new URL('/subscribers/export', window.location.origin)
210+
if (currentFilter.value && currentFilter.value !== 'all') {
211+
url.searchParams.set(currentFilter.value, 'true')
212+
}
213+
window.location.href = url.toString()
214+
}
206215
</script>

src/Controller/SubscribersController.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,58 @@ public function index(Request $request): JsonResponse|Response
8585

8686
return $this->json($initialData);
8787
}
88+
89+
#[Route('/subscribers/export', name: 'subscribers_export', methods: 'GET')]
90+
public function export(Request $request): Response
91+
{
92+
$filter = new SubscribersFilterRequest(
93+
isConfirmed: $request->query->has('confirmed') ? true :
94+
($request->query->has('unconfirmed') ? false : null),
95+
isBlacklisted: $request->query->has('blacklisted') ? true :
96+
($request->query->has('non-blacklisted') ? false : null),
97+
sortBy: $request->query->get('sortBy'),
98+
sortDirection: $request->query->get('sortDirection'),
99+
findColumn: $request->query->get('findColumn'),
100+
findValue: $request->query->get('findValue'),
101+
);
102+
$collection = $this->subscribersClient->getSubscribers($filter, 0);
103+
$exportData = $collection->items;
104+
if (empty($exportData)) {
105+
return new Response('No subscribers to export.', Response::HTTP_NOT_FOUND);
106+
}
107+
$handle = fopen('php://temp', 'r+');
108+
109+
$headers = array_keys((array) $exportData[0]);
110+
fputcsv($handle, $headers);
111+
112+
foreach ($exportData as $data) {
113+
$row = [
114+
'id' => $data->id,
115+
'email' => $data->email,
116+
'createdAt' => (new DateTimeImmutable($data->createdAt))->format('Y-m-d H:i:s'),
117+
'confirmed' => $data->confirmed,
118+
'blacklisted' => $data->blacklisted,
119+
'bounceCount' => $data->bounceCount,
120+
'uniqueId' => $data->uniqueId,
121+
'htmlEmail' => $data->htmlEmail,
122+
'disabled' => $data->disabled,
123+
'lists' => implode('|', array_map(fn($list) => $list['name'], $data->subscribedLists)),
124+
];
125+
126+
fputcsv($handle, $row);
127+
}
128+
129+
rewind($handle);
130+
$csvContent = stream_get_contents($handle);
131+
fclose($handle);
132+
133+
$response = new Response($csvContent);
134+
$response->headers->set('Content-Type', 'text/csv');
135+
$response->headers->set(
136+
'Content-Disposition',
137+
'attachment; filename="subscribers_export_' . date('Y-m-d_H-i-s') . '.csv"'
138+
);
139+
140+
return $response;
141+
}
88142
}

0 commit comments

Comments
 (0)