90 lines
2.5 KiB
PHP
90 lines
2.5 KiB
PHP
<?php
|
|
/**
|
|
* app/api/upload.php
|
|
*/
|
|
|
|
require_once __DIR__ . '/../bootstrap.php';
|
|
requireAuth();
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
$baseUploadDir = defined('UPLOAD_BASE_DIR') ? UPLOAD_BASE_DIR : (__DIR__ . '/../uploads');
|
|
$maxFileSize = defined('UPLOAD_MAX_FILE_SIZE') ? (int)UPLOAD_MAX_FILE_SIZE : (5 * 1024 * 1024);
|
|
$allowedCategories = defined('UPLOAD_ALLOWED_CATEGORIES') ? UPLOAD_ALLOWED_CATEGORIES : ['misc'];
|
|
$allowedMimeTypes = [
|
|
'image/svg+xml' => 'svg',
|
|
'image/png' => 'png',
|
|
'image/jpeg' => 'jpg',
|
|
];
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
jsonError('Methode nicht erlaubt', 405);
|
|
}
|
|
|
|
if (empty($_FILES['file'])) {
|
|
jsonError('Keine Datei hochgeladen', 400);
|
|
}
|
|
|
|
$file = $_FILES['file'];
|
|
if (!is_array($file) || $file['error'] !== UPLOAD_ERR_OK) {
|
|
jsonError('Upload-Fehler', 400);
|
|
}
|
|
|
|
if ((int)$file['size'] > $maxFileSize) {
|
|
jsonError('Datei zu gross', 400);
|
|
}
|
|
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
$mimeType = finfo_file($finfo, $file['tmp_name']);
|
|
finfo_close($finfo);
|
|
|
|
if (!isset($allowedMimeTypes[$mimeType])) {
|
|
jsonError('Dateityp nicht erlaubt', 400);
|
|
}
|
|
|
|
$category = strtolower(trim((string)($_POST['category'] ?? 'misc')));
|
|
if ($category === '' || !in_array($category, $allowedCategories, true)) {
|
|
jsonError('Ungueltige Kategorie', 400);
|
|
}
|
|
|
|
$targetDir = rtrim($baseUploadDir, '/\\') . DIRECTORY_SEPARATOR . $category;
|
|
if (!is_dir($targetDir) && !mkdir($targetDir, 0755, true) && !is_dir($targetDir)) {
|
|
jsonError('Upload-Verzeichnis konnte nicht erstellt werden', 500);
|
|
}
|
|
|
|
$extension = $allowedMimeTypes[$mimeType];
|
|
$filename = sprintf('%s_%s.%s', $category, bin2hex(random_bytes(16)), $extension);
|
|
$targetPath = $targetDir . DIRECTORY_SEPARATOR . $filename;
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
|
|
jsonError('Datei konnte nicht gespeichert werden', 500);
|
|
}
|
|
|
|
$publicPath = '/uploads/' . $category . '/' . $filename;
|
|
$uploadId = null;
|
|
|
|
$uploadTableExists = $sql->single("SHOW TABLES LIKE 'uploads'");
|
|
if (!empty($uploadTableExists)) {
|
|
$uploadId = $sql->set(
|
|
'INSERT INTO uploads (filename, path, mime_type, category) VALUES (?, ?, ?, ?)',
|
|
'ssss',
|
|
[$filename, $publicPath, $mimeType, $category],
|
|
true
|
|
);
|
|
}
|
|
|
|
echo json_encode([
|
|
'status' => 'ok',
|
|
'filename' => $filename,
|
|
'path' => $publicPath,
|
|
'mime_type' => $mimeType,
|
|
'id' => $uploadId,
|
|
]);
|
|
|
|
function jsonError(string $message, int $status = 400): void
|
|
{
|
|
http_response_code($status);
|
|
echo json_encode(['error' => $message]);
|
|
exit;
|
|
}
|