Панель администратора: управление товарами
Студент создаст защищенный раздел для администратора, где реализует добавление, редактирование и удаление товаров.
Проектирование административной панели
До этого момента мы работали над клиентской частью (Frontend/User-facing) нашего интернет-магазина. Теперь пришло время создать панель управления (Backend/Admin panel). Это закрытая часть сайта, доступная только сотрудникам магазина. Здесь они смогут управлять каталогом товаров, категориями и заказами. Мы будем использовать паттерн CRUD (Create, Read, Update, Delete) — четыре базовые функции, используемые при работе с базами данных (Chunking).
Первый шаг — разделение прав доступа. Мы не можем позволить любому зарегистрированному пользователю добавлять товары. Нам нужно добавить поле `is_admin` (тип boolean) в таблицу `users`. Затем мы создадим специальный Middleware (Посредник), который будет проверять это поле при каждой попытке зайти в админку.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class IsAdmin {
public function handle(Request $request, Closure $next): Response {
// Проверяем, авторизован ли пользователь и является ли он администратором
if (auth()->check() && auth()->user()->is_admin) {
return $next($request); // Разрешаем прохождение запроса дальше
}
// Если нет прав, перенаправляем на главную с сообщением об ошибке
return redirect('/')->with('error', 'У вас нет доступа к этому разделу.');
}
}
// В файле routes/web.php группируем маршруты:
/*
Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () {
Route::resource('products', AdminProductController::class);
});
*/
Контроллер управления товарами и загрузка файлов
В Laravel есть удобный инструмент — Resource Controllers. Команда `php artisan make:controller AdminProductController --resource` создает контроллер с готовыми методами для всех операций CRUD: `index` (список), `create` (форма добавления), `store` (сохранение), `edit` (форма редактирования), `update` (обновление) и `destroy` (удаление).
Одной из самых сложных задач для новичков является правильная обработка загрузки изображений товаров (Scaffolding). Форма HTML должна обязательно содержать атрибут `enctype="multipart/form-data"`. В контроллере мы используем фасад `Storage` для сохранения файла на диск сервера. Laravel предоставляет абстракцию файловой системы, что позволяет легко менять место хранения файлов: от локального диска до облачного хранилища Amazon S3.
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class AdminProductController extends Controller {
public function store(Request $request) {
// Валидация входящих данных
$validated = $request->validate([
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
'category_id' => 'required|exists:categories,id',
'image' => 'nullable|image|mimes:jpg,png,jpeg|max:2048',
'description' => 'nullable|string'
]);
// Обработка загрузки изображения
if ($request->hasFile('image')) {
// Сохраняем файл в папку 'products' на диске 'public'
$path = $request->file('image')->store('products', 'public');
$validated['image'] = $path;
}
// Массовое заполнение (Mass Assignment) и сохранение в БД
Product::create($validated);
return redirect()->route('admin.products.index')
->with('success', 'Товар успешно добавлен!');
}
}
Валидация и безопасность (Mass Assignment)
В методе `store` мы используем метод `$request->validate()`. Это критически важный шаг для безопасности. Мы строго определяем, какие данные ожидаем получить. Правило `image|mimes:jpg,png|max:2048` гарантирует, что пользователь загрузит именно картинку определенного формата и размером не более 2 Мегабайт.
Обратите внимание на вызов `Product::create($validated)`. Это называется Mass Assignment (Массовое назначение). Чтобы это сработало, в модели `Product` необходимо обязательно определить свойство `$fillable` — массив полей, которые разрешено заполнять таким образом. Если забыть добавить поле (например, `price`) в `$fillable`, Laravel проигнорирует его при сохранении, и в базе данных окажется пустое значение, что приведет к ошибке SQL. Это частая ошибка начинающих разработчиков.
Флеш-карточки
Что означает аббревиатура CRUD?
Нажмите, чтобы увидеть ответ
Create, Read, Update, Delete (Создание, Чтение, Обновление, Удаление) - четыре базовые функции управления данными.
Нажмите, чтобы вернуться
Какой HTML атрибут обязателен для формы загрузки файлов?
Нажмите, чтобы увидеть ответ
enctype="multipart/form-data"
Нажмите, чтобы вернуться
Для чего нужно свойство $fillable в моделях Eloquent?
Нажмите, чтобы увидеть ответ
Оно защищает от уязвимости Mass Assignment, указывая, какие поля разрешено заполнять массово через методы create() или update().
Нажмите, чтобы вернуться
Задание
Реализация функционала удаления товара
- В AdminProductController найдите метод destroy(Product $product).
- Напишите проверку: если у товара есть изображение ($product->image), удалите его с диска с помощью Storage::disk('public')->delete($product->image).
- Вызовите метод $product->delete() для удаления записи из базы данных.
- Верните redirect()->route('admin.products.index') с сообщением 'Товар удален'.
- В Blade-шаблоне создайте HTML-форму с методом POST и директивами @csrf и @method('DELETE') для кнопки удаления.