'php', 'javascript' => 'javascript', 'js' => 'javascript', 'python' => 'python', 'java' => 'java']; return $map[$label] ?? 'plain'; } /** Resolve a repo-relative file to an absolute path, or null if it escapes. */ function resolve_repo_file(array $repo, string $filename): ?string { $repoDir = realpath(UPLOAD_DIR . '/' . $repo['slug']); $full = realpath(UPLOAD_DIR . '/' . $repo['slug'] . '/' . $filename); if ($repoDir === false || $full === false || strpos($full, $repoDir . DIRECTORY_SEPARATOR) !== 0) { return null; } return $full; } /** Breadcrumb trail for a folder or file path within a repo. */ function render_crumbs(array $repo, string $path): void { $slug = $repo['slug']; $segments = $path === '' ? [] : explode('/', $path); $last = count($segments) - 1; ?> [], 'files' => []]; } $page_title = $repo['name'] . ($folder !== '' ? ' / ' . $folder : ''); [$og_title, $og_description, $og_image, $og_url] = repo_share_meta($repo, $folder); require __DIR__ . '/includes/header.php'; render_crumbs($repo, $folder); ?>

Download ZIP

No files in this repository yet.

📁 ..
' . '📄 ' . e($file['name']) . '
' . markdown_to_html($md) . '
'; } } break; } } } require __DIR__ . '/includes/footer.php'; } function render_file_view(array $repo, string $blob): void { $filename = safe_relpath($blob); $record = get_file_by_name((int) $repo['id'], $filename); if (!$record) { render_404(); return; } $full = resolve_repo_file($repo, $filename); if ($full === null) { render_404(); return; } $isImage = is_image_file($filename); $isSvg = is_svg_file($filename); $isModel = is_model_file($filename); $modelFmt = $isModel ? model_format($filename) : ''; // A model file renders in the 3D viewer; only small, text-based model // formats (OBJ / ASCII PLY / G-code) also keep a readable "Source" view. $modelSourceOk = $isModel && is_text_model_format($modelFmt) && (int) $record['filesize'] <= 2 * 1024 * 1024; $hasRendered = $isImage || $isModel; // has a non-source view $showSource = $isSvg || $modelSourceOk || (!$isImage && !$isModel); $lines = []; $lang = 'plain'; if ($showSource) { $code = file_get_contents($full); if ($code === false) { $code = ''; } $lang = highlight_lang_for($repo, $filename); $lines = explode("\n", str_replace("\r\n", "\n", $code)); } // Sidebar file tree for the whole repository. $allFiles = get_files_by_repo((int) $repo['id']); $allFolders = get_folders_by_repo((int) $repo['id']); $sidebar = render_tree_nodes( build_file_tree($allFiles, $allFolders), $repo, '', ['active' => $filename, 'open' => ancestor_dirs($filename)] ); $page_title = $repo['name'] . ' / ' . $filename; [$og_title, $og_description, $og_image, $og_url] = repo_share_meta($repo, $filename, true); require __DIR__ . '/includes/header.php'; render_crumbs($repo, $filename); ?>
lines ·
Raw Download
<?= e(basename($filename)) ?>
Loading 3D view…
$line): ?>
/" folder so * the archive expands into a single tidy directory. */ function render_archive(array $repo): void { if (!class_exists('ZipArchive')) { archive_error(500, 'Zip archives are unavailable on this server (the PHP zip extension is not installed).'); return; } $files = get_files_by_repo((int) $repo['id']); if (empty($files)) { render_404(); return; } // ZipArchive writes to a real file, so build it in a temp file, stream it, // then remove it. Building incrementally keeps memory use flat. $tmp = tempnam(sys_get_temp_dir(), 'repozip_'); if ($tmp === false) { archive_error(500, 'Unable to create the archive.'); return; } $zip = new ZipArchive(); if ($zip->open($tmp, ZipArchive::OVERWRITE) !== true) { @unlink($tmp); archive_error(500, 'Unable to create the archive.'); return; } $root = $repo['slug']; // top-level folder inside the zip $added = 0; // Preserve empty folders (they exist as folder rows but hold no files). foreach (get_folders_by_repo((int) $repo['id']) as $folder) { $zip->addEmptyDir($root . '/' . $folder['path']); } foreach ($files as $file) { $full = resolve_repo_file($repo, $file['filename']); if ($full === null || !is_file($full)) { continue; // skip records whose file is missing on disk } if ($zip->addFile($full, $root . '/' . $file['filename'])) { $added++; } } $zip->close(); if ($added === 0) { @unlink($tmp); render_404(); return; } $size = filesize($tmp); header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . $repo['slug'] . '.zip"'); header('X-Content-Type-Options: nosniff'); if ($size !== false) { header('Content-Length: ' . $size); } readfile($tmp); @unlink($tmp); } /** Emit a plain-text error for the archive endpoint (no HTML chrome yet sent). */ function archive_error(int $code, string $message): void { http_response_code($code); header('Content-Type: text/plain; charset=utf-8'); echo $message; }