productModel = new Product(); $this->categoryModel = new Category(); $this->orderModel = new Order(); $this->userModel = new User(); } public function dashboard(): void { $this->requireAdmin(); $stats = [ 'total_products' => $this->productModel->count(), 'active_products' => $this->productModel->count(['is_available' => true]), 'total_orders' => $this->orderModel->count(), 'total_users' => $this->userModel->count(), 'revenue' => $this->orderModel->getStats()['revenue'] ]; $this->view('admin/dashboard', [ 'stats' => $stats, 'user' => $this->getCurrentUser() ], 'admin'); } public function products(): void { $this->requireAdmin(); $showAll = $this->getQuery('show_all') === '1'; $products = $this->productModel->getAllForAdmin($showAll); $this->view('admin/products/index', [ 'products' => $products, 'showAll' => $showAll, 'message' => $this->getQuery('message'), 'error' => $this->getQuery('error'), 'user' => $this->getCurrentUser() ], 'admin'); } public function addProduct(): void { $this->requireAdmin(); $categories = $this->categoryModel->getActive(); $this->view('admin/products/form', [ 'product' => null, 'categories' => $categories, 'action' => 'add', 'user' => $this->getCurrentUser() ], 'admin'); } public function storeProduct(): void { $this->requireAdmin(); $data = [ 'name' => $this->getPost('name'), 'category_id' => (int) $this->getPost('category_id'), 'description' => $this->getPost('description'), 'price' => (float) $this->getPost('price'), 'old_price' => $this->getPost('old_price') ? (float) $this->getPost('old_price') : null, 'sku' => $this->getPost('sku'), 'stock_quantity' => (int) $this->getPost('stock_quantity', 0), 'is_available' => $this->getPost('is_available') ? true : false, 'is_featured' => $this->getPost('is_featured') ? true : false, 'image_url' => $this->getPost('image_url'), 'color' => $this->getPost('color'), 'material' => $this->getPost('material'), 'card_size' => $this->getPost('card_size', 'small') ]; try { $this->productModel->createProduct($data); $this->redirect('/admin/products?message=' . urlencode('Товар успешно добавлен')); } catch (\Exception $e) { $this->redirect('/admin/products/add?error=' . urlencode($e->getMessage())); } } public function editProduct(int $id): void { $this->requireAdmin(); $product = $this->productModel->find($id); if (!$product) { $this->redirect('/admin/products?error=' . urlencode('Товар не найден')); return; } $categories = $this->categoryModel->getActive(); $this->view('admin/products/form', [ 'product' => $product, 'categories' => $categories, 'action' => 'edit', 'user' => $this->getCurrentUser() ], 'admin'); } public function updateProduct(int $id): void { $this->requireAdmin(); $data = [ 'name' => $this->getPost('name'), 'category_id' => (int) $this->getPost('category_id'), 'description' => $this->getPost('description'), 'price' => (float) $this->getPost('price'), 'old_price' => $this->getPost('old_price') ? (float) $this->getPost('old_price') : null, 'stock_quantity' => (int) $this->getPost('stock_quantity', 0), 'is_available' => $this->getPost('is_available') ? true : false, 'image_url' => $this->getPost('image_url'), 'color' => $this->getPost('color'), 'material' => $this->getPost('material') ]; try { $this->productModel->updateProduct($id, $data); $this->redirect('/admin/products?message=' . urlencode('Товар обновлен')); } catch (\Exception $e) { $this->redirect('/admin/products/edit/' . $id . '?error=' . urlencode($e->getMessage())); } } public function deleteProduct(int $id): void { $this->requireAdmin(); $this->productModel->update($id, ['is_available' => false]); $this->redirect('/admin/products?message=' . urlencode('Товар скрыт')); } public function removeProduct(int $id): void { $this->requireAdmin(); $product = $this->productModel->find($id); if (!$product) { $this->redirect('/admin/products?error=' . urlencode('Товар не найден')); return; } // Удаляем только если товара нет на складе if ($product['stock_quantity'] > 0) { $this->redirect('/admin/products?error=' . urlencode('Нельзя удалить товар, который есть на складе')); return; } // Полное удаление из БД $this->productModel->delete($id); $this->redirect('/admin/products?message=' . urlencode('Товар удален из базы данных')); } public function categories(): void { $this->requireAdmin(); $categories = $this->categoryModel->getAllWithProductCount(); $this->view('admin/categories/index', [ 'categories' => $categories, 'message' => $this->getQuery('message'), 'error' => $this->getQuery('error'), 'user' => $this->getCurrentUser() ], 'admin'); } public function addCategory(): void { $this->requireAdmin(); $parentCategories = $this->categoryModel->getParent(); $this->view('admin/categories/form', [ 'category' => null, 'parentCategories' => $parentCategories, 'action' => 'add', 'user' => $this->getCurrentUser() ], 'admin'); } public function storeCategory(): void { $this->requireAdmin(); $data = [ 'name' => $this->getPost('name'), 'parent_id' => $this->getPost('parent_id') ? (int) $this->getPost('parent_id') : null, 'description' => $this->getPost('description'), 'sort_order' => (int) $this->getPost('sort_order', 0), 'is_active' => $this->getPost('is_active') ? true : false ]; try { $this->categoryModel->createCategory($data); $this->redirect('/admin/categories?message=' . urlencode('Категория добавлена')); } catch (\Exception $e) { $this->redirect('/admin/categories/add?error=' . urlencode($e->getMessage())); } } public function editCategory(int $id): void { $this->requireAdmin(); $category = $this->categoryModel->find($id); if (!$category) { $this->redirect('/admin/categories?error=' . urlencode('Категория не найдена')); return; } $parentCategories = $this->categoryModel->getParent(); $this->view('admin/categories/form', [ 'category' => $category, 'parentCategories' => $parentCategories, 'action' => 'edit', 'user' => $this->getCurrentUser() ], 'admin'); } public function updateCategory(int $id): void { $this->requireAdmin(); $data = [ 'name' => $this->getPost('name'), 'parent_id' => $this->getPost('parent_id') ? (int) $this->getPost('parent_id') : null, 'description' => $this->getPost('description'), 'sort_order' => (int) $this->getPost('sort_order', 0), 'is_active' => $this->getPost('is_active') ? true : false ]; try { $this->categoryModel->updateCategory($id, $data); $this->redirect('/admin/categories?message=' . urlencode('Категория обновлена')); } catch (\Exception $e) { $this->redirect('/admin/categories/edit/' . $id . '?error=' . urlencode($e->getMessage())); } } public function deleteCategory(int $id): void { $this->requireAdmin(); $result = $this->categoryModel->safeDelete($id); if ($result['deleted']) { $this->redirect('/admin/categories?message=' . urlencode('Категория удалена')); } else { $msg = $result['reason'] === 'has_products' ? 'Категория скрыта (содержит товары)' : 'Категория скрыта (имеет дочерние категории)'; $this->redirect('/admin/categories?message=' . urlencode($msg)); } } public function orders(): void { $this->requireAdmin(); $orders = $this->orderModel->getAllForAdmin(); $this->view('admin/orders/index', [ 'orders' => $orders, 'user' => $this->getCurrentUser() ], 'admin'); } public function orderDetails(int $id): void { $this->requireAdmin(); $order = $this->orderModel->getWithDetails($id); if (!$order) { $this->redirect('/admin/orders?error=' . urlencode('Заказ не найден')); return; } $this->view('admin/orders/details', [ 'order' => $order, 'user' => $this->getCurrentUser() ], 'admin'); } public function updateOrderStatus(int $id): void { $this->requireAdmin(); $status = $this->getPost('status'); $this->orderModel->updateStatus($id, $status); $this->redirect('/admin/orders/' . $id); } public function users(): void { $this->requireAdmin(); $users = $this->userModel->getAllPaginated(); $this->view('admin/users/index', [ 'users' => $users, 'user' => $this->getCurrentUser() ], 'admin'); } }