WebOrbiton
v2.0.0.0

Publisium

156 lines · 7.9 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. require_once __DIR__ . '/includes/site-front.php';
  11. ​
  12. Auth::boot();
  13. Auth::requireRoleAtLeast(Auth::ROLE_EDITOR_IN_CHIEF);
  14. ​
  15. $currentUser = Auth::user();
  16. $currentRole = Auth::role();
  17. $db = Database::site();
  18. ​
  19. $flashMessage = null;
  20. $flashType = 'success';
  21. ​
  22. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  23. if (!Csrf::verify($_POST['csrf_token'] ?? null)) {
  24. $flashMessage = 'Your session expired. Please try again.';
  25. $flashType = 'error';
  26. } else {
  27. require __DIR__ . '/dashboard-actions/manage-analytics.php';
  28. ActivityLog::record('analytics.' . (string) ($_POST['action'] ?? ''));
  29. $flashMessage = 'Saved.';
  30. }
  31. }
  32. ​
  33. $editId = (int) ($_GET['edit'] ?? 0) ?: null;
  34. $editingScript = null;
  35. if ($editId !== null) {
  36. $statement = $db->prepare('SELECT * FROM analytics_scripts WHERE id = :id LIMIT 1');
  37. $statement->execute(['id' => $editId]);
  38. $editingScript = $statement->fetch() ?: null;
  39. }
  40. ​
  41. $scripts = $db->query('SELECT * FROM analytics_scripts ORDER BY created_at DESC')->fetchAll();
  42. ​
  43. $db->prepare('INSERT IGNORE INTO site_settings (setting_key, setting_value) VALUES (:key, :value)')
  44. ->execute(['key' => 'consent_footer_icon_enabled', 'value' => '0']);
  45. ​
  46. $consentSetting = $db->prepare('SELECT setting_value FROM site_settings WHERE setting_key = :key LIMIT 1');
  47. $consentSetting->execute(['key' => 'consent_manager_enabled']);
  48. $consentEnabled = ($consentSetting->fetch()['setting_value'] ?? '0') === '1';
  49. $consentSetting->execute(['key' => 'consent_footer_icon_enabled']);
  50. $consentFooterIconEnabled = ($consentSetting->fetch()['setting_value'] ?? '0') === '1';
  51. SiteFront::resetSettings();
  52. $bannerSettings = SiteFront::settings();
  53. $bannerCategories = SiteFront::consentCategories();
  54. ​
  55. $dashActivePage = 'analytics';
  56. $dashPageTitle = 'Analytics';
  57. ​
  58. require __DIR__ . '/includes/dash-header.php';
  59. ​
  60. ?>
  61. ​
  62. <?php if ($flashMessage !== null): ?>
  63. <div class="dash-flash dash-flash-<?= htmlspecialchars($flashType) ?>"><?= Icons::icon($flashType === 'error' ? 'x' : 'check', 'icon icon-sm') ?><?= htmlspecialchars($flashMessage) ?></div>
  64. <?php endif; ?>
  65. ​
  66. <h1 class="dash-title"><?= Icons::icon("analytics", "icon icon-lg") ?>Analytics</h1>
  67. ​
  68. <div class="sidebar-box" style="max-width:640px;margin-bottom:24px;">
  69. <form method="post">
  70. <?= Csrf::field() ?>
  71. <input type="hidden" name="action" value="save_consent_settings">
  72. <label><input type="checkbox" name="consent_manager_enabled" <?= $consentEnabled ? 'checked' : '' ?>> Ask visitors for cookie consent (scripts that need consent wait until they accept)</label>
  73. <label><input type="checkbox" name="consent_footer_icon_enabled" <?= $consentFooterIconEnabled ? 'checked' : '' ?>> Show a cookie icon in the footer so visitors can change their choice later</label>
  74. <?php foreach (['analytics' => 'Analytics', 'marketing' => 'Marketing'] as $bannerCategory => $bannerLabel): ?>
  75. <label><?= $bannerLabel ?> in the cookie banner</label>
  76. <select name="consent_show_<?= $bannerCategory ?>">
  77. <?php foreach (SiteFront::CONSENT_SHOW as $showKey => $showLabel): ?>
  78. <option value="<?= $showKey ?>" <?= ($bannerSettings['consent_show_' . $bannerCategory] ?? 'auto') === $showKey ? 'selected' : '' ?>><?= htmlspecialchars($showLabel) ?></option>
  79. <?php endforeach; ?>
  80. </select>
  81. <?php endforeach; ?>
  82. <p class="consent-status" style="font-size:13px;color:var(--muted);margin:12px 0 0;">
  83. <?php if (!$consentEnabled): ?>
  84. Cookie consent is off, so no banner is shown and all scripts run right away.
  85. <?php elseif ($bannerCategories === []): ?>
  86. Nothing on the site needs consent right now, so the banner and the cookie icon are hidden.
  87. <?php else: ?>
  88. Right now the banner asks about: <strong><?= htmlspecialchars(implode(', ', array_map('ucfirst', $bannerCategories))) ?></strong>.
  89. <?php endif; ?>
  90. </p>
  91. <button type="submit" class="dash-btn dash-btn-primary" style="margin-top:12px;"><?= Icons::icon('check', 'icon icon-sm') ?>Save</button>
  92. </form>
  93. </div>
  94. ​
  95. <table class="dash-table">
  96. <thead><tr><th><?= Icons::icon('heading', 'icon icon-sm') ?>Name</th><th><?= Icons::icon('layout', 'icon icon-sm') ?>Where</th><th><?= Icons::icon('shield', 'icon icon-sm') ?>Needs consent</th><th><?= Icons::icon('toggle', 'icon icon-sm') ?>Active</th><th></th></tr></thead>
  97. <tbody>
  98. <?php foreach ($scripts as $script): ?>
  99. <tr>
  100. <td><?= htmlspecialchars($script['name']) ?></td>
  101. <td><?= htmlspecialchars(['head' => 'In the head', 'body_start' => 'Start of the page', 'body_end' => 'End of the page'][$script['placement']] ?? $script['placement']) ?></td>
  102. <td><?= !$script['requires_consent'] ? 'No' : (['marketing' => 'Marketing', 'both' => 'Analytics and marketing'][$script['consent_category'] ?? 'analytics'] ?? 'Analytics') ?></td>
  103. <td><?= $script['is_active'] ? 'Yes' : 'No' ?></td>
  104. <td class="dash-table-actions">
  105. <a href="analytics.php?edit=<?= (int) $script['id'] ?>" class="dash-btn-small"><?= Icons::icon('edit', 'icon icon-sm') ?>Edit</a>
  106. <form method="post" style="display:inline;" onsubmit="return confirm('Delete this script? It stops running on the site right away.');">
  107. <?= Csrf::field() ?>
  108. <input type="hidden" name="action" value="delete_analytics_script">
  109. <input type="hidden" name="script_id" value="<?= (int) $script['id'] ?>">
  110. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete</button>
  111. </form>
  112. </td>
  113. </tr>
  114. <?php endforeach; ?>
  115. <?php if (empty($scripts)): ?>
  116. <tr><td colspan="5">No tracking scripts yet. Add one below, for example Google Analytics.</td></tr>
  117. <?php endif; ?>
  118. </tbody>
  119. </table>
  120. ​
  121. <h2 class="dash-subtitle"><?= Icons::icon('plus', 'icon icon-sm') ?><?= $editingScript ? 'Edit script' : 'New script' ?></h2>
  122. <form method="post">
  123. <?= Csrf::field() ?>
  124. <input type="hidden" name="action" value="save_analytics_script">
  125. <?php if ($editingScript): ?>
  126. <input type="hidden" name="script_id" value="<?= (int) $editingScript['id'] ?>">
  127. <?php endif; ?>
  128. ​
  129. <label>Name</label>
  130. <input type="text" name="name" value="<?= htmlspecialchars($editingScript['name'] ?? '') ?>" required>
  131. ​
  132. <label>Code (paste it exactly as your analytics service gives it to you)</label>
  133. <textarea name="script_code" rows="8" class="be-code"><?= htmlspecialchars($editingScript['script_code'] ?? '') ?></textarea>
  134. ​
  135. <label>Where to add it</label>
  136. <select name="placement">
  137. <option value="head" <?= ($editingScript['placement'] ?? 'head') === 'head' ? 'selected' : '' ?>>In the head (most tools ask for this)</option>
  138. <option value="body_start" <?= ($editingScript['placement'] ?? '') === 'body_start' ? 'selected' : '' ?>>Start of the page</option>
  139. <option value="body_end" <?= ($editingScript['placement'] ?? '') === 'body_end' ? 'selected' : '' ?>>End of the page</option>
  140. </select>
  141. ​
  142. <?php $consentValue = !($editingScript['requires_consent'] ?? 1) ? 'none' : (in_array($editingScript['consent_category'] ?? 'analytics', ['marketing', 'both'], true) ? $editingScript['consent_category'] : 'analytics'); ?>
  143. <label>Cookie consent</label>
  144. <select name="consent">
  145. <option value="analytics" <?= $consentValue === 'analytics' ? 'selected' : '' ?>>Run only after the visitor allows analytics</option>
  146. <option value="marketing" <?= $consentValue === 'marketing' ? 'selected' : '' ?>>Run only after the visitor allows marketing</option>
  147. <option value="both" <?= $consentValue === 'both' ? 'selected' : '' ?>>Run only after the visitor allows both analytics and marketing</option>
  148. <option value="none" <?= $consentValue === 'none' ? 'selected' : '' ?>>Always run (only for code that doesn’t track anyone)</option>
  149. </select>
  150. <label><input type="checkbox" name="is_active" <?= ($editingScript['is_active'] ?? 1) ? 'checked' : '' ?>> Active</label>
  151. ​
  152. <button type="submit" class="dash-btn dash-btn-primary" style="margin-top:16px;"><?= Icons::icon('check', 'icon icon-sm') ?>Save script</button>
  153. </form>
  154. ​
  155. <?php require __DIR__ . '/includes/dash-footer.php'; ?>
  156. ​