WebOrbiton
v1.0.0.6

Publisium

145 lines · 6.0 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. require_once __DIR__ . '/includes/config.php';
  6. require_once __DIR__ . '/includes/database.php';
  7. require_once __DIR__ . '/includes/auth.php';
  8. require_once __DIR__ . '/includes/csrf.php';
  9. require_once __DIR__ . '/includes/activity-log.php';
  10. ​
  11. Auth::boot();
  12. Auth::requireRoleAtLeast(Auth::ROLE_EDITOR_IN_CHIEF);
  13. ​
  14. $currentUser = Auth::user();
  15. $currentRole = Auth::role();
  16. $db = Database::site();
  17. $logEnabled = ActivityLog::isEnabled();
  18. ​
  19. $flashMessage = null;
  20. $flashType = 'success';
  21. ​
  22. if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'clear_activity_log') {
  23. if (!Csrf::verify($_POST['csrf_token'] ?? null)) {
  24. $flashMessage = 'Your session expired. Please try again.';
  25. $flashType = 'error';
  26. } else {
  27. $days = max(0, (int) ($_POST['older_than_days'] ?? 0));
  28. if ($days > 0) {
  29. $statement = $db->prepare('DELETE FROM activity_log WHERE created_at < DATE_SUB(NOW(), INTERVAL :days DAY)');
  30. $statement->bindValue('days', $days, PDO::PARAM_INT);
  31. $statement->execute();
  32. } else {
  33. $db->exec('DELETE FROM activity_log');
  34. }
  35. $flashMessage = 'Old entries cleared.';
  36. }
  37. }
  38. ​
  39. $perPage = 50;
  40. $page = max(1, (int) ($_GET['page'] ?? 1));
  41. $total = (int) $db->query('SELECT COUNT(*) FROM activity_log')->fetchColumn();
  42. $totalPages = max(1, (int) ceil($total / $perPage));
  43. $page = min($page, $totalPages);
  44. ​
  45. $statement = $db->prepare('SELECT * FROM activity_log ORDER BY id DESC LIMIT :limit OFFSET :offset');
  46. $statement->bindValue('limit', $perPage, PDO::PARAM_INT);
  47. $statement->bindValue('offset', ($page - 1) * $perPage, PDO::PARAM_INT);
  48. $statement->execute();
  49. $entries = $statement->fetchAll();
  50. ​
  51. $actionLabels = [
  52. 'account.delete' => 'Deleted an account',
  53. 'ads.save_ad' => 'Saved an ad',
  54. 'ads.delete_ad' => 'Deleted an ad',
  55. 'analytics.save_analytics_script' => 'Saved a tracking script',
  56. 'analytics.delete_analytics_script' => 'Deleted a tracking script',
  57. 'analytics.save_consent_settings' => 'Changed cookie consent settings',
  58. 'article.auto_publish' => 'Published on schedule',
  59. 'article.empty_trash' => 'Emptied the trash',
  60. 'article.moderate' => 'Reviewed an article',
  61. 'article.purge' => 'Deleted an article for good',
  62. 'article.restore' => 'Restored an article from the trash',
  63. 'article.restore_version' => 'Went back to an older version',
  64. 'article.save' => 'Saved an article',
  65. 'article.trash' => 'Moved an article to the trash',
  66. 'category.delete' => 'Deleted a category',
  67. 'category.save' => 'Saved a category',
  68. 'indexnow.skipped' => 'Search engine ping skipped',
  69. 'indexnow.submit' => 'Told search engines about a change',
  70. 'language.add' => 'Added a language',
  71. 'language.copy' => 'Copied texts to a language',
  72. 'language.delete' => 'Deleted a language',
  73. 'language.settings' => 'Changed language settings',
  74. 'language.site' => 'Translated site texts',
  75. 'language.site_copy' => 'Copied site texts to a language',
  76. 'language.strings' => 'Changed interface texts',
  77. 'language.toggle' => 'Turned a language on or off',
  78. 'page.delete' => 'Deleted a page',
  79. 'page.save' => 'Saved a page',
  80. 'settings.save' => 'Changed settings',
  81. 'translation.copy' => 'Copied a translation',
  82. 'translation.delete' => 'Removed a translation',
  83. 'translation.save' => 'Saved a translation',
  84. 'updater.auto_install' => 'Installed an update automatically',
  85. ];
  86. ​
  87. $dashActivePage = 'activity';
  88. $dashPageTitle = 'Activity log';
  89. ​
  90. require __DIR__ . '/includes/dash-header.php';
  91. ​
  92. ?>
  93. ​
  94. <?php if ($flashMessage !== null): ?>
  95. <div class="dash-flash dash-flash-<?= htmlspecialchars($flashType) ?>"><?= Icons::icon($flashType === 'error' ? 'x' : 'check', 'icon icon-sm') ?><?= htmlspecialchars($flashMessage) ?></div>
  96. <?php endif; ?>
  97. ​
  98. <h1 class="dash-title"><?= Icons::icon('stats', 'icon icon-lg') ?>Activity log</h1>
  99. ​
  100. <?php if (!$logEnabled): ?>
  101. <div class="dash-flash dash-flash-error"><?= Icons::icon('x', 'icon icon-sm') ?>The activity log is off, so nothing new is being recorded. You can turn it on in Settings → General.</div>
  102. <?php endif; ?>
  103. ​
  104. <table class="dash-table">
  105. <thead><tr><th>When</th><th>Who</th><th>What happened</th><th>Item</th><th>Details</th><th>IP</th></tr></thead>
  106. <tbody>
  107. <?php foreach ($entries as $entry): ?>
  108. <tr>
  109. <td><?= htmlspecialchars((string) $entry['created_at']) ?></td>
  110. <td><?= htmlspecialchars((string) $entry['user_name']) ?></td>
  111. <td><?= htmlspecialchars($actionLabels[(string) $entry['action']] ?? (string) $entry['action']) ?></td>
  112. <td><?= htmlspecialchars(trim(ucfirst((string) $entry['entity_type']) . ' ' . ($entry['entity_id'] !== null ? '#' . $entry['entity_id'] : ''))) ?></td>
  113. <td><?= htmlspecialchars((string) $entry['details']) ?></td>
  114. <td><?= htmlspecialchars((string) $entry['ip_address']) ?></td>
  115. </tr>
  116. <?php endforeach; ?>
  117. <?php if (empty($entries)): ?>
  118. <tr><td colspan="6">Nothing here yet. Changes made in the dashboard will show up here.</td></tr>
  119. <?php endif; ?>
  120. </tbody>
  121. </table>
  122. ​
  123. <?php if ($totalPages > 1): ?>
  124. <p style="margin-top:16px;display:flex;gap:12px;align-items:center;">
  125. <?php if ($page > 1): ?><a href="activity.php?page=<?= $page - 1 ?>" class="dash-btn-small">&larr; Newer</a><?php endif; ?>
  126. <span>Page <?= $page ?> of <?= $totalPages ?></span>
  127. <?php if ($page < $totalPages): ?><a href="activity.php?page=<?= $page + 1 ?>" class="dash-btn-small">Older &rarr;</a><?php endif; ?>
  128. </p>
  129. <?php endif; ?>
  130. ​
  131. <form method="post" style="margin-top:24px;" onsubmit="return confirm('Clear these entries from the log?');">
  132. <?= Csrf::field() ?>
  133. <input type="hidden" name="action" value="clear_activity_log">
  134. <label>Clear old entries</label>
  135. <select name="older_than_days">
  136. <option value="30">Older than 30 days</option>
  137. <option value="90">Older than 90 days</option>
  138. <option value="365">Older than 1 year</option>
  139. <option value="0">Everything</option>
  140. </select>
  141. <button type="submit" class="dash-btn dash-btn-danger" style="margin-top:12px;"><?= Icons::icon('trash', 'icon icon-sm') ?>Clear</button>
  142. </form>
  143. ​
  144. <?php require __DIR__ . '/includes/dash-footer.php'; ?>
  145. ​