categories.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. require_once __DIR__ . "/../config.php";
  3. require_once __DIR__ . "/../includes/functions.php";
  4. // Check admin login
  5. if (!isset($_SESSION["admin_logged_in"]) || !$_SESSION["admin_logged_in"]) {
  6. header("Location: login.php");
  7. exit();
  8. }
  9. $pageTitle = "Kategorien verwalten";
  10. $message = "";
  11. $messageType = "";
  12. $categories = getCategories();
  13. $products = getProducts();
  14. if ($_SERVER["REQUEST_METHOD"] === "POST") {
  15. // Validate CSRF token
  16. if (!validateCsrfToken($_POST["csrf_token"] ?? "")) {
  17. $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
  18. $messageType = "error";
  19. } else {
  20. if (isset($_POST["add_category"])) {
  21. $label = normalizeCategoryLabel($_POST["label"] ?? "");
  22. if (!isValidCategoryLabel($label)) {
  23. $message =
  24. "Bitte geben Sie einen Kategorienamen mit maximal 80 Zeichen ein.";
  25. $messageType = "error";
  26. } else {
  27. $categoryId = generateCategoryIdFromLabel($label, $categories);
  28. $categories[] = [
  29. "id" => $categoryId,
  30. "label" => $label,
  31. ];
  32. saveCategories($categories);
  33. logAccess("Admin added category", [
  34. "category_id" => $categoryId,
  35. "label" => $label,
  36. ]);
  37. $message = "Kategorie wurde erfolgreich angelegt.";
  38. $messageType = "success";
  39. }
  40. }
  41. if (isset($_POST["update_category"])) {
  42. $categoryId = normalizeCategoryId($_POST["category_id"] ?? "");
  43. $label = normalizeCategoryLabel($_POST["label"] ?? "");
  44. $found = false;
  45. if (!isValidCategoryLabel($label)) {
  46. $message =
  47. "Bitte geben Sie einen Kategorienamen mit maximal 80 Zeichen ein.";
  48. $messageType = "error";
  49. } else {
  50. foreach ($categories as &$category) {
  51. if ($category["id"] === $categoryId) {
  52. $category["label"] = $label;
  53. $found = true;
  54. break;
  55. }
  56. }
  57. unset($category);
  58. if (!$found) {
  59. $message = "Kategorie nicht gefunden.";
  60. $messageType = "error";
  61. } else {
  62. saveCategories($categories);
  63. logAccess("Admin updated category", [
  64. "category_id" => $categoryId,
  65. "label" => $label,
  66. ]);
  67. $message = "Kategorie wurde erfolgreich aktualisiert.";
  68. $messageType = "success";
  69. }
  70. }
  71. }
  72. if (isset($_POST["delete_category"])) {
  73. $categoryId = normalizeCategoryId($_POST["category_id"] ?? "");
  74. $label = "";
  75. $found = false;
  76. if (isCategoryInUse($categoryId)) {
  77. $message =
  78. "Diese Kategorie wird noch von Produkten verwendet und kann nicht gelöscht werden.";
  79. $messageType = "error";
  80. } else {
  81. $categories = array_values(
  82. array_filter($categories, function ($category) use (
  83. $categoryId,
  84. &$found,
  85. &$label,
  86. ) {
  87. if ($category["id"] === $categoryId) {
  88. $found = true;
  89. $label = $category["label"];
  90. return false;
  91. }
  92. return true;
  93. }),
  94. );
  95. if (!$found) {
  96. $message = "Kategorie nicht gefunden.";
  97. $messageType = "error";
  98. } else {
  99. saveCategories($categories);
  100. logAccess("Admin deleted category", [
  101. "category_id" => $categoryId,
  102. "label" => $label,
  103. ]);
  104. $message = "Kategorie wurde gelöscht.";
  105. $messageType = "success";
  106. }
  107. }
  108. }
  109. $categories = getCategories();
  110. $products = getProducts();
  111. }
  112. }
  113. $editCategoryId = normalizeCategoryId($_GET["edit"] ?? "");
  114. $editingCategory = null;
  115. if ($editCategoryId !== "") {
  116. $editingCategory = getCategoryById($editCategoryId);
  117. if ($editingCategory === null && $message === "") {
  118. $message = "Ausgewählte Kategorie wurde nicht gefunden.";
  119. $messageType = "error";
  120. }
  121. }
  122. $bodyClass = "admin-page";
  123. include __DIR__ . "/../includes/header.php";
  124. ?>
  125. <div class="admin-header">
  126. <h2>Kategorien verwalten</h2>
  127. <div>
  128. <a href="index.php" class="btn btn-secondary">Zurück zum Dashboard</a>
  129. </div>
  130. </div>
  131. <?php if ($message !== ""): ?>
  132. <div class="alert alert-<?php echo $messageType; ?>">
  133. <?php echo htmlspecialchars($message); ?>
  134. </div>
  135. <?php endif; ?>
  136. <?php if ($editingCategory !== null): ?>
  137. <div class="panel panel-lg">
  138. <h3>Kategorie bearbeiten</h3>
  139. <form method="POST">
  140. <?php echo csrfField(); ?>
  141. <input type="hidden" name="category_id" value="<?php echo htmlspecialchars(
  142. $editingCategory["id"],
  143. ); ?>">
  144. <div class="form-group">
  145. <label for="category_id_display">ID</label>
  146. <input type="text" id="category_id_display" value="<?php echo htmlspecialchars(
  147. $editingCategory["id"],
  148. ); ?>" readonly>
  149. <small>Die ID sollte gleichbleiben, damit Produktzuordnungen und Filter-URLs gültig bleiben.</small>
  150. </div>
  151. <div class="form-group">
  152. <label for="label_edit">Name *</label>
  153. <input type="text" id="label_edit" name="label" maxlength="80" required value="<?php echo htmlspecialchars(
  154. $editingCategory["label"],
  155. ); ?>">
  156. </div>
  157. <button type="submit" name="update_category" class="btn">Kategorie aktualisieren</button>
  158. <a href="categories.php" class="btn btn-secondary">Abbrechen</a>
  159. </form>
  160. </div>
  161. <?php else: ?>
  162. <div class="panel panel-lg">
  163. <h3>Neue Kategorie anlegen</h3>
  164. <form method="POST">
  165. <div class="form-group">
  166. <label for="label">Name *</label>
  167. <input type="text" id="label" name="label" maxlength="80" required placeholder="z.B. Accessoires">
  168. <small>Die technische ID wird einmalig automatisch aus dem Namen erzeugt.</small>
  169. </div>
  170. <button type="submit" name="add_category" class="btn">Kategorie anlegen</button>
  171. </form>
  172. </div>
  173. <?php endif; ?>
  174. <div class="panel">
  175. <h3>Kategorien</h3>
  176. <div class="table-responsive">
  177. <table class="responsive-table">
  178. <thead>
  179. <tr>
  180. <th>Name</th>
  181. <th>ID</th>
  182. <th>Produkte</th>
  183. <th>Aktionen</th>
  184. </tr>
  185. </thead>
  186. <tbody>
  187. <?php foreach ($categories as $category): ?>
  188. <?php
  189. $productCount = 0;
  190. foreach ($products as $product) {
  191. if (productHasCategory($product, $category["id"])) {
  192. $productCount++;
  193. }
  194. }
  195. ?>
  196. <tr>
  197. <td data-label="Name"><?php echo htmlspecialchars(
  198. $category["label"],
  199. ); ?></td>
  200. <td data-label="ID"><code><?php echo htmlspecialchars(
  201. $category["id"],
  202. ); ?></code></td>
  203. <td data-label="Produkte"><?php echo $productCount; ?></td>
  204. <td data-label="Aktionen">
  205. <a href="categories.php?edit=<?php echo urlencode(
  206. $category["id"],
  207. ); ?>" class="btn btn-small btn-secondary">Bearbeiten</a>
  208. <form method="POST" class="inline-form" onsubmit="return confirm('Kategorie wirklich löschen?');">
  209. <?php echo csrfField(); ?>
  210. <input type="hidden" name="category_id" value="<?php echo htmlspecialchars(
  211. $category["id"],
  212. ); ?>">
  213. <button type="submit" name="delete_category" class="btn btn-small">Löschen</button>
  214. </form>
  215. </td>
  216. </tr>
  217. <?php endforeach; ?>
  218. </tbody>
  219. </table>
  220. </div>
  221. </div>
  222. <?php include __DIR__ . "/../includes/footer.php"; ?>