WebOrbiton
v1.0.0.0

StocketBase

128 lines · 5.8 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_STORE_OWNER);
  13. ​
  14. $currentUser = Auth::user();
  15. $currentRole = Auth::role();
  16. $db = Database::site();
  17. ​
  18. $flashMessage = null;
  19. $flashType = 'success';
  20. ​
  21. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  22. if (!Csrf::verify($_POST['csrf_token'] ?? null)) {
  23. $flashMessage = 'Security check failed, please try again.';
  24. $flashType = 'error';
  25. } else {
  26. require __DIR__ . '/dashboard-actions/manage-analytics.php';
  27. ActivityLog::record('analytics.' . (string) ($_POST['action'] ?? ''));
  28. $flashMessage = 'Saved.';
  29. }
  30. }
  31. ​
  32. $editId = (int) ($_GET['edit'] ?? 0) ?: null;
  33. $editingScript = null;
  34. if ($editId !== null) {
  35. $statement = $db->prepare('SELECT * FROM analytics_scripts WHERE id = :id LIMIT 1');
  36. $statement->execute(['id' => $editId]);
  37. $editingScript = $statement->fetch() ?: null;
  38. }
  39. ​
  40. $scripts = $db->query('SELECT * FROM analytics_scripts ORDER BY created_at DESC')->fetchAll();
  41. ​
  42. $db->prepare('INSERT IGNORE INTO site_settings (setting_key, setting_value) VALUES (:key, :value)')
  43. ->execute(['key' => 'consent_footer_icon_enabled', 'value' => '0']);
  44. ​
  45. $consentSetting = $db->prepare('SELECT setting_value FROM site_settings WHERE setting_key = :key LIMIT 1');
  46. $consentSetting->execute(['key' => 'consent_manager_enabled']);
  47. $consentEnabled = ($consentSetting->fetch()['setting_value'] ?? '0') === '1';
  48. $consentSetting->execute(['key' => 'consent_footer_icon_enabled']);
  49. $consentFooterIconEnabled = ($consentSetting->fetch()['setting_value'] ?? '0') === '1';
  50. ​
  51. $dashActivePage = 'analytics';
  52. $dashPageTitle = 'Analytics';
  53. ​
  54. require __DIR__ . '/includes/dash-header.php';
  55. ​
  56. ?>
  57. ​
  58. <?php if ($flashMessage !== null): ?>
  59. <div class="dash-flash dash-flash-<?= htmlspecialchars($flashType) ?>"><?= Icons::icon($flashType === 'error' ? 'x' : 'check', 'icon icon-sm') ?><?= htmlspecialchars($flashMessage) ?></div>
  60. <?php endif; ?>
  61. ​
  62. <h1 class="dash-title"><?= Icons::icon("analytics", "icon icon-lg") ?>Analytics</h1>
  63. ​
  64. <div class="sidebar-box" style="max-width:640px;margin-bottom:24px;">
  65. <form method="post">
  66. <?= Csrf::field() ?>
  67. <input type="hidden" name="action" value="save_consent_settings">
  68. <label><input type="checkbox" name="consent_manager_enabled" <?= $consentEnabled ? 'checked' : '' ?>> Enable consent manager (controls whether consent-gated scripts run before the visitor accepts)</label>
  69. <label><input type="checkbox" name="consent_footer_icon_enabled" <?= $consentFooterIconEnabled ? 'checked' : '' ?>> Show cookie icon in footer (lets visitors reopen the consent manager)</label>
  70. <button type="submit" class="dash-btn dash-btn-primary" style="margin-top:12px;"><?= Icons::icon('check', 'icon icon-sm') ?>Save</button>
  71. </form>
  72. </div>
  73. ​
  74. <table class="dash-table">
  75. <thead><tr><th><?= Icons::icon('heading', 'icon icon-sm') ?>Name</th><th><?= Icons::icon('layout', 'icon icon-sm') ?>Placement</th><th><?= Icons::icon('shield', 'icon icon-sm') ?>Requires consent</th><th><?= Icons::icon('toggle', 'icon icon-sm') ?>Active</th><th></th></tr></thead>
  76. <tbody>
  77. <?php foreach ($scripts as $script): ?>
  78. <tr>
  79. <td><?= htmlspecialchars($script['name']) ?></td>
  80. <td><?= htmlspecialchars($script['placement']) ?></td>
  81. <td><?= $script['requires_consent'] ? 'Yes' : 'No' ?></td>
  82. <td><?= $script['is_active'] ? 'Yes' : 'No' ?></td>
  83. <td class="dash-table-actions">
  84. <a href="analytics.php?edit=<?= (int) $script['id'] ?>" class="dash-btn-small"><?= Icons::icon('edit', 'icon icon-sm') ?>Edit</a>
  85. <form method="post" style="display:inline;" onsubmit="return confirm('Delete this script?');">
  86. <?= Csrf::field() ?>
  87. <input type="hidden" name="action" value="delete_analytics_script">
  88. <input type="hidden" name="script_id" value="<?= (int) $script['id'] ?>">
  89. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete</button>
  90. </form>
  91. </td>
  92. </tr>
  93. <?php endforeach; ?>
  94. <?php if (empty($scripts)): ?>
  95. <tr><td colspan="5">No analytics scripts yet.</td></tr>
  96. <?php endif; ?>
  97. </tbody>
  98. </table>
  99. ​
  100. <h2 class="dash-subtitle"><?= Icons::icon('plus', 'icon icon-sm') ?><?= $editingScript ? 'Edit script' : 'New script' ?></h2>
  101. <form method="post">
  102. <?= Csrf::field() ?>
  103. <input type="hidden" name="action" value="save_analytics_script">
  104. <?php if ($editingScript): ?>
  105. <input type="hidden" name="script_id" value="<?= (int) $editingScript['id'] ?>">
  106. <?php endif; ?>
  107. ​
  108. <label>Name</label>
  109. <input type="text" name="name" value="<?= htmlspecialchars($editingScript['name'] ?? '') ?>" required>
  110. ​
  111. <label>Script code (raw HTML / &lt;style&gt; / &lt;script&gt;)</label>
  112. <textarea name="script_code" rows="8" class="be-code"><?= htmlspecialchars($editingScript['script_code'] ?? '') ?></textarea>
  113. ​
  114. <label>Placement</label>
  115. <select name="placement">
  116. <option value="head" <?= ($editingScript['placement'] ?? 'head') === 'head' ? 'selected' : '' ?>>&lt;head&gt;</option>
  117. <option value="body_start" <?= ($editingScript['placement'] ?? '') === 'body_start' ? 'selected' : '' ?>>Start of &lt;body&gt;</option>
  118. <option value="body_end" <?= ($editingScript['placement'] ?? '') === 'body_end' ? 'selected' : '' ?>>End of &lt;body&gt;</option>
  119. </select>
  120. ​
  121. <label><input type="checkbox" name="requires_consent" <?= ($editingScript['requires_consent'] ?? 1) ? 'checked' : '' ?>> Requires visitor consent before running</label>
  122. <label><input type="checkbox" name="is_active" <?= ($editingScript['is_active'] ?? 1) ? 'checked' : '' ?>> Active</label>
  123. ​
  124. <button type="submit" class="dash-btn dash-btn-primary" style="margin-top:16px;"><?= Icons::icon('check', 'icon icon-sm') ?>Save script</button>
  125. </form>
  126. ​
  127. <?php require __DIR__ . '/includes/dash-footer.php'; ?>
  128. ​