getMessage(), $e->status, $e->errorCode); } $clientId = (int)$tenant['client_id']; if (empty($_FILES['audio']) || $_FILES['audio']['error'] !== UPLOAD_ERR_OK) { $code = $_FILES['audio']['error'] ?? -1; $msgs = [ UPLOAD_ERR_INI_SIZE => 'File exceeds server upload limit.', UPLOAD_ERR_FORM_SIZE => 'File exceeds form size limit.', UPLOAD_ERR_PARTIAL => 'File was only partially uploaded.', UPLOAD_ERR_NO_FILE => 'No audio file received.', ]; dbnToolsError($msgs[$code] ?? "Upload error (code {$code}).", 400, 'upload_error'); } $file = $_FILES['audio']; $maxBytes = 200 * 1024 * 1024; if ($file['size'] > $maxBytes) { dbnToolsError('File too large. Maximum 200 MB.', 413, 'file_too_large'); } $allowedExts = ['mp3', 'wav', 'ogg', 'oga', 'm4a', 'mp4', 'flac', 'webm', 'aac']; $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($ext, $allowedExts, true)) { dbnToolsError("Unsupported format: .{$ext}. Use MP3, WAV, OGG, M4A, FLAC, or WebM.", 415, 'unsupported_format'); } // Resolve storage directory $storageRoot = dbnToolsEnv('AUDIO_STORAGE_ROOT', '/home/dobetternorge/audio-uploads'); $clientDir = rtrim($storageRoot, '/') . '/' . $clientId; if (!is_dir($clientDir) && !mkdir($clientDir, 0750, true)) { dbnToolsError('Could not create storage directory.', 500, 'storage_error'); } $uniqueId = bin2hex(random_bytes(12)); $storagePath = $clientDir . '/' . $uniqueId . '.' . $ext; if (!move_uploaded_file($file['tmp_name'], $storagePath)) { dbnToolsError('Failed to store uploaded file.', 500, 'move_error'); } $title = pathinfo($file['name'], PATHINFO_FILENAME); $title = preg_replace('/[_\-]+/', ' ', $title); $title = mb_substr(trim($title), 0, 200) ?: 'Audio ' . date('Y-m-d'); $db = dbnToolsDb(); $db->prepare( 'INSERT INTO client_documents (client_id, title, source_type, audio_storage_path, status, file_size_bytes, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())' )->execute([$clientId, $title, 'audio', $storagePath, 'ready', (int)$file['size']]); $docId = (int)$db->lastInsertId(); dbnToolsRespond([ 'ok' => true, 'document' => [ 'id' => $docId, 'title' => $title, 'file_size_bytes' => (int)$file['size'], 'audio_storage_path' => $storagePath, 'source_type' => 'audio', ], ]);