<?php
// media.php — list folders & images under ../images/tiles
// Security notes:
// - Prevents directory traversal
// - Only serves paths inside $baseDir
// - Returns JSON { breadcrumb, folders, images }
error_reporting(E_ALL);
ini_set('display_errors', 1);
header('Content-Type: application/json; charset=utf-8');
$baseDir = realpath(__DIR__ . '/../images/tiles'); // one level up, then images/tiles
if ($baseDir === false || !is_dir($baseDir)) {
http_response_code(500);
echo json_encode(['error' => 'Base directory not found']);
exit;
}
// Normalize requested subpath (relative to base)
$sub = isset($_GET['sub']) ? $_GET['sub'] : '';
$sub = str_replace('\\', '/', $sub);
$sub = preg_replace('#\.+/#', '', $sub); // strip things like ../ ./ etc.
$sub = trim($sub, '/');
$path = $baseDir . ($sub ? '/' . $sub : '');
$real = realpath($path);
if ($real === false || strpos($real, $baseDir) !== 0) {
// Fallback to base if invalid or attempting traversal
$real = $baseDir;
$sub = '';
}
if (!is_dir($real)) {
http_response_code(400);
echo json_encode(['error' => 'Not a directory']);
exit;
}
// Helper: build web URL from file path (same-origin)
function file_to_url(string $filePath): string {
// Try to derive a URL relative to the document root
$docroot = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', '/');
$filePath = realpath($filePath);
if ($docroot && $filePath && strpos($filePath, $docroot) === 0) {
$rel = substr($filePath, strlen($docroot));
return $rel === '' ? '/' : str_replace(DIRECTORY_SEPARATOR, '/', $rel);
}
// Fallback: relative from current script
$scriptDir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
return $scriptDir . '/' . basename($filePath);
}
$entries = scandir($real) ?: [];
$folders = [];
$images = [];
$allowExt = ['jpg','jpeg','png','gif','webp','avif','bmp','svg'];
foreach ($entries as $e) {
if ($e === '.' || $e === '..' || $e[0] === '.') continue;
$full = $real . '/' . $e;
if (is_dir($full)) {
$folders[] = [
'name' => $e,
'sub' => $sub ? ($sub . '/' . $e) : $e
];
} elseif (is_file($full)) {
$ext = strtolower(pathinfo($e, PATHINFO_EXTENSION));
if (in_array($ext, $allowExt, true)) {
$images[] = [
'name' => $e,
'url' => file_to_url($full)
];
}
}
}
// Build breadcrumb from $sub
$crumbs = [];
$parts = $sub === '' ? [] : explode('/', $sub);
$running = '';
$crumbs[] = ['label' => 'tiles', 'sub' => '']; // root
foreach ($parts as $p) {
$running = $running ? ($running . '/' . $p) : $p;
$crumbs[] = ['label' => $p, 'sub' => $running];
}
echo json_encode([
'cwd' => $sub,
'breadcrumb' => $crumbs,
'folders' => $folders,
'images' => $images
], JSON_UNESCAPED_SLASHES);