1e51ef7def
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/ - 12 code-workspace-Files - STATUS-*.md - viele M/D/R-Änderungen an bereits getrackten Files - .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
76 lines
2.2 KiB
PHP
76 lines
2.2 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/artifact
|
|
* Multipart-Upload für Modul-erzeugte Artefakte (Bilder, Karten, Audio).
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/../../bootstrap.php';
|
|
|
|
v2_validate_method('POST');
|
|
$auth = v2_auth_require('student');
|
|
$studentId = (int) ($auth['sub'] ?? 0);
|
|
|
|
$slug = $_POST['moduleSlug'] ?? '';
|
|
$label = $_POST['label'] ?? '';
|
|
if (!$slug) {
|
|
v2_response_error(400, 'missing_slug', 'Feld "moduleSlug" fehlt.');
|
|
}
|
|
|
|
if (empty($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
|
|
v2_response_error(400, 'upload_failed', 'Datei-Upload fehlgeschlagen.');
|
|
}
|
|
|
|
$file = $_FILES['file'];
|
|
$mimeType = mime_content_type($file['tmp_name']) ?: 'application/octet-stream';
|
|
|
|
// Erlaubte MIME-Typen
|
|
$allowedMime = ['image/png', 'image/jpeg', 'image/webp', 'audio/mpeg', 'audio/wav', 'audio/ogg', 'application/pdf'];
|
|
if (!in_array($mimeType, $allowedMime, true)) {
|
|
v2_response_error(415, 'unsupported_media_type', "MIME-Typ '$mimeType' nicht erlaubt.");
|
|
}
|
|
|
|
// Max 10 MB
|
|
if ($file['size'] > 10 * 1024 * 1024) {
|
|
v2_response_error(413, 'file_too_large', 'Max 10 MB pro Upload.');
|
|
}
|
|
|
|
// Ablage
|
|
$uploadDir = V2_ROOT . "/uploads/$slug/student-$studentId";
|
|
if (!is_dir($uploadDir)) {
|
|
if (!mkdir($uploadDir, 0775, true)) {
|
|
v2_response_error(500, 'upload_dir_failed', 'Upload-Ordner konnte nicht erstellt werden.');
|
|
}
|
|
}
|
|
|
|
$ext = pathinfo($file['name'], PATHINFO_EXTENSION) ?: 'bin';
|
|
$ext = preg_replace('/[^a-zA-Z0-9]/', '', $ext);
|
|
$filename = sprintf('%s-%s.%s', date('Ymd-His'), bin2hex(random_bytes(4)), $ext);
|
|
$destPath = "$uploadDir/$filename";
|
|
$publicUrl = V2_BASE_URL . "/uploads/$slug/student-$studentId/$filename";
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $destPath)) {
|
|
v2_response_error(500, 'move_failed', 'Datei konnte nicht abgelegt werden.');
|
|
}
|
|
|
|
v2_db_exec("
|
|
INSERT INTO artifacts_v2
|
|
(student_id, module_slug, mime_type, url, label, bytes)
|
|
VALUES
|
|
(:sid, :slug, :mt, :url, :lbl, :b)
|
|
", [
|
|
':sid' => $studentId,
|
|
':slug' => $slug,
|
|
':mt' => $mimeType,
|
|
':url' => $publicUrl,
|
|
':lbl' => $label,
|
|
':b' => (int) $file['size'],
|
|
]);
|
|
$id = (int) v2_db_insert_id();
|
|
|
|
v2_response_created([
|
|
'id' => $id,
|
|
'url' => $publicUrl,
|
|
'thumbnail' => null, // TODO: Thumbnail-Generation für Bilder
|
|
]);
|