From d9cb77c6feed334e28df3e0bd4ef32f61653b73e Mon Sep 17 00:00:00 2001 From: DualFroz Date: Tue, 25 Aug 2026 20:25:00 +0200 Subject: [PATCH] feat(admin): add category and attribute controllers --- src/Controllers/Admin/AttributeController.php | 57 ++++++++++ src/Controllers/Admin/CategoryController.php | 102 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/Controllers/Admin/AttributeController.php create mode 100644 src/Controllers/Admin/CategoryController.php diff --git a/src/Controllers/Admin/AttributeController.php b/src/Controllers/Admin/AttributeController.php new file mode 100644 index 0000000..e4136e6 --- /dev/null +++ b/src/Controllers/Admin/AttributeController.php @@ -0,0 +1,57 @@ +view('admin.attributes.index', [ + 'attributes' => $this->ctx->attributes->withValues(), + ], 'admin.layout'); + } + + public function store(): Response + { + $name = trim((string) $this->ctx->request->input('name', '')); + if ($name === '') { + $this->ctx->session->flash('error', 'Attribute name is required.'); + return $this->redirect('/admin/attributes'); + } + $slug = slugify($name); + if ($this->ctx->attributes->findBySlug($slug) === null) { + $this->ctx->attributes->create($name, $slug); + $this->ctx->session->flash('success', 'Attribute created.'); + } else { + $this->ctx->session->flash('error', 'That attribute already exists.'); + } + return $this->redirect('/admin/attributes'); + } + + public function storeValue(string $id): Response + { + $attributeId = (int) $id; + $attribute = $this->ctx->attributes->find($attributeId); + if ($attribute === null) { + return $this->notFound(); + } + + $value = trim((string) $this->ctx->request->input('value', '')); + if ($value === '') { + $this->ctx->session->flash('error', 'Value is required.'); + return $this->redirect('/admin/attributes'); + } + + $slug = slugify($value); + if ($this->ctx->attributes->findValueBySlug($attributeId, $slug) === null) { + $this->ctx->attributes->createValue($attributeId, $value, $slug); + $this->ctx->session->flash('success', 'Value added.'); + } else { + $this->ctx->session->flash('error', 'That value already exists for this attribute.'); + } + return $this->redirect('/admin/attributes'); + } +} diff --git a/src/Controllers/Admin/CategoryController.php b/src/Controllers/Admin/CategoryController.php new file mode 100644 index 0000000..4673f4a --- /dev/null +++ b/src/Controllers/Admin/CategoryController.php @@ -0,0 +1,102 @@ +view('admin.categories.index', [ + 'categories' => $this->ctx->categories->withProductCounts(), + ], 'admin.layout'); + } + + public function create(): Response + { + return $this->view('admin.categories.form', [ + 'category' => null, + 'errors' => [], + ], 'admin.layout'); + } + + public function store(): Response + { + [$fields, $errors] = $this->validate(); + if ($errors !== []) { + return $this->view('admin.categories.form', [ + 'category' => $fields, + 'errors' => $errors, + ], 'admin.layout', 422); + } + + $this->ctx->categories->create($fields['name'], $fields['slug'], $fields['description']); + $this->ctx->session->flash('success', 'Category created.'); + return $this->redirect('/admin/categories'); + } + + public function edit(string $id): Response + { + $category = $this->ctx->categories->find((int) $id); + if ($category === null) { + return $this->notFound(); + } + + return $this->view('admin.categories.form', [ + 'category' => $category, + 'errors' => [], + ], 'admin.layout'); + } + + public function update(string $id): Response + { + $category = $this->ctx->categories->find((int) $id); + if ($category === null) { + return $this->notFound(); + } + + [$fields, $errors] = $this->validate(); + if ($errors !== []) { + return $this->view('admin.categories.form', [ + 'category' => array_merge($category, $fields), + 'errors' => $errors, + ], 'admin.layout', 422); + } + + $this->ctx->categories->update((int) $id, $fields['name'], $fields['slug'], $fields['description']); + $this->ctx->session->flash('success', 'Category updated.'); + return $this->redirect('/admin/categories'); + } + + public function destroy(string $id): Response + { + $this->ctx->categories->delete((int) $id); + $this->ctx->session->flash('success', 'Category deleted.'); + return $this->redirect('/admin/categories'); + } + + private function validate(): array + { + $request = $this->ctx->request; + $name = trim((string) $request->input('name', '')); + $slug = trim((string) $request->input('slug', '')); + if ($slug === '') { + $slug = slugify($name); + } + + $errors = []; + if ($name === '') { + $errors['name'] = 'Name is required.'; + } + + $fields = [ + 'name' => $name, + 'slug' => $slug, + 'description' => trim((string) $request->input('description', '')), + ]; + + return [$fields, $errors]; + } +}