[MVC] Полная миграция на MVC архитектуру
- Создано ядро MVC: App, Router, Controller, Model, View, Database - Созданы модели: User, Product, Category, Cart, Order - Созданы контроллеры: Home, Auth, Product, Cart, Order, Page, Admin - Созданы layouts и partials для представлений - Добавлены все views для страниц - Настроена маршрутизация с чистыми URL - Обновлена конфигурация Docker и Apache для mod_rewrite - Добавлена единая точка входа public/index.php
This commit is contained in:
374
app/Controllers/AdminController.php
Normal file
374
app/Controllers/AdminController.php
Normal file
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Models\Product;
|
||||
use App\Models\Category;
|
||||
use App\Models\Order;
|
||||
use App\Models\User;
|
||||
|
||||
/**
|
||||
* AdminController - контроллер админ-панели
|
||||
*/
|
||||
class AdminController extends Controller
|
||||
{
|
||||
private Product $productModel;
|
||||
private Category $categoryModel;
|
||||
private Order $orderModel;
|
||||
private User $userModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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 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');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user