user(); abort_unless($user, 403); $hasRecentExport = $user->dataExports() ->whereIn('status', [DataExport::STATUS_PENDING, DataExport::STATUS_PROCESSING]) ->exists(); if ($hasRecentExport) { return back()->with('error', __('profile.export.messages.in_progress')); } $recentReadyExport = $user->dataExports() ->where('status', DataExport::STATUS_READY) ->where('created_at', '>=', now()->subDay()) ->exists(); if ($recentReadyExport) { return back()->with('error', __('profile.export.messages.recent_ready')); } $export = $user->dataExports()->create([ 'tenant_id' => $user->tenant_id, 'status' => DataExport::STATUS_PENDING, ]); GenerateDataExport::dispatch($export->id); return back()->with('status', __('profile.export.messages.started')); } public function download(Request $request, DataExport $export) { $user = $request->user(); abort_unless($user && $export->user_id === $user->id, 403); if (! $export->isReady() || $export->hasExpired() || ! $export->path) { return back()->with('error', __('profile.export.messages.not_available')); } return Storage::disk('local')->download($export->path, sprintf('fotospiel-data-export-%s.zip', $export->created_at?->format('Ymd') ?? now()->format('Ymd'))); } }