v1.2.0 - Anpassung der Release Notes
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="colors.php"><span class="material-icons text-secondary me-2">palette</span>Farben</a></li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="planning.php"><span class="material-icons text-secondary me-2">event</span>Terminplanung</a></li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="users.php"><span class="material-icons text-secondary me-2">group</span>Benutzer</a></li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="info.php"><span class="material-icons text-secondary me-2">info</span>Release Notes</a></li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="version.php"><span class="material-icons text-secondary me-2">info</span>Release Notes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
215
info.php
215
info.php
@@ -1,215 +0,0 @@
|
||||
<?php
|
||||
// 🔐 Sicherheits- und Datenbanklogik zuerst – VOR jeglicher HTML-Ausgabe
|
||||
include('inc/check_login.php');
|
||||
require_once('inc/db.php');
|
||||
|
||||
$is_admin = ($_SESSION['role'] === 'admin');
|
||||
$message = '';
|
||||
$message_type = '';
|
||||
$edit_mode = false;
|
||||
$edit_release = null;
|
||||
|
||||
// --- Nur Admins: Aktionen verarbeiten ---
|
||||
if ($is_admin) {
|
||||
// Löschen
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||
$id = (int)$_GET['id'];
|
||||
$stmt = mysqli_prepare($conn, "DELETE FROM releases WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "i", $id);
|
||||
if (mysqli_stmt_execute($stmt)) {
|
||||
$_SESSION['message'] = "Version erfolgreich gelöscht!";
|
||||
$_SESSION['message_type'] = 'success';
|
||||
} else {
|
||||
$_SESSION['message'] = "Fehler beim Löschen.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
}
|
||||
mysqli_stmt_close($stmt);
|
||||
header("Location: info.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Bearbeiten: Daten laden
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
||||
$id = (int)$_GET['id'];
|
||||
$stmt = mysqli_prepare($conn, "SELECT id, version, release_date, notes FROM releases WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "i", $id);
|
||||
mysqli_stmt_execute($stmt);
|
||||
$result = mysqli_stmt_get_result($stmt);
|
||||
$edit_release = mysqli_fetch_assoc($result);
|
||||
mysqli_stmt_close($stmt);
|
||||
$edit_mode = true;
|
||||
if (!$edit_release) {
|
||||
$_SESSION['message'] = "Version nicht gefunden.";
|
||||
$_SESSION['message_type'] = 'warning';
|
||||
}
|
||||
}
|
||||
|
||||
// Speichern (POST)
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$version = trim($_POST['version'] ?? '');
|
||||
$date = trim($_POST['date'] ?? '');
|
||||
$notes = trim($_POST['notes'] ?? '');
|
||||
$id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
|
||||
|
||||
if (empty($version) || empty($date) || empty($notes)) {
|
||||
$_SESSION['message'] = "Alle Felder sind erforderlich.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} elseif (!preg_match('/^v\d+\.\d+\.\d+$/', $version)) {
|
||||
$_SESSION['message'] = "Ungültiges Versionsformat. Beispiel: v1.4.2";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} elseif (!strtotime($date)) {
|
||||
$_SESSION['message'] = "Ungültiges Datum.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} else {
|
||||
if ($id) {
|
||||
$stmt = mysqli_prepare($conn, "UPDATE releases SET version = ?, release_date = ?, notes = ? WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "sssi", $version, $date, $notes, $id);
|
||||
} else {
|
||||
$stmt = mysqli_prepare($conn, "INSERT INTO releases (version, release_date, notes) VALUES (?, ?, ?)");
|
||||
mysqli_stmt_bind_param($stmt, "sss", $version, $date, $notes);
|
||||
}
|
||||
|
||||
if (mysqli_stmt_execute($stmt)) {
|
||||
$_SESSION['message'] = $id ? "Version aktualisiert!" : "Neue Version hinzugefügt!";
|
||||
$_SESSION['message_type'] = 'success';
|
||||
mysqli_stmt_close($stmt);
|
||||
header("Location: info.php");
|
||||
exit();
|
||||
} else {
|
||||
$_SESSION['message'] = "Fehler beim Speichern.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
}
|
||||
mysqli_stmt_close($stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Meldungen aus Session holen (nach Redirects) ---
|
||||
if (isset($_SESSION['message'])) {
|
||||
$message = $_SESSION['message'];
|
||||
$message_type = $_SESSION['message_type'];
|
||||
unset($_SESSION['message'], $_SESSION['message_type']);
|
||||
}
|
||||
|
||||
// --- Daten für Anzeige laden ---
|
||||
$releases = [];
|
||||
$result = mysqli_query($conn, "SELECT id, version, release_date, notes FROM releases ORDER BY release_date DESC, id DESC");
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$row['notes_array'] = array_filter(array_map('trim', explode("\n", $row['notes'])));
|
||||
$releases[] = $row;
|
||||
}
|
||||
$current_release = $releases[0] ?? null;
|
||||
|
||||
// --- Erst JETZT: HTML-Header einbinden ---
|
||||
require_once('inc/header.php');
|
||||
?>
|
||||
|
||||
<div class="container mt-5 mb-4">
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-<?= htmlspecialchars($message_type) ?> alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($message) ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<h2 class="mb-4">ℹ️ Info & Versionshinweise</h2>
|
||||
|
||||
<?php if ($current_release): ?>
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header bg-primary-subtle text-secondary">
|
||||
<h4 class="mb-0">Aktuelle Version</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="h5 mb-0"><?= htmlspecialchars($current_release['version']) ?></p>
|
||||
<p class="text-muted small mb-0">Veröffentlicht am: <?= date('d.m.Y', strtotime($current_release['release_date'])) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-secondary bg-opacity-50 text-secondary d-flex justify-content-between align-items-center">
|
||||
<h4 class="mb-0">Release Notes</h4>
|
||||
<?php if ($is_admin): ?>
|
||||
<a class="btn btn-sm d-flex align-items-center justify-content-center" data-bs-toggle="collapse" href="#releaseFormCollapse" role="button" aria-expanded="false" aria-controls="releaseFormCollapse">Add
|
||||
<span class="material-symbols-outlined">add</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<?php if ($is_admin): ?>
|
||||
<div class="collapse <?= $edit_mode ? 'show' : '' ?>" id="releaseFormCollapse">
|
||||
<div class="card card-body bg-light mb-4">
|
||||
<h5><?= $edit_mode ? 'Version bearbeiten' : 'Neue Version hinzufügen'; ?></h5>
|
||||
<form method="POST">
|
||||
<?php if ($edit_mode): ?>
|
||||
<input type="hidden" name="id" value="<?= htmlspecialchars($edit_release['id']); ?>">
|
||||
<?php endif; ?>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Versionsnummer</label>
|
||||
<input type="text" class="form-control" name="version" value="<?= htmlspecialchars($edit_release['version'] ?? ''); ?>" placeholder="z. B. v1.5.0" required>
|
||||
<div class="form-text">Format: v1.4.2</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Veröffentlichungsdatum</label>
|
||||
<input type="date" class="form-control" name="date" value="<?= htmlspecialchars($edit_release['release_date'] ?? date('Y-m-d')); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Release Notes (ein Punkt pro Zeile)</label>
|
||||
<textarea class="form-control" name="notes" rows="5" required><?= htmlspecialchars($edit_release['notes'] ?? '') ?></textarea>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-sm btn-outline-<?= $edit_mode ? 'success' : 'primary'; ?>"><?= $edit_mode ? 'Speichern' : 'Hinzufügen'; ?></button>
|
||||
<a href="info.php" class="btn btn-sm btn-outline-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($releases)): ?>
|
||||
<p class="text-muted">Keine Release Notes vorhanden.</p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($releases as $release): ?>
|
||||
<div class="d-flex align-items-start">
|
||||
<div class="flex-grow-1">
|
||||
<h5 class="mt-4 mb-1"><?= htmlspecialchars($release['version']) ?></h5>
|
||||
<p class="text-muted small mb-3">Veröffentlicht am: <?= date('d.m.Y', strtotime($release['release_date'])) ?></p>
|
||||
<ul class="mb-4">
|
||||
<?php foreach ($release['notes_array'] as $note): ?>
|
||||
<li><?= htmlspecialchars($note) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php if ($is_admin): ?>
|
||||
<div class="dropdown ms-3 mt-4">
|
||||
<a href="#" class="text-secondary" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<span class="material-icons">more_vert</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item d-flex align-items-center" href="info.php?action=edit&id=<?= $release['id'] ?>">
|
||||
<span class="material-icons me-2">mode_edit_outline</span> Bearbeiten
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item d-flex align-items-center text-danger" href="info.php?action=delete&id=<?= $release['id'] ?>" onclick="return confirm('Wirklich löschen?')">
|
||||
<span class="material-icons me-2">delete_outline</span> Löschen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include('inc/footer.php'); ?>
|
||||
402
version.php
Executable file
402
version.php
Executable file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
include('inc/check_login.php');
|
||||
require_once('inc/db.php');
|
||||
|
||||
define('APP_URL', 'https://domili.borgal.de');
|
||||
|
||||
// 🔹 Funktion zur sicheren Formatierung
|
||||
function parse_formatting($text)
|
||||
{
|
||||
if (empty($text)) return '';
|
||||
$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
|
||||
$text = preg_replace('/\[b\](.*?)\[\/b\]/i', '<strong>$1</strong>', $text);
|
||||
$text = preg_replace('/\[i\](.*?)\[\/i\]/i', '<em>$1</em>', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
// 🔹 Holt alle Benutzer mit gültiger E-Mail
|
||||
function get_all_user_emails($conn)
|
||||
{
|
||||
$stmt = mysqli_prepare($conn, "SELECT id, username, email FROM users WHERE email IS NOT NULL AND email != ''");
|
||||
mysqli_stmt_execute($stmt);
|
||||
$result = mysqli_stmt_get_result($stmt);
|
||||
$users = [];
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$users[] = $row;
|
||||
}
|
||||
mysqli_stmt_close($stmt);
|
||||
return $users;
|
||||
}
|
||||
|
||||
$is_admin = ($_SESSION['role'] === 'admin');
|
||||
$message = '';
|
||||
$message_type = '';
|
||||
$edit_mode = false;
|
||||
$edit_release = null;
|
||||
|
||||
if ($is_admin) {
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'publish' && isset($_GET['id'])) {
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
$stmt_data = mysqli_prepare($conn, "SELECT version, release_date, features, bugfixes FROM releases WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt_data, "i", $id);
|
||||
mysqli_stmt_execute($stmt_data);
|
||||
$release_data = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt_data));
|
||||
mysqli_stmt_close($stmt_data);
|
||||
|
||||
if (!$release_data) {
|
||||
$_SESSION['message'] = "Version nicht gefunden.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
header("Location: version.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
$stmt = mysqli_prepare($conn, "UPDATE releases SET is_draft = 0 WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "i", $id);
|
||||
$success = mysqli_stmt_execute($stmt);
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
if ($success) {
|
||||
// 🔹 Sende E-Mail an alle Benutzer mit gültiger E-Mail
|
||||
$all_users = get_all_user_emails($conn);
|
||||
|
||||
if (!empty($all_users) && file_exists(__DIR__ . '/vendor/autoload.php')) {
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$version = htmlspecialchars($release_data['version']);
|
||||
$release_date_raw = date('d.m.Y', strtotime($release_data['release_date']));
|
||||
$version_url = APP_URL . '/version.php';
|
||||
$app_url = APP_URL;
|
||||
|
||||
$features = array_filter(array_map('trim', explode("\n", $release_data['features'] ?? '')));
|
||||
$bugs = array_filter(array_map('trim', explode("\n", $release_data['bugfixes'] ?? '')));
|
||||
|
||||
foreach ($all_users as $user) {
|
||||
$recipient_email = $user['email'];
|
||||
$recipient_name = $user['username'] ?? 'Benutzer';
|
||||
|
||||
try {
|
||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->isSMTP();
|
||||
$mail->Host = SMTP_HOST;
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = SMTP_USERNAME;
|
||||
$mail->Password = SMTP_PASSWORD;
|
||||
$mail->SMTPSecure = SMTP_ENCRYPTION;
|
||||
$mail->Port = SMTP_PORT;
|
||||
$mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME);
|
||||
|
||||
// Text-Version
|
||||
$text_body = "Hallo $recipient_name,\n\n";
|
||||
$text_body .= "Es wurde soeben eine neue Version in DoMiLi veröffentlicht:\n\n";
|
||||
$text_body .= "Version: $version\n";
|
||||
$text_body .= "Veröffentlicht am: $release_date_raw\n";
|
||||
$text_body .= "Details: $version_url\n\n";
|
||||
|
||||
if (!empty($features)) {
|
||||
$text_body .= "Neue Features:\n";
|
||||
foreach ($features as $f) {
|
||||
$text_body .= "- " . strip_tags(parse_formatting($f)) . "\n";
|
||||
}
|
||||
$text_body .= "\n";
|
||||
}
|
||||
if (!empty($bugs)) {
|
||||
$text_body .= "Behobene Fehler:\n";
|
||||
foreach ($bugs as $b) {
|
||||
$text_body .= "- " . strip_tags(parse_formatting($b)) . "\n";
|
||||
}
|
||||
$text_body .= "\n";
|
||||
}
|
||||
|
||||
$text_body .= "Direkt zur App: $app_url\n\n";
|
||||
$text_body .= "Dein DoMiLi-Admin";
|
||||
|
||||
// HTML-Version
|
||||
$html_features = '';
|
||||
if (!empty($features)) {
|
||||
$html_features .= "<p style=\"margin: 0.5em 0;\"><strong>Neue Features:</strong></p>\n<ul style=\"margin-top: 0.5em; margin-bottom: 0.5em;\">";
|
||||
foreach ($features as $f) {
|
||||
$html_features .= "<li>" . parse_formatting($f) . "</li>\n";
|
||||
}
|
||||
$html_features .= "</ul>\n";
|
||||
}
|
||||
|
||||
$html_bugs = '';
|
||||
if (!empty($bugs)) {
|
||||
$html_bugs .= "<p style=\"margin: 0.5em 0;\"><strong>Behobene Fehler:</strong></p>\n<ul style=\"margin-top: 0.5em; margin-bottom: 0.5em;\">";
|
||||
foreach ($bugs as $b) {
|
||||
$html_bugs .= "<li>" . parse_formatting($b) . "</li>\n";
|
||||
}
|
||||
$html_bugs .= "</ul>\n";
|
||||
}
|
||||
|
||||
$html_body = "
|
||||
<p>Hallo <strong>$recipient_name</strong>,</p>
|
||||
<p>Es wurde soeben eine neue Version in DoMiLi veröffentlicht:</p>
|
||||
<ul>
|
||||
<li><strong>Version:</strong> <a href=\"$version_url\" style=\"color: #0d6efd; text-decoration: none;\">$version</a></li>
|
||||
<li><strong>Veröffentlicht am:</strong>
|
||||
<span x-apple-data-detectors=\"false\" style=\"display: inline-block;\">$release_date_raw</span>
|
||||
</li>
|
||||
</ul>
|
||||
$html_features
|
||||
$html_bugs
|
||||
<p><a href=\"$app_url\" style=\"color: #0d6efd; text-decoration: none;\">Direkt zur App</a></p>
|
||||
<p><em>Dein DoMiLi-Admin</em></p>
|
||||
";
|
||||
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = "DoMiLi: Neue Version veröffentlicht – " . $release_data['version'];
|
||||
$mail->Body = $html_body;
|
||||
$mail->AltBody = $text_body;
|
||||
$mail->addAddress($recipient_email);
|
||||
$mail->send();
|
||||
} catch (Exception $e) {
|
||||
error_log("PHPMailer Fehler beim Senden an $recipient_email: " . $mail->ErrorInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['message'] = "Version veröffentlicht!";
|
||||
$_SESSION['message_type'] = 'success';
|
||||
} else {
|
||||
$_SESSION['message'] = "Fehler beim Freigeben.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
}
|
||||
header("Location: version.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||
$id = (int)$_GET['id'];
|
||||
$stmt = mysqli_prepare($conn, "DELETE FROM releases WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "i", $id);
|
||||
if (mysqli_stmt_execute($stmt)) {
|
||||
$_SESSION['message'] = "Version gelöscht!";
|
||||
$_SESSION['message_type'] = 'success';
|
||||
} else {
|
||||
$_SESSION['message'] = "Fehler beim Löschen.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
}
|
||||
mysqli_stmt_close($stmt);
|
||||
header("Location: version.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
||||
$id = (int)$_GET['id'];
|
||||
$stmt = mysqli_prepare($conn, "SELECT id, version, release_date, features, bugfixes, is_draft FROM releases WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "i", $id);
|
||||
mysqli_stmt_execute($stmt);
|
||||
$edit_release = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt));
|
||||
mysqli_stmt_close($stmt);
|
||||
$edit_mode = true;
|
||||
if (!$edit_release) {
|
||||
$_SESSION['message'] = "Version nicht gefunden.";
|
||||
$_SESSION['message_type'] = 'warning';
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$version = trim($_POST['version'] ?? '');
|
||||
$date = trim($_POST['date'] ?? '');
|
||||
$features = trim($_POST['features'] ?? '');
|
||||
$bugfixes = trim($_POST['bugfixes'] ?? '');
|
||||
$id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
|
||||
|
||||
if (empty($version) || empty($date)) {
|
||||
$_SESSION['message'] = "Versionsnummer und Datum sind erforderlich.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} elseif (!preg_match('/^v\d+\.\d+\.\d+$/', $version)) {
|
||||
$_SESSION['message'] = "Ungültiges Versionsformat. Beispiel: v1.4.2";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} elseif (!strtotime($date)) {
|
||||
$_SESSION['message'] = "Ungültiges Datum.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
} else {
|
||||
if ($id) {
|
||||
$stmt = mysqli_prepare($conn, "UPDATE releases SET version = ?, release_date = ?, features = ?, bugfixes = ? WHERE id = ?");
|
||||
mysqli_stmt_bind_param($stmt, "ssssi", $version, $date, $features, $bugfixes, $id);
|
||||
} else {
|
||||
$stmt = mysqli_prepare($conn, "INSERT INTO releases (version, release_date, features, bugfixes, is_draft) VALUES (?, ?, ?, ?, 1)");
|
||||
mysqli_stmt_bind_param($stmt, "ssss", $version, $date, $features, $bugfixes);
|
||||
}
|
||||
|
||||
if (mysqli_stmt_execute($stmt)) {
|
||||
$_SESSION['message'] = $id ? "Version aktualisiert!" : "Entwurf gespeichert!";
|
||||
$_SESSION['message_type'] = 'success';
|
||||
mysqli_stmt_close($stmt);
|
||||
header("Location: version.php");
|
||||
exit();
|
||||
} else {
|
||||
$_SESSION['message'] = "Fehler beim Speichern.";
|
||||
$_SESSION['message_type'] = 'danger';
|
||||
}
|
||||
mysqli_stmt_close($stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION['message'])) {
|
||||
$message = $_SESSION['message'];
|
||||
$message_type = $_SESSION['message_type'];
|
||||
unset($_SESSION['message'], $_SESSION['message_type']);
|
||||
}
|
||||
|
||||
if ($is_admin) {
|
||||
$result = mysqli_query($conn, "SELECT id, version, release_date, features, bugfixes, is_draft FROM releases ORDER BY release_date DESC, id DESC");
|
||||
} else {
|
||||
$result = mysqli_query($conn, "SELECT id, version, release_date, features, bugfixes FROM releases WHERE is_draft = 0 ORDER BY release_date DESC, id DESC");
|
||||
}
|
||||
|
||||
$releases = [];
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$row['features_list'] = array_filter(array_map('trim', explode("\n", $row['features'] ?? '')));
|
||||
$row['bugfixes_list'] = array_filter(array_map('trim', explode("\n", $row['bugfixes'] ?? '')));
|
||||
$releases[] = $row;
|
||||
}
|
||||
|
||||
$latest_published_version = null;
|
||||
foreach ($releases as $rel) {
|
||||
if (($rel['is_draft'] ?? 0) == 0) {
|
||||
$latest_published_version = $rel['version'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
require_once('inc/header.php');
|
||||
?>
|
||||
|
||||
<div class="container mt-5 mb-4">
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-<?= htmlspecialchars($message_type) ?> alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($message) ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<h2 class="mb-4">ℹ️ Info & Versionshinweise</h2>
|
||||
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-secondary bg-opacity-50 text-secondary d-flex justify-content-between align-items-center">
|
||||
<h4 class="mb-0">Release Notes</h4>
|
||||
<?php if ($is_admin): ?>
|
||||
<a class="btn btn-sm d-flex align-items-center justify-content-center" data-bs-toggle="collapse" href="#releaseFormCollapse" role="button" aria-expanded="false" aria-controls="releaseFormCollapse">Add
|
||||
<span class="material-symbols-outlined">add</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<?php if ($is_admin): ?>
|
||||
<div class="collapse <?= $edit_mode ? 'show' : '' ?>" id="releaseFormCollapse">
|
||||
<div class="card card-body bg-light mb-4">
|
||||
<h5><?= $edit_mode ? 'Version bearbeiten' : 'Neuen Entwurf anlegen'; ?></h5>
|
||||
<form method="POST">
|
||||
<?php if ($edit_mode): ?>
|
||||
<input type="hidden" name="id" value="<?= htmlspecialchars($edit_release['id']); ?>">
|
||||
<?php endif; ?>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Versionsnummer</label>
|
||||
<input type="text" class="form-control" name="version" value="<?= htmlspecialchars($edit_release['version'] ?? ''); ?>" placeholder="z. B. v1.5.0" required>
|
||||
<div class="form-text">Format: v1.4.2</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Veröffentlichungsdatum</label>
|
||||
<input type="date" class="form-control" name="date" value="<?= htmlspecialchars($edit_release['release_date'] ?? date('Y-m-d')); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Neue Features (ein Punkt pro Zeile)<br>
|
||||
<small class="text-muted">Verwende [b]fett[/b] oder [i]kursiv[/i] für Hervorhebungen.</small>
|
||||
</label>
|
||||
<textarea class="form-control" name="features" rows="4"><?= htmlspecialchars($edit_release['features'] ?? '') ?></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Behobene Fehler (ein Punkt pro Zeile)<br>
|
||||
<small class="text-muted">Verwende [b]fett[/b] oder [i]kursiv[/i] für Hervorhebungen.</small>
|
||||
</label>
|
||||
<textarea class="form-control" name="bugfixes" rows="4"><?= htmlspecialchars($edit_release['bugfixes'] ?? '') ?></textarea>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-sm btn-outline-<?= $edit_mode ? 'success' : 'primary'; ?>"><?= $edit_mode ? 'Speichern' : 'Entwurf speichern'; ?></button>
|
||||
<a href="version.php" class="btn btn-sm btn-outline-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($releases)): ?>
|
||||
<p class="text-muted">Keine veröffentlichten Release Notes vorhanden.</p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($releases as $release): ?>
|
||||
<div class="d-flex align-items-start">
|
||||
<div class="flex-grow-1">
|
||||
<h5 class="mt-4 mb-1">
|
||||
<?= htmlspecialchars($release['version']) ?>
|
||||
<?php if (($release['is_draft'] ?? 0) == 1): ?>
|
||||
<span class="badge bg-warning text-dark ms-1">Entwurf</span>
|
||||
<?php elseif ($release['version'] === $latest_published_version): ?>
|
||||
<span class="badge bg-success ms-1">aktuelle Version</span>
|
||||
<?php endif; ?>
|
||||
</h5>
|
||||
<p class="text-muted small mb-3">Veröffentlicht am: <?= date('d.m.Y', strtotime($release['release_date'])) ?></p>
|
||||
|
||||
<?php if (!empty($release['features_list'])): ?>
|
||||
<p class="small text-success mb-1"><strong>Neue Features:</strong></p>
|
||||
<ul class="mb-3">
|
||||
<?php foreach ($release['features_list'] as $f): ?>
|
||||
<li><?= parse_formatting($f) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($release['bugfixes_list'])): ?>
|
||||
<p class="small text-danger mb-1"><strong>Behobene Fehler:</strong></p>
|
||||
<ul class="mb-3">
|
||||
<?php foreach ($release['bugfixes_list'] as $b): ?>
|
||||
<li><?= parse_formatting($b) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($is_admin): ?>
|
||||
<div class="dropdown ms-3 mt-4">
|
||||
<a href="#" class="text-secondary" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<span class="material-icons">more_vert</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<?php if (($release['is_draft'] ?? 0) == 1): ?>
|
||||
<li>
|
||||
<a class="dropdown-item d-flex align-items-center text-success" href="version.php?action=publish&id=<?= $release['id'] ?>" onclick="return confirm('Wirklich veröffentlichen?')">
|
||||
<span class="material-icons me-2">check</span> Veröffentlichen
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<li>
|
||||
<a class="dropdown-item d-flex align-items-center" href="version.php?action=edit&id=<?= $release['id'] ?>">
|
||||
<span class="material-icons me-2">mode_edit_outline</span> Bearbeiten
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item d-flex align-items-center text-danger" href="version.php?action=delete&id=<?= $release['id'] ?>" onclick="return confirm('Wirklich löschen?')">
|
||||
<span class="material-icons me-2">delete_outline</span> Löschen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include('inc/footer.php'); ?>
|
||||
Reference in New Issue
Block a user