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/dollhouse.php
<?php
/**
 * Dollhouse-Daten: Grundriss + Szenen-Positionen für die 3D-Puppenhaus-Ansicht.
 * GET ?language=de → { floorplan, width, height, rooms: [{id,name,x,y,thumb}] }
 */

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

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

$language = strtolower(trim((string)($_GET['language'] ?? 'en')));
if (!preg_match('/^[a-z]{2}$/', $language)) {
    $language = 'en';
}

$db = new SQLite3(__DIR__ . '/../admin/data/vrm.db');
$db->busyTimeout(5000);

// Aktiven Grundriss ermitteln.
$plan = $db->querySingle('SELECT id, extension FROM site_plans ORDER BY position LIMIT 1', true);
if (!$plan) {
    echo json_encode(['ok' => false, 'error' => 'no floorplan']);
    exit;
}
$planId = (int)$plan['id'];
$ext = (string)$plan['extension'];
$floorplan = 'floorplans/s' . $planId . '.' . $ext;
$floorAbs = __DIR__ . '/../' . $floorplan;

$width = 0;
$height = 0;
if (is_file($floorAbs)) {
    $info = @getimagesize($floorAbs);
    if ($info) {
        $width = (int)$info[0];
        $height = (int)$info[1];
    }
}

// Räume mit Koordinaten + Namen + Vorschaubild.
$stmt = $db->prepare("
    SELECT c.panos_id AS id, c.coordinates AS coord,
           COALESCE(NULLIF(pp.name,''), 'Scene ' || c.panos_id) AS name
    FROM pano_site_plans_connections c
    LEFT JOIN languages l ON l.short = :lang
    LEFT JOIN pano_phrases pp ON pp.panos_id = c.panos_id AND pp.languages_id = l.id
    WHERE c.site_plans_id = :pid
    GROUP BY c.panos_id
    ORDER BY c.panos_id
");
$stmt->bindValue(':lang', $language, SQLITE3_TEXT);
$stmt->bindValue(':pid', $planId, SQLITE3_INTEGER);
$res = $stmt->execute();

$rooms = [];
while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
    $parts = explode(',', (string)$row['coord']);
    if (count($parts) < 2) {
        continue;
    }
    $x = (float)trim($parts[0]);
    $y = (float)trim($parts[1]);
    $id = (int)$row['id'];
    $thumb = 'panos/p' . $id . '.tiles/thumb.jpg';
    if (!is_file(__DIR__ . '/../' . $thumb)) {
        $thumb = null;
    }
    $rooms[] = [
        'id' => $id,
        'name' => (string)$row['name'],
        'x' => $x,
        'y' => $y,
        'thumb' => $thumb,
    ];
}
$db->close();

echo json_encode([
    'ok' => true,
    'floorplan' => $floorplan,
    'width' => $width,
    'height' => $height,
    'rooms' => $rooms,
], JSON_UNESCAPED_UNICODE);