|
|
@@ -2,79 +2,7 @@
|
|
|
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,
|
|
|
- ];
|
|
|
-}
|
|
|
+require_once __DIR__ . "/../manage-client/lib/client.php";
|
|
|
|
|
|
function settingsFormatBackupDate(string $date): string
|
|
|
{
|
|
|
@@ -86,43 +14,6 @@ function settingsFormatBackupDate(string $date): string
|
|
|
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 settingsIsSuperAdmin(): bool
|
|
|
{
|
|
|
return normalizeAdminUsername($_SESSION['admin_username'] ?? "") === "admin";
|
|
|
@@ -190,47 +81,6 @@ function settingsWriteLocalConfig(string $content): void
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-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();
|
|
|
@@ -264,41 +114,6 @@ if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['save_settings'])) {
|
|
|
$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";
|
|
|
- }
|
|
|
- }
|
|
|
} elseif ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['save_local_config'])) {
|
|
|
if (!$isSuperAdmin) {
|
|
|
http_response_code(403);
|
|
|
@@ -567,9 +382,7 @@ if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['save_settings'])) {
|
|
|
}
|
|
|
|
|
|
$settings = getSystemSettings();
|
|
|
-$updaterStatus = settingsGetUpdaterStatus();
|
|
|
-$backupCapabilities = backupRemoteCapabilities();
|
|
|
-$backups = backupListBackups();
|
|
|
+$manageStatus = manageClientStatus();
|
|
|
$localConfigContent = $isSuperAdmin ? settingsReadLocalConfig() : "";
|
|
|
|
|
|
$categories = getCategories();
|
|
|
@@ -855,66 +668,31 @@ include __DIR__ . "/../includes/header.php";
|
|
|
</form>
|
|
|
</div>
|
|
|
|
|
|
-<div class="panel panel-lg mt-4" id="backups">
|
|
|
- <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>
|
|
|
+<div class="panel panel-lg mt-4" id="update-backup">
|
|
|
+ <h3>Update & Backup</h3>
|
|
|
+ <p>Installierte Version: <?php echo escape($manageStatus["version"] !== "" ? $manageStatus["version"] : "unbekannt"); ?></p>
|
|
|
+ <?php if (!$manageStatus["configured"]): ?>
|
|
|
+ <p>Der Manage-Client ist nicht konfiguriert. <code>manage-client/config.php</code> fehlt oder ist unvollständig.</p>
|
|
|
+ <?php elseif ($manageStatus["update"] !== null && $manageStatus["update"]["available"]): ?>
|
|
|
+ <p>Update verfügbar: <?php echo escape($manageStatus["update"]["latest"]); ?></p>
|
|
|
+ <?php elseif ($manageStatus["update"] !== null): ?>
|
|
|
+ <p>Kein Update verfügbar.</p>
|
|
|
+ <?php else: ?>
|
|
|
+ <p>Update-Status konnte nicht geladen werden<?php echo $manageStatus["update_error"] !== null
|
|
|
+ ? ": " . escape($manageStatus["update_error"])
|
|
|
+ : "."; ?></p>
|
|
|
+ <?php endif; ?>
|
|
|
<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"])); ?>
|
|
|
+ Letztes Backup:
|
|
|
+ <?php echo $manageStatus["last_backup_at"] !== null
|
|
|
+ ? escape(settingsFormatBackupDate($manageStatus["last_backup_at"]))
|
|
|
+ : "noch keines"; ?>
|
|
|
+ (<?php echo count($manageStatus["backups"]); ?> lokal)
|
|
|
</p>
|
|
|
-
|
|
|
- <form method="POST" action="settings.php#backups" 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" action="settings.php#backups" 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 if ($manageStatus["pending_migrations"] !== []): ?>
|
|
|
+ <p><?php echo count($manageStatus["pending_migrations"]); ?> offene Migration(en).</p>
|
|
|
<?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>
|
|
|
+ <p><a href="manage.php" class="btn btn-secondary">Update & Backup öffnen</a></p>
|
|
|
</div>
|
|
|
|
|
|
<?php if ($isSuperAdmin): ?>
|