| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <?php
- declare(strict_types=1);
- require_once __DIR__ . "/../includes/auth.php";
- require_once __DIR__ . "/../includes/layout.php";
- require_once __DIR__ . "/../includes/releases.php";
- manageRequireLogin();
- $messages = [];
- $errors = [];
- if (($_SERVER["REQUEST_METHOD"] ?? "") === "POST") {
- try {
- manageRequireCsrf();
- $action = (string) ($_POST["action"] ?? "");
- $version = trim((string) ($_POST["version"] ?? ""));
- if ($action === "upload") {
- $release = manageReleasePublishUpload($version, $_FILES["package"] ?? []);
- $messages[] = "Release " . $version . " wurde hochgeladen und als aktuell veröffentlicht.";
- $messages[] = "SHA-256: " . $release["sha256"];
- } elseif ($action === "set_latest") {
- manageReleaseSetLatest($version);
- $messages[] = "Aktuelles Release ist jetzt " . $version . ".";
- } elseif ($action === "delete") {
- manageReleaseDelete($version);
- $messages[] = "Release " . $version . " wurde gelöscht.";
- }
- } catch (Throwable $exception) {
- $errors[] = $exception->getMessage();
- }
- }
- try {
- $manifest = manageReleaseReadManifest();
- $releases = manageReleaseListDescending();
- } catch (Throwable $exception) {
- $manifest = ["latest" => "", "releases" => []];
- $releases = [];
- $errors[] = $exception->getMessage();
- }
- // Server-side upload ceiling, so the form can state the real limit instead of
- // failing with an empty $_FILES entry.
- function manageUploadLimitBytes(): int
- {
- $toBytes = static function (string $value): int {
- $value = trim($value);
- if ($value === "") {
- return 0;
- }
- $unit = strtolower(substr($value, -1));
- $number = (int) $value;
- return match ($unit) {
- "g" => $number * 1073741824,
- "m" => $number * 1048576,
- "k" => $number * 1024,
- default => $number,
- };
- };
- $limits = array_filter([
- $toBytes((string) ini_get("upload_max_filesize")),
- $toBytes((string) ini_get("post_max_size")),
- ]);
- return $limits === [] ? 0 : (int) min($limits);
- }
- $uploadLimit = manageUploadLimitBytes();
- manageRenderHeader("Releases", $messages, $errors);
- ?>
- <section class="cards">
- <div class="card">
- <p class="card-label">Aktuelles Release</p>
- <p class="card-value"><?php echo manageEscape($manifest["latest"] !== "" ? $manifest["latest"] : "keines"); ?></p>
- </div>
- <div class="card">
- <p class="card-label">Paket-Präfix</p>
- <p class="card-value"><?php echo manageEscape(MANAGE_PACKAGE_PREFIX); ?></p>
- </div>
- <div class="card">
- <p class="card-label">Upload-Limit</p>
- <p class="card-value"><?php echo $uploadLimit > 0 ? manageEscape(manageFormatBytes($uploadLimit)) : "unbekannt"; ?></p>
- <p class="card-hint">PHP: upload_max_filesize / post_max_size</p>
- </div>
- </section>
- <h2>Release hochladen</h2>
- <form method="POST" enctype="multipart/form-data" class="panel">
- <?php echo manageCsrfField(); ?>
- <input type="hidden" name="action" value="upload">
- <div class="form-row">
- <div class="form-group">
- <label for="version">Version</label>
- <input type="text" id="version" name="version" required placeholder="v1.3.15"
- pattern="v[0-9]+\.[0-9]+\.[0-9]+">
- </div>
- <div class="form-group">
- <label for="package">ZIP-Paket</label>
- <input type="file" id="package" name="package" accept=".zip,application/zip" required>
- </div>
- </div>
- <p class="hint">
- Prüfsumme und Größe werden serverseitig berechnet. Ein Upload setzt das Release automatisch als aktuell.
- </p>
- <button type="submit" class="btn">Hochladen und veröffentlichen</button>
- </form>
- <h2>Veröffentlichte Releases</h2>
- <?php if ($releases === []): ?>
- <p class="empty">Noch keine Releases vorhanden. Paket mit dem Build-Skript aus dem Client-Paket (<code>scripts/create-release-zip.sh</code>) bauen und hier hochladen.</p>
- <?php else: ?>
- <div class="table-scroll">
- <table class="data-table">
- <thead>
- <tr>
- <th>Version</th>
- <th>Paket</th>
- <th>SHA-256</th>
- <th>Größe</th>
- <th>Veröffentlicht</th>
- <th>Aktionen</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($releases as $version => $release): ?>
- <?php $isLatest = $manifest["latest"] === $version; ?>
- <tr>
- <td>
- <strong><?php echo manageEscape($version); ?></strong>
- <?php if ($isLatest): ?>
- <br><span class="badge badge-ok">aktuell</span>
- <?php endif; ?>
- </td>
- <td><code><?php echo manageEscape($release["package"] ?? ""); ?></code></td>
- <td class="mono-cell"><?php echo manageEscape($release["sha256"] ?? ""); ?></td>
- <td><?php echo manageEscape(manageFormatBytes((int) ($release["size"] ?? 0))); ?></td>
- <td><?php echo manageEscape($release["published_at"] ?? ""); ?></td>
- <td>
- <div class="button-row">
- <?php if (!$isLatest): ?>
- <form method="POST">
- <?php echo manageCsrfField(); ?>
- <input type="hidden" name="action" value="set_latest">
- <input type="hidden" name="version" value="<?php echo manageEscape($version); ?>">
- <button type="submit" class="btn btn-secondary">Als aktuell setzen</button>
- </form>
- <?php endif; ?>
- <form method="POST" onsubmit="return confirm('Dieses Release wirklich löschen?');">
- <?php echo manageCsrfField(); ?>
- <input type="hidden" name="action" value="delete">
- <input type="hidden" name="version" value="<?php echo manageEscape($version); ?>">
- <button type="submit" class="btn btn-danger">Löschen</button>
- </form>
- </div>
- </td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- </div>
- <?php endif; ?>
- <?php manageRenderFooter(); ?>
|