authorize('view', $website); [$from, $to] = $this->parseDateRange($request); $service = AnalyticsQueryService::for($website, $from, $to); [$headers, $rows] = match ($report) { 'pages' => $this->pagesExport($service), 'landing-pages' => $this->landingPagesExport($service), 'exit-pages' => $this->exitPagesExport($service), 'sources' => $this->sourcesExport($service), 'referrers' => $this->referrersExport($service), 'campaigns' => $this->campaignsExport($service), 'events' => $this->eventsExport($service), 'countries' => $this->countriesExport($service), 'browsers' => $this->browsersExport($service), 'languages' => $this->languagesExport($service), 'summary' => $this->summaryExport($service, $from, $to), default => abort(404, 'Unknown report type.'), }; $filename = "{$website->domain}_{$report}_{$from->format('Y-m-d')}_to_{$to->format('Y-m-d')}.csv"; return $this->streamCsv($filename, $headers, $rows); } private function streamCsv(string $filename, array $headers, iterable $rows): StreamedResponse { return response()->streamDownload(function () use ($headers, $rows) { $handle = fopen('php://output', 'w'); fputcsv($handle, $headers); foreach ($rows as $row) { fputcsv($handle, $row); } fclose($handle); }, $filename, [ 'Content-Type' => 'text/csv', ]); } private function pagesExport(AnalyticsQueryService $service): array { $data = $service->topPages(500); return [ ['Path', 'Views', 'Unique Views', 'Avg Time on Page (s)'], $data->map(fn ($r) => [ $r->path, $r->views, $r->unique_views, round($r->avg_time ?? 0, 1), ]), ]; } private function landingPagesExport(AnalyticsQueryService $service): array { $data = $service->landingPages(500); return [ ['Path', 'Entrances', 'Bounce Rate (%)'], $data->map(fn ($r) => [ $r->entry_page ?? $r->path ?? '—', $r->entrances ?? $r->sessions ?? 0, $r->bounce_rate ?? 0, ]), ]; } private function exitPagesExport(AnalyticsQueryService $service): array { $data = $service->exitPages(500); return [ ['Path', 'Exits'], $data->map(fn ($r) => [ $r->exit_page ?? $r->path ?? '—', $r->exits ?? 0, ]), ]; } private function sourcesExport(AnalyticsQueryService $service): array { $data = $service->trafficSources(500); return [ ['Source', 'Sessions', 'Bounces', 'Avg Duration (s)', 'Avg Pages'], $data->map(fn ($r) => [ $r->source, $r->sessions, $r->bounces, round($r->avg_duration ?? 0, 1), round($r->avg_pages ?? 0, 1), ]), ]; } private function referrersExport(AnalyticsQueryService $service): array { $data = $service->referrers(500); return [ ['Referrer Domain', 'Sessions', 'Bounces', 'Avg Duration (s)'], $data->map(fn ($r) => [ $r->referrer_domain, $r->sessions, $r->bounces, round($r->avg_duration ?? 0, 1), ]), ]; } private function campaignsExport(AnalyticsQueryService $service): array { $data = $service->campaigns(500); return [ ['UTM Source', 'UTM Medium', 'UTM Campaign', 'Sessions', 'Bounces', 'Avg Duration (s)'], $data->map(fn ($r) => [ $r->utm_source, $r->utm_medium, $r->utm_campaign, $r->sessions, $r->bounces, round($r->avg_duration ?? 0, 1), ]), ]; } private function eventsExport(AnalyticsQueryService $service): array { $data = $service->eventsOverview(500); return [ ['Event Name', 'Category', 'Total', 'Unique Visitors', 'Total Value'], $data->map(fn ($r) => [ $r->name, $r->category, $r->total, $r->unique_visitors, $r->total_value, ]), ]; } private function countriesExport(AnalyticsQueryService $service): array { $data = $service->visitorsByCountry(500); return [ ['Country', 'Visitors'], $data->map(fn ($r) => [$r->country, $r->visitors]), ]; } private function browsersExport(AnalyticsQueryService $service): array { $data = $service->visitorsByBrowser(100); return [ ['Browser', 'Visitors'], $data->map(fn ($r) => [$r->browser, $r->visitors]), ]; } private function languagesExport(AnalyticsQueryService $service): array { $data = $service->visitorsByLanguage(100); return [ ['Language', 'Visitors'], $data->map(fn ($r) => [$r->language, $r->visitors]), ]; } private function summaryExport(AnalyticsQueryService $service, $from, $to): array { $summary = $service->summary(); return [ ['Metric', 'Value'], collect([ ['Period', $from->format('Y-m-d') . ' to ' . $to->format('Y-m-d')], ['Page Views', $summary['page_views']], ['Unique Visitors', $summary['visitors']], ['Sessions', $summary['sessions']], ['Bounce Rate (%)', $summary['bounce_rate']], ['Avg Duration (s)', $summary['avg_duration']], ['Pages / Session', $summary['avg_pages']], ]), ]; } }