WebOrbiton
v1.0.0.0

StocketBase

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