Spaces:
Build error
Build error
| header('Content-Type: application/json'); | |
| header('Access-Control-Allow-Origin: *'); | |
| header('Access-Control-Allow-Methods: POST, OPTIONS'); | |
| header('Access-Control-Allow-Headers: Content-Type'); | |
| if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { | |
| http_response_code(204); | |
| exit; | |
| } | |
| if ($_SERVER['REQUEST_METHOD'] !== 'POST') { | |
| http_response_code(405); | |
| echo json_encode(['error' => 'Method not allowed']); | |
| exit; | |
| } | |
| $username = trim($_POST['username'] ?? ''); | |
| // Validate username | |
| if (!preg_match('/^[a-z0-9]{3,32}$/', $username)) { | |
| http_response_code(400); | |
| echo json_encode(['error' => 'Invalid username']); | |
| exit; | |
| } | |
| // Check user exists | |
| $db = new PDO('sqlite:/data/db/platform.sqlite'); | |
| $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
| $stmt = $db->prepare('SELECT id FROM users WHERE username = ?'); | |
| $stmt->execute([$username]); | |
| if (!$stmt->fetch()) { | |
| http_response_code(404); | |
| echo json_encode(['error' => 'User not found']); | |
| exit; | |
| } | |
| $htdocs = "/data/sites/{$username}/htdocs"; | |
| // Allowed file extensions | |
| $allowed = [ | |
| 'php','html','htm','css','js','json','txt','xml', | |
| 'png','jpg','jpeg','gif','webp','svg','ico', | |
| 'woff','woff2','ttf','eot','pdf','zip' | |
| ]; | |
| if (empty($_FILES['files'])) { | |
| http_response_code(400); | |
| echo json_encode(['error' => 'No files uploaded']); | |
| exit; | |
| } | |
| $uploaded = []; | |
| $errors = []; | |
| // Normalise $_FILES array for multiple uploads | |
| $files = $_FILES['files']; | |
| $count = is_array($files['name']) ? count($files['name']) : 1; | |
| for ($i = 0; $i < $count; $i++) { | |
| $name = is_array($files['name']) ? $files['name'][$i] : $files['name']; | |
| $tmp = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name']; | |
| $error = is_array($files['error']) ? $files['error'][$i] : $files['error']; | |
| if ($error !== UPLOAD_ERR_OK) { | |
| $errors[] = "{$name}: upload error code {$error}"; | |
| continue; | |
| } | |
| // Sanitise filename — strip any path components | |
| $name = basename($name); | |
| $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); | |
| if (!in_array($ext, $allowed)) { | |
| $errors[] = "{$name}: file type .{$ext} not allowed"; | |
| continue; | |
| } | |
| // Enforce 10 MB per file | |
| if (filesize($tmp) > 10 * 1024 * 1024) { | |
| $errors[] = "{$name}: exceeds 10 MB limit"; | |
| continue; | |
| } | |
| $dest = "{$htdocs}/{$name}"; | |
| if (move_uploaded_file($tmp, $dest)) { | |
| // Update files table | |
| $stmt = $db->prepare(' | |
| INSERT INTO files (username, filepath, updated_at) | |
| VALUES (?, ?, datetime("now")) | |
| ON CONFLICT(username, filepath) DO UPDATE SET updated_at=datetime("now") | |
| '); | |
| $stmt->execute([$username, $name]); | |
| $uploaded[] = $name; | |
| } else { | |
| $errors[] = "{$name}: failed to save file"; | |
| } | |
| } | |
| echo json_encode([ | |
| 'success' => count($uploaded) > 0, | |
| 'uploaded' => $uploaded, | |
| 'errors' => $errors | |
| ]); |