$params */ public function upload(Request $request, array $params): Response { $agentId = (int) $params['id']; if ($this->agents->findById($agentId) === null) { return Response::error('Unbekannter Agent: ' . $agentId, 404); } $file = $request->files['audio'] ?? null; if (!is_array($file) || !isset($file['tmp_name'], $file['error'])) { return Response::error('Feld "audio" (Datei) ist erforderlich.', 422); } $error = (int) $file['error']; if ($error === UPLOAD_ERR_INI_SIZE || $error === UPLOAD_ERR_FORM_SIZE) { return Response::error('Datei zu gross.', 413); } if ($error !== UPLOAD_ERR_OK) { return Response::error('Datei-Upload fehlgeschlagen.', 422); } $contents = @file_get_contents((string) $file['tmp_name']); if ($contents === false) { return Response::error('Datei-Upload fehlgeschlagen.', 422); } try { $recording = $this->recordings->store($agentId, $contents, (string) ($file['type'] ?? '')); } catch (InvalidArgumentException $e) { return Response::error($e->getMessage(), 422); } return Response::json(['recording' => $recording], 201); } /** * @param array $params * @param array $authenticatedAgent */ public function index(Request $request, array $params, array $authenticatedAgent): Response { if ((int) $params['id'] !== (int) $authenticatedAgent['id']) { return Response::error('Ein Agent darf nur seine eigene Warteschlange abfragen.', 403); } $status = isset($request->query['status']) ? (string) $request->query['status'] : null; try { $recordings = $this->recordings->listForAgent((int) $params['id'], $status); } catch (InvalidArgumentException $e) { return Response::error($e->getMessage(), 400); } return Response::json(['recordings' => $recordings]); } /** * @param array $params * @param array $authenticatedAgent */ public function download(Request $request, array $params, array $authenticatedAgent): Response { $recording = $this->recordings->findById((int) $params['id']); if ($recording === null) { return Response::error('Aufnahme nicht gefunden.', 404); } if ((int) $recording['agent_id'] !== (int) $authenticatedAgent['id']) { return Response::error('Diese Aufnahme gehoert einem anderen Agenten.', 403); } $bytes = $this->recordings->readAudio((int) $recording['id']); if ($bytes === null) { return Response::error('Audiodatei nicht gefunden.', 404); } return Response::binary($bytes, $recording['mime_type'], 200, [ 'Content-Disposition' => 'attachment; filename="recording-' . $recording['id'] . '"', ]); } /** * @param array $params * @param array $authenticatedAgent */ public function markProcessed(Request $request, array $params, array $authenticatedAgent): Response { $recording = $this->recordings->findById((int) $params['id']); if ($recording === null) { return Response::error('Aufnahme nicht gefunden.', 404); } if ((int) $recording['agent_id'] !== (int) $authenticatedAgent['id']) { return Response::error('Diese Aufnahme gehoert einem anderen Agenten.', 403); } $status = (string) ($request->body['status'] ?? ''); if ($status !== 'done') { return Response::error('Feld "status" muss "done" sein.', 422); } $updated = $this->recordings->markDone((int) $recording['id']); return Response::json(['recording' => $updated]); } }