schneespur/app/Services/DriverExportService.php
Michael 2c63440ed8 Revert: move code back to project root from schneespur/ subdirectory
- Reverts the schneespur/ subdirectory restructure (b8e426b)
- Restores package.json and vite.config.js (needed for npm build, were
  removed in an earlier cleanup before the restructure)
- Updates public/build/ assets with current Vite output (new content hashes)
2026-05-17 18:24:26 +00:00

99 lines
3 KiB
PHP

<?php
namespace App\Services;
use App\Models\User;
use RuntimeException;
use ZipArchive;
class DriverExportService
{
public function exportSingle(User $driver): string
{
$this->ensureZipAvailable();
$path = tempnam(sys_get_temp_dir(), 'schneespur-export-');
$zip = new ZipArchive();
if ($zip->open($path, ZipArchive::OVERWRITE) !== true) {
throw new RuntimeException('Could not create ZIP archive');
}
$this->addDriverFiles($zip, $driver, '');
$zip->close();
return $path;
}
public function exportAll(): string
{
$this->ensureZipAvailable();
$path = tempnam(sys_get_temp_dir(), 'schneespur-export-');
$zip = new ZipArchive();
if ($zip->open($path, ZipArchive::OVERWRITE) !== true) {
throw new RuntimeException('Could not create ZIP archive');
}
$drivers = User::drivers()->with('dsgvoConfirmations')->orderBy('name')->get();
foreach ($drivers as $driver) {
$this->addDriverFiles($zip, $driver, "fahrer-{$driver->id}/");
}
$zip->close();
return $path;
}
private function addDriverFiles(ZipArchive $zip, User $driver, string $prefix): void
{
$zip->addFromString($prefix.'profile.json', json_encode([
'id' => $driver->id,
'name' => $driver->name,
'email' => $driver->email,
'phone' => $driver->phone,
'notes' => $driver->notes,
'created_at' => $driver->created_at?->toIso8601String(),
'dsgvo_informed_at' => $driver->dsgvo_informed_at?->toIso8601String(),
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$zip->addFromString($prefix.'dsgvo_confirmations.csv', $this->buildConfirmationsCsv($driver));
$zip->addFromString($prefix.'jobs.csv', "id,start,end,customer,notes\n");
$zip->addFromString($prefix.'workshifts.csv', "id,start,end,driver\n");
$zip->addFromString($prefix.'locations.csv', "id,lat,lon,timestamp\n");
$zip->addEmptyDir($prefix.'photos');
}
private function buildConfirmationsCsv(User $driver): string
{
$stream = fopen('php://temp', 'r+');
fputcsv($stream, ['confirmed_at', 'template_version', 'signed_by', 'ip_address', 'user_agent']);
foreach ($driver->dsgvoConfirmations()->orderBy('confirmed_at')->get() as $confirmation) {
fputcsv($stream, [
$confirmation->confirmed_at?->toIso8601String(),
$confirmation->template_version,
$confirmation->signed_by,
$confirmation->ip_address,
$confirmation->user_agent,
]);
}
rewind($stream);
$csv = stream_get_contents($stream);
fclose($stream);
return $csv;
}
private function ensureZipAvailable(): void
{
if (! class_exists(ZipArchive::class)) {
throw new RuntimeException('PHP zip extension is required for data export');
}
}
}