index.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. declare(strict_types=1);
  3. require_once __DIR__ . "/../includes/auth.php";
  4. require_once __DIR__ . "/../includes/layout.php";
  5. require_once __DIR__ . "/../includes/instances.php";
  6. require_once __DIR__ . "/../includes/releases.php";
  7. require_once __DIR__ . "/../includes/backups.php";
  8. manageRequireLogin();
  9. $messages = [];
  10. $errors = [];
  11. $instances = [];
  12. $latest = "";
  13. $releaseCount = 0;
  14. try {
  15. $instances = manageInstanceList();
  16. $latest = manageReleaseLatestVersion();
  17. $releaseCount = count(manageReleaseReadManifest()["releases"]);
  18. } catch (Throwable $exception) {
  19. $errors[] = $exception->getMessage();
  20. }
  21. if (trim((string) MANAGE_PUBLIC_URL) === "") {
  22. $errors[] = "MANAGE_PUBLIC_URL ist nicht gesetzt. Clients können ohne diesen Wert kein Paket herunterladen.";
  23. }
  24. if (!managePasswordConfigured()) {
  25. $errors[] = "Es ist kein Admin-Passwort konfiguriert.";
  26. }
  27. // An instance is "stale" when it has not been seen for a week. Cheap signal
  28. // that a cron job died or the instance was decommissioned without being removed.
  29. function manageDashboardIsStale(string $lastSeenAt): bool
  30. {
  31. if ($lastSeenAt === "") {
  32. return true;
  33. }
  34. $timestamp = strtotime($lastSeenAt);
  35. return $timestamp === false || time() - $timestamp > 604800;
  36. }
  37. function manageDashboardUpdateState(array $instance, string $latest): string
  38. {
  39. if ($latest === "" || $instance["version"] === "") {
  40. return "unbekannt";
  41. }
  42. if (version_compare(ltrim($latest, "vV"), ltrim($instance["version"], "vV"), ">")) {
  43. return "Update verfügbar";
  44. }
  45. return "aktuell";
  46. }
  47. manageRenderHeader("Übersicht", $messages, $errors);
  48. ?>
  49. <section class="cards">
  50. <div class="card">
  51. <p class="card-label">Produkt</p>
  52. <p class="card-value"><?php echo manageEscape(manageProductName()); ?></p>
  53. </div>
  54. <div class="card">
  55. <p class="card-label">Aktuelles Release</p>
  56. <p class="card-value"><?php echo manageEscape($latest !== "" ? $latest : "keines"); ?></p>
  57. <p class="card-hint"><?php echo (int) $releaseCount; ?> Release(s) im Manifest</p>
  58. </div>
  59. <div class="card">
  60. <p class="card-label">Instanzen</p>
  61. <p class="card-value"><?php echo count($instances); ?></p>
  62. <p class="card-hint"><a href="instances.php">verwalten</a></p>
  63. </div>
  64. <div class="card">
  65. <p class="card-label">S3-Archiv</p>
  66. <p class="card-value"><?php echo manageS3Enabled() ? "aktiv" : "aus"; ?></p>
  67. <p class="card-hint"><a href="settings.php">Einstellungen</a></p>
  68. </div>
  69. </section>
  70. <h2>Instanzen</h2>
  71. <?php if ($instances === []): ?>
  72. <p class="empty">Noch keine Instanz registriert. <a href="instances.php">Jetzt anlegen</a> – dabei wird das
  73. Token erzeugt, das in die <code>config.php</code> des Clients gehört.</p>
  74. <?php else: ?>
  75. <div class="table-scroll">
  76. <table class="data-table">
  77. <thead>
  78. <tr>
  79. <th>Instanz</th>
  80. <th>Status</th>
  81. <th>Version</th>
  82. <th>Update</th>
  83. <th>Zuletzt gesehen</th>
  84. <th>Letztes Backup</th>
  85. <th>Backups</th>
  86. <th>Migrationen</th>
  87. </tr>
  88. </thead>
  89. <tbody>
  90. <?php foreach ($instances as $instance): ?>
  91. <?php
  92. $stale = manageDashboardIsStale($instance["last_seen_at"]);
  93. $updateState = manageDashboardUpdateState($instance, $latest);
  94. ?>
  95. <tr>
  96. <td>
  97. <strong><?php echo manageEscape($instance["id"]); ?></strong>
  98. <?php if ($instance["label"] !== ""): ?>
  99. <br><span class="muted"><?php echo manageEscape($instance["label"]); ?></span>
  100. <?php endif; ?>
  101. </td>
  102. <td>
  103. <?php if (!$instance["enabled"]): ?>
  104. <span class="badge badge-error">deaktiviert</span>
  105. <?php elseif ($stale): ?>
  106. <span class="badge badge-warn">inaktiv</span>
  107. <?php else: ?>
  108. <span class="badge badge-ok">aktiv</span>
  109. <?php endif; ?>
  110. </td>
  111. <td><?php echo manageEscape($instance["version"] !== "" ? $instance["version"] : "–"); ?></td>
  112. <td>
  113. <?php if ($updateState === "Update verfügbar"): ?>
  114. <span class="badge badge-warn">Update verfügbar</span>
  115. <?php else: ?>
  116. <?php echo manageEscape($updateState); ?>
  117. <?php endif; ?>
  118. </td>
  119. <td><?php echo manageEscape($instance["last_seen_at"] !== "" ? $instance["last_seen_at"] : "nie"); ?></td>
  120. <td><?php echo manageEscape($instance["last_backup_at"] !== "" ? $instance["last_backup_at"] : "nie"); ?></td>
  121. <td><a href="backups.php#<?php echo manageEscape($instance["id"]); ?>"><?php echo (int) $instance["backup_count"]; ?></a></td>
  122. <td>
  123. <?php if ($instance["pending_migrations"] > 0): ?>
  124. <span class="badge badge-error"><?php echo (int) $instance["pending_migrations"]; ?> offen</span>
  125. <?php else: ?>
  126. –
  127. <?php endif; ?>
  128. </td>
  129. </tr>
  130. <?php endforeach; ?>
  131. </tbody>
  132. </table>
  133. </div>
  134. <?php endif; ?>
  135. <h2>Client-Paket</h2>
  136. <p>
  137. Jedes Projekt erhält den Ordner <code>client-package/</code> aus diesem Repository: er enthält den
  138. einzukopierenden Client-Code <em>und</em> die vollständige Integrationsdokumentation.
  139. </p>
  140. <p>
  141. Verteilbares ZIP erzeugen: <code>scripts/build-client-package.sh</code> –
  142. das Ergebnis liegt danach unter <code>build/</code>.
  143. </p>
  144. <?php manageRenderFooter(); ?>