php-hosting / api /upload.php
Emalawi19's picture
Create api/upload.php
36d9100 verified
Raw
History Blame Contribute Delete
2.96 kB
<?php
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
]);