WebOrbiton
v1.0.0.6

Publisium

147 lines · 6.8 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. if (!Auth::hasRoleAtLeast(Auth::ROLE_EDITOR_IN_CHIEF)) {
  6. echo '<p>Only editors in chief can manage categories.</p>';
  7. return;
  8. }
  9. ​
  10. $db = Database::site();
  11. $categories = $db->query('SELECT * FROM categories ORDER BY sort_order ASC, name ASC')->fetchAll();
  12. foreach ($categories as &$category) {
  13. if (!array_key_exists('show_in_menu', $category)) {
  14. $category['show_in_menu'] = 1;
  15. }
  16. }
  17. unset($category);
  18. ​
  19. ?>
  20. <div class="dash-header-row">
  21. <h1 class="dash-title"><?= Icons::icon("categories", "icon icon-lg") ?>Categories</h1>
  22. <button type="button" class="dash-btn dash-btn-primary" id="category-new-btn"><?= Icons::icon('plus', 'icon icon-sm') ?>New category</button>
  23. </div>
  24. ​
  25. <table class="dash-table">
  26. <thead>
  27. <tr>
  28. <th><?= Icons::icon('heading', 'icon icon-sm') ?>Name</th>
  29. <th><?= Icons::icon('hash', 'icon icon-sm') ?>Web address</th>
  30. <th><?= Icons::icon('menu', 'icon icon-sm') ?>In menu</th>
  31. <th></th>
  32. </tr>
  33. </thead>
  34. <tbody>
  35. <?php foreach ($categories as $category): ?>
  36. <tr>
  37. <td><?= htmlspecialchars($category['name']) ?></td>
  38. <td><?= htmlspecialchars($category['slug']) ?></td>
  39. <td>
  40. <form method="post" style="display:inline;">
  41. <?= Csrf::field() ?>
  42. <input type="hidden" name="action" value="toggle_category_menu">
  43. <input type="hidden" name="category_id" value="<?= (int) $category['id'] ?>">
  44. <button type="submit" class="dash-btn-small"><?= Icons::icon($category['show_in_menu'] ? 'check' : 'x', 'icon icon-sm') ?><?= $category['show_in_menu'] ? 'Shown' : 'Hidden' ?></button>
  45. </form>
  46. </td>
  47. <td class="dash-table-actions">
  48. <button type="button" class="dash-btn-small js-edit-category"
  49. data-id="<?= (int) $category['id'] ?>"
  50. data-name="<?= htmlspecialchars($category['name'], ENT_QUOTES) ?>"
  51. data-description="<?= htmlspecialchars((string) $category['description'], ENT_QUOTES) ?>"
  52. data-parent="<?= (int) ($category['parent_id'] ?? 0) ?>"
  53. data-show-in-menu="<?= (int) $category['show_in_menu'] ?>"><?= Icons::icon('edit', 'icon icon-sm') ?>Edit</button>
  54. <?php if (Languages::enabled()): ?>
  55. <a href="translate.php?type=category&id=<?= (int) $category['id'] ?>" class="dash-btn-small"><?= Icons::icon('translate', 'icon icon-sm') ?>Translate</a>
  56. <?php endif; ?>
  57. <form method="post" style="display:inline;" onsubmit="return confirm('Delete this category? Its articles stay, they just won\'t have a category.');">
  58. <?= Csrf::field() ?>
  59. <input type="hidden" name="action" value="delete_category">
  60. <input type="hidden" name="category_id" value="<?= (int) $category['id'] ?>">
  61. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete</button>
  62. </form>
  63. </td>
  64. </tr>
  65. <?php endforeach; ?>
  66. <?php if (empty($categories)): ?>
  67. <tr>
  68. <td colspan="4">No categories yet. Add one to group your articles.</td>
  69. </tr>
  70. <?php endif; ?>
  71. </tbody>
  72. </table>
  73. ​
  74. <div id="category-form-wrapper" class="sidebar-box" style="max-width:520px;margin-top:20px;display:none;">
  75. <h2 class="dash-subtitle" style="margin-top:0;"><?= Icons::icon('plus', 'icon icon-sm') ?><span id="category-form-title">New category</span></h2>
  76. <form method="post" id="category-form">
  77. <?= Csrf::field() ?>
  78. <input type="hidden" name="action" value="save_category">
  79. <input type="hidden" name="category_id" id="category_id_input" value="">
  80. ​
  81. <label>Name</label>
  82. <input type="text" name="name" id="category_name_input" required>
  83. ​
  84. <label>Description</label>
  85. <textarea name="description" id="category_description_input" rows="2"></textarea>
  86. ​
  87. <label>Parent category</label>
  88. <select name="parent_id" id="category_parent_input">
  89. <option value="">None (top level)</option>
  90. <?php foreach ($categories as $category): ?>
  91. <option value="<?= (int) $category['id'] ?>"><?= htmlspecialchars($category['name']) ?></option>
  92. <?php endforeach; ?>
  93. </select>
  94. ​
  95. <label><input type="checkbox" name="show_in_menu" id="category_show_in_menu_input" checked> Show in site menu</label>
  96. ​
  97. <div class="publish-actions">
  98. <button type="submit" class="dash-btn dash-btn-primary"><?= Icons::icon('check', 'icon icon-sm') ?>Save category</button>
  99. <button type="button" class="dash-btn" id="category-cancel-btn"><?= Icons::icon('x', 'icon icon-sm') ?>Cancel</button>
  100. </div>
  101. </form>
  102. </div>
  103. ​
  104. <script>
  105. (function() {
  106. var wrapper = document.getElementById('category-form-wrapper');
  107. var formTitle = document.getElementById('category-form-title');
  108. var form = document.getElementById('category-form');
  109. ​
  110. function resetForm() {
  111. form.reset();
  112. document.getElementById('category_id_input').value = '';
  113. document.getElementById('category_show_in_menu_input').checked = true;
  114. formTitle.textContent = 'New category';
  115. }
  116. ​
  117. function showForm() {
  118. wrapper.style.display = '';
  119. wrapper.scrollIntoView({
  120. behavior: 'smooth',
  121. block: 'nearest'
  122. });
  123. }
  124. ​
  125. document.getElementById('category-new-btn').addEventListener('click', function() {
  126. resetForm();
  127. showForm();
  128. });
  129. ​
  130. document.getElementById('category-cancel-btn').addEventListener('click', function() {
  131. wrapper.style.display = 'none';
  132. resetForm();
  133. });
  134. ​
  135. document.querySelectorAll('.js-edit-category').forEach(function(button) {
  136. button.addEventListener('click', function() {
  137. document.getElementById('category_id_input').value = this.dataset.id;
  138. document.getElementById('category_name_input').value = this.dataset.name;
  139. document.getElementById('category_description_input').value = this.dataset.description;
  140. document.getElementById('category_parent_input').value = this.dataset.parent === '0' ? '' : this.dataset.parent;
  141. document.getElementById('category_show_in_menu_input').checked = this.dataset.showInMenu === '1';
  142. formTitle.textContent = 'Edit category';
  143. showForm();
  144. });
  145. });
  146. })();
  147. </script>