HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //home/panomity.de/vr.panomity.com/api/object-library.php
<?php
/**
 * Objektbibliothek für Virtual Staging.
 *
 * GET  → { objects: [{name,url,size}] } (öffentlich, listet media/objects3d)
 * POST multipart { model: .glb, edit_key } → Upload in die Bibliothek
 */

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

$libDir = __DIR__ . '/../media/objects3d';
if (!is_dir($libDir)) {
    @mkdir($libDir, 0775, true);
}

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $objects = [];
    foreach (glob($libDir . '/*.glb') ?: [] as $file) {
        $objects[] = [
            'name' => basename($file, '.glb'),
            'url' => 'media/objects3d/' . basename($file),
            'size' => filesize($file),
        ];
    }
    echo json_encode(['ok' => true, 'objects' => $objects], JSON_UNESCAPED_UNICODE);
    exit;
}

// POST: Upload (Editor-Key erforderlich)
$config = require __DIR__ . '/config.gpuq.php';
$editKey = (string)($_POST['edit_key'] ?? '');
if ($editKey === '' || !hash_equals((string)($config['staging_edit_key'] ?? ''), $editKey)) {
    http_response_code(403);
    echo json_encode(['ok' => false, 'error' => 'Forbidden']);
    exit;
}

if (empty($_FILES['model']) || !is_uploaded_file($_FILES['model']['tmp_name'])) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'model file required']);
    exit;
}
if ((int)$_FILES['model']['size'] > 50 * 1024 * 1024) {
    http_response_code(413);
    echo json_encode(['ok' => false, 'error' => 'file too large (max 50MB)']);
    exit;
}

$name = (string)($_FILES['model']['name'] ?? 'object.glb');
$base = preg_replace('/[^A-Za-z0-9._-]/', '_', basename($name));
if (!preg_match('/\.glb$/i', $base)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'only .glb files allowed']);
    exit;
}

// GLB-Magic prüfen ("glTF")
$fh = fopen($_FILES['model']['tmp_name'], 'rb');
$magic = fread($fh, 4);
fclose($fh);
if ($magic !== 'glTF') {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'not a valid GLB file']);
    exit;
}

$target = $libDir . '/' . $base;
if (!move_uploaded_file($_FILES['model']['tmp_name'], $target)) {
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'failed to store file']);
    exit;
}

echo json_encode(['ok' => true, 'name' => basename($base, '.glb'), 'url' => 'media/objects3d/' . $base]);