Upload via GUI (32 Dateien)

This commit is contained in:
2026-11-01 11:17:07 +00:00
parent e1c6f8dfca
commit 53f8bf0577
7 changed files with 626 additions and 491 deletions
+26 -10
View File
@@ -84,7 +84,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && !$tooBig) {
$error = 'App-Upload fehlgeschlagen (Code ' . ($upload['error'] ?? '?') . '). Prüft upload_max_filesize, post_max_size und die Servergrenze.';
} else {
$res = site_publish_app((string) ($_POST['platform'] ?? ''), (string) $upload['tmp_name'], trim((string) ($_POST['version'] ?? '')), (string) ($_POST['notes'] ?? ''));
if ($res['ok']) $message = 'App-Version veröffentlicht.';
if ($res['ok']) $message = 'App-Version ' . $res['version'] . ' veröffentlicht.';
else $error = $res['error'];
}
} elseif ($action === 'delete_app') {
@@ -107,6 +107,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && !$tooBig) {
} else {
$error = 'Ungültige Installation.';
}
} elseif ($action === 'set_preview' || $action === 'remove_preview') {
$img = $_FILES['preview'] ?? [];
if ($action === 'set_preview' && ($img['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
$error = 'Bitte ein Bild auswählen (PNG, JPG oder WebP, höchstens 1 MB).';
} else {
$res = site_set_preview((int) ($_POST['id'] ?? 0), $action === 'set_preview' ? (string) $img['tmp_name'] : null, $action === 'set_preview' ? (string) $img['name'] : null);
if ($res['ok']) $message = $action === 'set_preview' ? 'Vorschaubild geändert. Es bleibt bei weiteren Versionen erhalten.' : 'Vorschaubild entfernt.';
else $error = $res['error'];
}
} elseif ($action === 'feature' || $action === 'unfeature') {
$message = site_set_featured((int) ($_POST['id'] ?? 0), $action === 'feature') ? ($action === 'feature' ? 'Als „Empfohlen“ markiert. DeskHub zeigt es nach der nächsten Katalog-Aktualisierung (spätestens in wenigen Minuten).' : 'Empfehlung entfernt.') : null;
$error = $message ? null : 'Eintrag nicht gefunden.';
@@ -144,7 +153,7 @@ site_header($loggedIn ? $tabs[$tab][0] . ' · Verwaltung' : 'Anmelden', $tab, $l
<?php else:
$signed = site_public_key() !== '';
$appReleases = site_app_releases();
$latestApp = ['android' => null, 'windows' => null, 'minecraft' => null];
$latestApp = array_fill_keys(array_keys(site_app_platforms()), null);
foreach ($appReleases as $r) if (array_key_exists($r['platform'], $latestApp) && $latestApp[$r['platform']] === null) $latestApp[$r['platform']] = $r;
$pushSa = push_service_account();
$pushRows = push_db()->query('SELECT * FROM push_installs ORDER BY COALESCE(last_used_at, created_at) DESC LIMIT 200')->fetchAll();
@@ -200,7 +209,8 @@ site_header($loggedIn ? $tabs[$tab][0] . ' · Verwaltung' : 'Anmelden', $tab, $l
</div>
<label>Beschreibung<textarea name="description" rows="3"></textarea></label>
</fieldset>
<label>Vorschaubild (optional, PNG/JPG/WebP, höchstens 1 MB)<input type="file" name="preview" accept="image/png,image/jpeg,image/webp"></label>
<label>Vorschaubild (nur beim ersten Mal nötig, PNG/JPG/WebP, höchstens 1 MB)<input type="file" name="preview" accept="image/png,image/jpeg,image/webp"></label>
<p class="muted small">Bei einem Update von Plugin oder Theme bleibt das vorhandene Bild erhalten: einfach weglassen. Ändern oder entfernen kannst du es unten bei dem Eintrag.</p>
<div><button type="submit">Veröffentlichen</button></div>
</form>
</section>
@@ -218,6 +228,12 @@ site_header($loggedIn ? $tabs[$tab][0] . ' · Verwaltung' : 'Anmelden', $tab, $l
<?php if (!empty($it['language']) && is_array($__l = json_decode((string) $it['language'], true))): ?><span class="badge">🌐 <?= site_h((string) $__l['name']) ?> (<?= site_h((string) $__l['code']) ?>)</span><?php endif; ?>
<?= admin_btn(!empty($it['featured']) ? 'unfeature' : 'feature', ['id' => (int) $it['id']], !empty($it['featured']) ? 'Empfehlung entfernen' : 'Als Empfehlung markieren', 'ghost sm') ?>
</div>
<div class="previewrow">
<?php if (!empty($it['preview'])): ?><img class="thumb-sm" src="preview.php?file=<?= site_h(rawurlencode((string) $it['preview'])) ?>" alt="Vorschaubild von <?= site_h($it['name']) ?>"><?php else: ?><span class="thumb-sm none">kein Bild</span><?php endif; ?>
<form method="post" enctype="multipart/form-data" class="inline"><input type="hidden" name="action" value="set_preview"><input type="hidden" name="csrf" value="<?= site_h($csrf) ?>"><input type="hidden" name="id" value="<?= (int) $it['id'] ?>">
<input type="file" name="preview" accept="image/png,image/jpeg,image/webp" required> <button type="submit" class="ghost sm"><?= !empty($it['preview']) ? 'Bild ersetzen' : 'Bild hinzufügen' ?></button></form>
<?php if (!empty($it['preview'])) echo admin_btn('remove_preview', ['id' => (int) $it['id']], 'Bild entfernen', 'link danger', 'Vorschaubild wirklich entfernen?'); ?>
</div>
<div class="tablewrap flat"><table>
<?php foreach (site_versions((int) $it['id']) as $v): ?>
<tr><td><strong><?= site_h($v['version']) ?></strong></td><td class="muted"><?= site_h(substr($v['created_at'], 0, 10)) ?></td><td><?= (int) $v['downloads'] ?> Downloads</td>
@@ -232,24 +248,24 @@ site_header($loggedIn ? $tabs[$tab][0] . ' · Verwaltung' : 'Anmelden', $tab, $l
</div>
<?php elseif ($tab === 'apps'): ?>
<div class="pagehead"><div><h1>Apps</h1><p class="sub">Windows-, Android-App und Minecraft-Plugin veröffentlichen. Die Apps zeigen ihren Nutzern automatisch „Update verfügbar“, sobald hier eine höhere Version liegt.</p></div></div>
<div class="pagehead"><div><h1>Apps</h1><p class="sub">Windows-, Android-App, Minecraft-Plugin, WordPress-Plugin und Chrome-Erweiterung veröffentlichen. Die Apps zeigen ihren Nutzern automatisch „Update verfügbar“, sobald hier eine höhere Version liegt.</p></div></div>
<section class="card">
<header><div><h2>Neue App-Version hochladen</h2><p>Windows-Setups dürfen bis 300 MB groß sein (PHP-Grenzen <code>upload_max_filesize</code> / <code>post_max_size</code> beachten).</p></div></header>
<form method="post" enctype="multipart/form-data" class="form">
<input type="hidden" name="action" value="publish_app"><input type="hidden" name="csrf" value="<?= site_h($csrf) ?>">
<div class="row2">
<label>Plattform<select name="platform"><option value="windows">Windows (EXE)</option><option value="android">Android (APK)</option><option value="minecraft">Minecraft-Plugin (JAR)</option></select></label>
<label>Versionsnummer<input type="text" name="version" placeholder="3.4.0" pattern="[0-9]+[.][0-9]+[.][0-9]+([+-][A-Za-z0-9.-]+)?" required></label>
<label>Plattform<select name="platform" id="platform"><?php foreach (site_app_platforms() as $pk => $pv): ?><option value="<?= site_h($pk) ?>" data-zip="<?= $pv['ext'] === 'zip' ? '1' : '0' ?>"><?= site_h($pv['label'] . ' – ' . $pv['what']) ?></option><?php endforeach; ?></select></label>
<label>Versionsnummer <span class="muted small" id="versionhint" hidden>(leer lassen: wird aus dem Paket gelesen)</span><input type="text" id="appversion" name="version" placeholder="3.4.0" pattern="[0-9]+[.][0-9]+[.][0-9]+([+-][A-Za-z0-9.-]+)?" required></label>
</div>
<label>Installationsdatei<input type="file" name="app_file" accept=".apk,.exe,.jar,application/vnd.android.package-archive,application/vnd.microsoft.portable-executable" required></label>
<label>Installationsdatei<input type="file" name="app_file" accept=".apk,.exe,.jar,.zip,application/vnd.android.package-archive,application/vnd.microsoft.portable-executable,application/zip" required></label>
<label>Änderungen (optional, erscheint im Update-Hinweis)<textarea name="notes" rows="2" maxlength="2000"></textarea></label>
<div><button type="submit">App-Version hochladen</button></div>
</form>
</section>
<div class="cols three">
<?php foreach (['windows' => 'Windows', 'android' => 'Android', 'minecraft' => 'Minecraft'] as $pf => $pl): $mine = array_values(array_filter($appReleases, fn($r) => $r['platform'] === $pf)); $cur = $latestApp[$pf]; ?>
<div class="cols">
<?php foreach (array_map(fn($p) => $p['label'], site_app_platforms()) as $pf => $pl): $mine = array_values(array_filter($appReleases, fn($r) => $r['platform'] === $pf)); $cur = $latestApp[$pf]; ?>
<section class="card">
<header><div><h2><?= site_h($pl) ?></h2><p><?= ['windows' => 'Setup (EXE)', 'android' => 'Installationsdatei (APK)', 'minecraft' => 'Plugin (JAR)'][$pf] ?></p></div>
<header><div><h2><?= site_h($pl) ?></h2><p><?= site_h(site_app_platforms()[$pf]['what']) ?></p></div>
<?= $cur ? '<span class="badge ok">aktuell ' . site_h($cur['version']) . '</span>' : '<span class="badge">noch nichts veröffentlicht</span>' ?></header>
<?php if (!$mine): ?><div class="empty">Noch keine Version veröffentlicht.</div><?php else: ?>
<div class="tablewrap"><table>