div TODOs

This commit is contained in:
2026-02-16 13:56:01 +01:00
parent 12141485ae
commit 510a248edb
36 changed files with 1500 additions and 1533 deletions

View File

@@ -1,133 +1,89 @@
<?php
/**
* app/api/upload.php
*
* Zentrale Upload-API
* - Gerätetyp-Bilder (SVG / JPG / PNG)
* - Floorpläne (SVG)
* - Rack-Ansichten
*
* KEINE Logik für automatische Zuordnung
* -> Upload + Rückgabe von Pfad / Metadaten
*/
require_once __DIR__ . '/../bootstrap.php';
requireAuth();
header('Content-Type: application/json');
// TODO: Single-User-Auth prüfen
// if (!$_SESSION['user']) { http_response_code(403); exit; }
/* =========================
* Konfiguration
* ========================= */
// TODO: Upload-Basisverzeichnis aus config.php
$baseUploadDir = __DIR__ . '/../uploads';
// Erlaubte Typen
$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',
'image/png',
'image/jpeg'
'image/svg+xml' => 'svg',
'image/png' => 'png',
'image/jpeg' => 'jpg',
];
// TODO: Max. Dateigröße festlegen (z.B. 5MB)
$maxFileSize = 5 * 1024 * 1024;
/* =========================
* Validierung
* ========================= */
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
jsonError('Methode nicht erlaubt', 405);
}
if (empty($_FILES['file'])) {
http_response_code(400);
echo json_encode(['error' => 'Keine Datei hochgeladen']);
exit;
jsonError('Keine Datei hochgeladen', 400);
}
$file = $_FILES['file'];
if ($file['error'] !== UPLOAD_ERR_OK) {
http_response_code(400);
echo json_encode(['error' => 'Upload-Fehler']);
exit;
if (!is_array($file) || $file['error'] !== UPLOAD_ERR_OK) {
jsonError('Upload-Fehler', 400);
}
if ($file['size'] > $maxFileSize) {
http_response_code(400);
echo json_encode(['error' => 'Datei zu groß']);
exit;
if ((int)$file['size'] > $maxFileSize) {
jsonError('Datei zu gross', 400);
}
// MIME-Type prüfen
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (!in_array($mimeType, $allowedMimeTypes)) {
http_response_code(400);
echo json_encode(['error' => 'Dateityp nicht erlaubt']);
exit;
if (!isset($allowedMimeTypes[$mimeType])) {
jsonError('Dateityp nicht erlaubt', 400);
}
/* =========================
* Zielverzeichnis
* ========================= */
// TODO: Kategorie definieren (device_types, floors, racks, etc.)
$category = $_POST['category'] ?? 'misc';
// Zielpfad
$targetDir = $baseUploadDir . '/' . preg_replace('/[^a-z0-9_-]/i', '', $category);
// Verzeichnis anlegen falls nötig
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
$category = strtolower(trim((string)($_POST['category'] ?? 'misc')));
if ($category === '' || !in_array($category, $allowedCategories, true)) {
jsonError('Ungueltige Kategorie', 400);
}
/* =========================
* Dateiname
* ========================= */
$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);
}
// Originalname bereinigen
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
// TODO: Eindeutigen Namen besser definieren (UUID?)
$filename = uniqid('upload_', true) . '.' . strtolower($extension);
$targetPath = $targetDir . '/' . $filename;
/* =========================
* Datei speichern
* ========================= */
$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)) {
http_response_code(500);
echo json_encode(['error' => 'Datei konnte nicht gespeichert werden']);
exit;
jsonError('Datei konnte nicht gespeichert werden', 500);
}
/* =========================
* Optional: DB-Eintrag
* ========================= */
$publicPath = '/uploads/' . $category . '/' . $filename;
$uploadId = null;
// TODO: Optional in Tabelle `uploads` speichern
// $uploadId = $sql->set(
// "INSERT INTO uploads (filename, path, mime_type, category)
// VALUES (?, ?, ?, ?)",
// "ssss",
// [$filename, $targetPath, $mimeType, $category],
// true
// );
/* =========================
* Antwort
* ========================= */
$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' => str_replace(__DIR__ . '/..', '', $targetPath),
'mime_type' => $mimeType
// 'id' => $uploadId ?? null
'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;
}