| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- <?php
- require_once __DIR__ . "/../config.php";
- require_once __DIR__ . "/../includes/functions.php";
- require_once __DIR__ . "/../includes/version.php";
- require_once __DIR__ . "/../includes/backup.php";
- if (!defined("UPDATE_MANIFEST_URL")) {
- define("UPDATE_MANIFEST_URL", "");
- }
- function settingsUpdaterVersionCompareValue(string $version): string
- {
- return ltrim(trim($version), "vV");
- }
- function settingsGetUpdaterStatus(): array
- {
- $manifestUrl = trim((string) UPDATE_MANIFEST_URL);
- if ($manifestUrl === "") {
- return [
- "label" => "Update-Ziel ist nicht konfiguriert.",
- "available" => false,
- "version" => "",
- ];
- }
- $context = stream_context_create([
- "http" => [
- "method" => "GET",
- "timeout" => 3,
- "ignore_errors" => true,
- "header" => "User-Agent: PSA-Orderform-Settings/" . APP_VERSION . "\r\n",
- ],
- ]);
- $body = @file_get_contents($manifestUrl, false, $context);
- if ($body === false) {
- return [
- "label" => "Update-Status konnte nicht geladen werden.",
- "available" => false,
- "version" => "",
- ];
- }
- $manifest = json_decode($body, true);
- if (!is_array($manifest)) {
- return [
- "label" => "Update-Status ist ungültig.",
- "available" => false,
- "version" => "",
- ];
- }
- $version = trim((string) ($manifest["version"] ?? $manifest["latest"] ?? ""));
- if (!preg_match('/^v\d+\.\d+\.\d+$/', $version)) {
- return [
- "label" => "Update-Version ist ungültig.",
- "available" => false,
- "version" => "",
- ];
- }
- $available =
- version_compare(
- settingsUpdaterVersionCompareValue($version),
- settingsUpdaterVersionCompareValue(APP_VERSION),
- ">",
- );
- return [
- "label" => $available
- ? "Update verfügbar: " . $version
- : "Kein Update verfügbar.",
- "available" => $available,
- "version" => $version,
- ];
- }
- function settingsFormatBackupDate(string $date): string
- {
- $timestamp = strtotime($date);
- if ($timestamp === false) {
- return $date;
- }
- return date("d.m.Y H:i", $timestamp);
- }
- function settingsGetBackupUploadLabel(array $backup): string
- {
- $uploads =
- isset($backup["remote_uploads"]) && is_array($backup["remote_uploads"])
- ? $backup["remote_uploads"]
- : [];
- if (empty($uploads)) {
- return "Nur lokal";
- }
- $successful = 0;
- foreach ($uploads as $upload) {
- if (is_array($upload) && !empty($upload["success"])) {
- $successful++;
- }
- }
- if ($successful === count($uploads)) {
- return "Remote erfolgreich (" . $successful . ")";
- }
- if ($successful > 0) {
- return "Teilweise erfolgreich (" . $successful . "/" . count($uploads) . ")";
- }
- return "Remote fehlgeschlagen";
- }
- function settingsGetBackupCapabilityLabel(array $capability): string
- {
- if (empty($capability["configured"])) {
- return "nicht konfiguriert";
- }
- return !empty($capability["available"]) ? "bereit" : "nicht verfügbar";
- }
- function settingsFindBackupByFilename(string $filename): ?array
- {
- if ($filename === "" || basename($filename) !== $filename) {
- return null;
- }
- foreach (backupListBackups() as $backup) {
- if (($backup["filename"] ?? "") === $filename) {
- return $backup;
- }
- }
- return null;
- }
- function settingsSendBackupDownload(array $backup): void
- {
- $filename = basename((string) ($backup["filename"] ?? ""));
- $path = backupGetDirectory() . $filename;
- if ($filename === "" || !is_file($path) || !is_readable($path)) {
- throw new RuntimeException("Backup-Datei wurde nicht gefunden.");
- }
- $size = filesize($path);
- if ($size === false) {
- throw new RuntimeException("Backup-Dateigröße konnte nicht gelesen werden.");
- }
- logAccess("Backup downloaded", [
- "filename" => $filename,
- ]);
- header("Content-Type: application/zip");
- header('Content-Disposition: attachment; filename="' . $filename . '"');
- header("Content-Length: " . (string) $size);
- header("X-Content-Type-Options: nosniff");
- readfile($path);
- exit();
- }
- if (empty($_SESSION['admin_logged_in'])) {
- header("Location: login.php");
- exit();
- }
- $pageTitle = "Einstellungen";
- $message = "";
- $messageType = "";
- if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['save_settings'])) {
- // Validate CSRF token
- if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
- $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
- $messageType = "error";
- } else {
- $settings = array_merge(getSystemSettings(), [
- "order_recipient_email" => $_POST['order_recipient_email'] ?? "",
- "attach_order_pdf_to_admin_email" => isset(
- $_POST['attach_order_pdf_to_admin_email'],
- ),
- "nametag_product_name" => $_POST['nametag_product_name'] ?? "",
- ]);
- if (saveSystemSettings($settings)) {
- logAccess("Admin updated system settings");
- $message = "Einstellungen wurden gespeichert.";
- $messageType = "success";
- } else {
- $message = "Einstellungen konnten nicht gespeichert werden.";
- $messageType = "error";
- }
- }
- } elseif ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['create_backup'])) {
- if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
- $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
- $messageType = "error";
- } else {
- try {
- $backup = backupCreate("manual");
- $message =
- "Backup wurde erstellt: " .
- $backup["filename"] .
- " (" .
- backupFormatBytes((int) $backup["size"]) .
- ").";
- $messageType = "success";
- } catch (Throwable $exception) {
- $message = "Backup konnte nicht erstellt werden: " . $exception->getMessage();
- $messageType = "error";
- }
- }
- } elseif ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['download_backup'])) {
- if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
- $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
- $messageType = "error";
- } else {
- try {
- $backup = settingsFindBackupByFilename((string) ($_POST["backup_filename"] ?? ""));
- if ($backup === null) {
- throw new RuntimeException("Backup wurde nicht gefunden.");
- }
- settingsSendBackupDownload($backup);
- } catch (Throwable $exception) {
- $message = "Backup konnte nicht heruntergeladen werden: " . $exception->getMessage();
- $messageType = "error";
- }
- }
- }
- $settings = getSystemSettings();
- $updaterStatus = settingsGetUpdaterStatus();
- $backupCapabilities = backupRemoteCapabilities();
- $backups = backupListBackups();
- $bodyClass = "admin-page";
- include __DIR__ . "/../includes/header.php";
- ?>
- <div class="admin-header">
- <h2>Einstellungen</h2>
- <div>
- <a href="index.php" class="btn btn-secondary">Zurück zum Dashboard</a>
- </div>
- </div>
- <?php if ($message !== ""): ?>
- <div class="alert alert-<?php echo escape($messageType); ?>">
- <?php echo escape($message); ?>
- </div>
- <?php endif; ?>
- <div class="panel panel-lg">
- <form method="POST">
- <?php echo csrfField(); ?>
- <div class="form-group">
- <label for="order_recipient_email">Empfängeradresse für interne Bestellungen *</label>
- <input type="email" id="order_recipient_email" name="order_recipient_email" required value="<?php echo escape(
- $settings["order_recipient_email"],
- ); ?>">
- </div>
- <div class="form-group">
- <label class="checkbox-label">
- <input type="checkbox" name="attach_order_pdf_to_admin_email" value="1" <?php echo !empty(
- $settings["attach_order_pdf_to_admin_email"]
- )
- ? "checked"
- : ""; ?>>
- PDF an interne Bestell-E-Mails anhängen
- </label>
- </div>
- <div class="form-group">
- <label for="nametag_product_name">Artikelname für Namensschilder *</label>
- <input type="text" id="nametag_product_name" name="nametag_product_name" required value="<?php echo escape(
- $settings["nametag_product_name"],
- ); ?>">
- <small>Muss exakt dem Produktnamen im Katalog entsprechen. Wird von der Namensschilder-Übersicht verwendet.</small>
- </div>
- <button type="submit" name="save_settings" class="btn">Speichern</button>
- </form>
- </div>
- <div class="panel panel-lg mt-4">
- <h3>Backups</h3>
- <p>Lokale Aufbewahrung: <?php echo (int) backupGetRetentionLimit(); ?> Backups</p>
- <p>Automatisches Intervall: <?php echo (int) floor(((int) BACKUP_AUTO_INTERVAL_SECONDS) / 86400); ?> Tage</p>
- <p>
- S3: <?php echo escape(settingsGetBackupCapabilityLabel($backupCapabilities["s3"])); ?> ·
- SFTP: <?php echo escape(settingsGetBackupCapabilityLabel($backupCapabilities["sftp"])); ?> ·
- Custom: <?php echo escape(settingsGetBackupCapabilityLabel($backupCapabilities["custom"])); ?> ·
- Managed: <?php echo escape(settingsGetBackupCapabilityLabel($backupCapabilities["managed"])); ?>
- </p>
- <form method="POST" class="inline-form">
- <?php echo csrfField(); ?>
- <button type="submit" name="create_backup" class="btn">Backup erstellen</button>
- </form>
- <h4 class="mt-4">Letzte Backups</h4>
- <?php if (empty($backups)): ?>
- <p>Es wurden noch keine Backups erstellt.</p>
- <?php else: ?>
- <div class="table-responsive">
- <table class="responsive-table">
- <thead>
- <tr>
- <th>Erstellt</th>
- <th>Auslöser</th>
- <th>Größe</th>
- <th>Dateien</th>
- <th>Remote</th>
- <th>Aktionen</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($backups as $backup): ?>
- <tr>
- <td data-label="Erstellt"><?php echo escape(settingsFormatBackupDate((string) ($backup["created_at"] ?? ""))); ?></td>
- <td data-label="Auslöser"><?php echo (($backup["trigger"] ?? "") === "automatic") ? "Automatisch" : "Manuell"; ?></td>
- <td data-label="Größe"><?php echo escape(backupFormatBytes((int) ($backup["size"] ?? 0))); ?></td>
- <td data-label="Dateien"><?php echo (int) ($backup["file_count"] ?? 0); ?></td>
- <td data-label="Remote"><?php echo escape(settingsGetBackupUploadLabel($backup)); ?></td>
- <td data-label="Aktionen">
- <form method="POST" class="inline-form">
- <?php echo csrfField(); ?>
- <input type="hidden" name="backup_filename" value="<?php echo escape($backup["filename"] ?? ""); ?>">
- <button type="submit" name="download_backup" class="btn btn-secondary btn-small">Download</button>
- </form>
- </td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- </div>
- <?php endif; ?>
- </div>
- <div class="panel panel-lg mt-4">
- <h3>Updater</h3>
- <p>Installierte Version: <?php echo escape(APP_VERSION); ?></p>
- <p>Update-Status: <?php echo escape($updaterStatus["label"]); ?></p>
- <p><a href="updater.php" class="btn btn-secondary">Updater öffnen</a></p>
- </div>
- <?php include __DIR__ . "/../includes/footer.php"; ?>
|