Магазин на Laravel 7, часть 11. Панель управления, просмотр и удаление категорий
13.10.2020
Теги: Laravel • MySQL • PHP • Web-разработка • БазаДанных • ИнтернетМагазин • КаталогТоваров • ПанельУправления • Практика • Фреймворк
Контроллер CategoryController
Теперь поработаем над панелью управления магазином. И начнем с категорий каталога товаров. Нам нужен ресурсный контроллер, т.е. контроллер, который позволяет выполянить CRUD-операции над категориями каталога. Создать такой контроллер можно с помощью artisan-команды.
> php artisan make:controller Admin/CategoryController --resource
namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class CategoryController extends Controller { public function index() { // ... } public function create() { // ... } public function store(Request $request) { // ... } public function show($id) { // ... } public function edit($id) { // ... } public function update(Request $request, $id) { // ... } public function destroy($id) { // ... } }
Но можно поступить лучше — сразу указать модель, с которой будет работать контроллер:
> php artisan make:controller Admin/CategoryController --resource --model=Models/Category
namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Models\Category; use Illuminate\Http\Request; class CategoryController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // ... } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // ... } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // ... } /** * Display the specified resource. * * @param \App\Models\Category $category * @return \Illuminate\Http\Response */ public function show(Category $category) { // ... } /** * Show the form for editing the specified resource. * * @param \App\Models\Category $category * @return \Illuminate\Http\Response */ public function edit(Category $category) { // ... } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Models\Category $category * @return \Illuminate\Http\Response */ public function update(Request $request, Category $category) { // ... } /** * Remove the specified resource from storage. * * @param \App\Models\Category $category * @return \Illuminate\Http\Response */ public function destroy(Category $category) { // ... } }
Семь маршрутов для CRUD
Теперь для каждого экшена нам нужен маршрут — всего семь маршрутов. Это можно сделать с помощью одной строки кода.
/* Тип URI Действие Имя маршрута -------------------------------------------------- GET /item index item.index GET /item/create create item.create POST /item store item.store GET /item/{id} show item.show GET /item/{id}/edit edit item.edit PUT/PATCH /item/{id} update item.update DELETE /item/{id} destroy item.destroy */ Route::resource('item', 'ItemController');
В нашем случае будет немного сложнее — потому что нужна группировка + защита маршртутов с помощью middleware.
Route::group([ 'as' => 'admin.', // имя маршрута, например admin.index 'prefix' => 'admin', // префикс маршрута, например admin/index 'namespace' => 'Admin', // пространство имен контроллера 'middleware' => ['auth', 'admin'] // один или несколько посредников ], function () { // главная страница панели управления Route::get('index', 'IndexController')->name('index'); // CRUD-операции над категориями каталога Route::resource('category', 'CategoryController'); });
Проверить маршруты можно с помощью artisan-команды:
> php artisan route:list --name=category +-----------+--------------------------------+------------------------+-------------------------------------------------------+------------+ | Method | URI | Name | Action | Middleware | +-----------+--------------------------------+------------------------+-------------------------------------------------------+------------+ | GET|HEAD | admin/category | admin.category.index | App\Http\Controllers\Admin\CategoryController@index | .......... | | GET|HEAD | admin/category/{category} | admin.category.show | App\Http\Controllers\Admin\CategoryController@show | .......... | | GET|HEAD | admin/category/create | admin.category.create | App\Http\Controllers\Admin\CategoryController@create | .......... | | POST | admin/category | admin.category.store | App\Http\Controllers\Admin\CategoryController@store | .......... | | GET|HEAD | admin/category/{category}/edit | admin.category.edit | App\Http\Controllers\Admin\CategoryController@edit | .......... | | PUT|PATCH | admin/category/{category} | admin.category.update | App\Http\Controllers\Admin\CategoryController@update | .......... | | DELETE | admin/category/{category} | admin.category.destroy | App\Http\Controllers\Admin\CategoryController@destroy | .......... | | GET|HEAD | catalog/category/{slug} | catalog.category | App\Http\Controllers\CatalogController@category | .......... | +-----------+--------------------------------+------------------------+-------------------------------------------------------+------------+
Реализуем метод index()
Хорошо, давайте реализуем метод index()
контроллера, который будет отвечать за показ всех категорий.
class CategoryController extends Controller { /* ... */ public function index() { $roots = Category::roots(); return view('admin.category.index', compact('roots')); } /* ... */ }
И создадим шаблон index.blade.php
в директории views/admin/category
:
@extends('layout.admin') @section('content') <h1>Все категории</h1> <table class="table table-bordered"> <tr> <th width="30%">Наименование</th> <th width="65%">Описание</th> <th><i class="fas fa-edit"></i></th> <th><i class="fas fa-trash-alt"></i></th> </tr> @include('admin.category.part.tree', ['items' => $roots, 'level' => -1]) </table> @endsection
Шаблон tree.blade.php
в директории views/admin/category/part
подключает сам себя для рекурсивного вывода всех категорий.
@if (count($items)) @php $level++; @endphp @foreach ($items as $item) <tr> <td> @if ($level) {{ str_repeat('—', $level) }} @endif <a href="{{ route('admin.category.show', ['category' => $item->id]) }}" style="font-weight:@if($level) normal @else bold @endif"> {{ $item->name }} </a> </td> <td>{{ iconv_substr($item->content, 0, 150) }}</td> <td> <a href="{{ route('admin.category.edit', ['category' => $item->id]) }}"> <i class="far fa-edit"></i> </a> </td> <td> <form action="{{ route('admin.category.destroy', ['category' => $item->id]) }}" method="post"> @csrf @method('DELETE') <button type="submit" class="m-0 p-0 border-0 bg-transparent"> <i class="far fa-trash-alt text-danger"></i> </button> </form> </td> </tr> @if ($item->children->count()) @include('admin.category.part.tree', ['items' => $item->children, 'level' => $level]) @endif @endforeach @endif
Реализуем метод show()
Теперь реализуем метод show()
контроллера, который будет отвечать за показ выбранной категории.
class CategoryController extends Controller { /* ... */ public function show(Category $category) { return view('admin.category.show', compact('category')); } /* ... */ }
И создадим шаблон show.blade.php
в директории views/admin/category
:
@extends('layout.admin') @section('content') <h1>Просмотр категории</h1> <div class="row"> <div class="col-md-6"> <p><strong>Название:</strong> {{ $category->name }}</p> <p><strong>ЧПУ (англ):</strong> {{ $category->slug }}</p> <p><strong>Краткое описание</strong></p> @isset($category->content) <p>{{ $category->content }}</p> @else <p>Описание отсутствует</p> @endisset </div> <div class="col-md-6"> <img src="https://via.placeholder.com/600x200" alt="" class="img-fluid"> </div> </div> @if ($category->children->count()) <p><strong>Дочерние категории</strong></p> <table class="table table-bordered"> <tr> <th>№</th> <th width="45%">Наименование</th> <th width="45%">ЧПУ (англ)</th> <th><i class="fas fa-edit"></i></th> <th><i class="fas fa-trash-alt"></i></th> </tr> @foreach ($category->children as $child) <tr> <td>{{ $loop->iteration }}</td> <td> <a href="{{ route('admin.category.show', ['category' => $child->id]) }}"> {{ $child->name }} </a> </td> <td>{{ $child->slug }}</td> <td> <a href="{{ route('admin.category.edit', ['category' => $child->id]) }}"> <i class="far fa-edit"></i> </a> </td> <td> <form action="{{ route('admin.category.destroy', ['category' => $child->id]) }}" method="post"> @csrf @method('DELETE') <button type="submit" class="m-0 p-0 border-0 bg-transparent"> <i class="far fa-trash-alt text-danger"></i> </button> </form> </td> </tr> @endforeach </table> @else <p>Нет дочерних категорий</p> @endif <form method="post" action="{{ route('admin.category.destroy', ['category' => $category->id]) }}"> @csrf @method('DELETE') <button type="submit" class="btn btn-danger"> Удалить категорию </button> </form> @endsection
Реализуем метод destroy()
Перед удалением категории мы должны проверить, что категория не имеет дочерних категорий и не содержит товаров.
class CategoryController extends Controller { /* ... */ public function destroy(Category $category) { if ($category->children->count()) { $errors[] = 'Нельзя удалить категорию с дочерними категориями'; } if ($category->products->count()) { $errors[] = 'Нельзя удалить категорию, которая содержит товары'; } if (!empty($errors)) { return back()->withErrors($errors); } $category->delete(); return redirect() ->route('admin.category.index') ->with('success', 'Категория каталога успешно удалена'); } /* ... */ }
- Магазин на Laravel 7, часть 18. Панель управления, пользователи и CRUD страниц сайта
- Магазин на Laravel 7, часть 17. Панель управления, работа с заказами, изменение статуса
- Магазин на Laravel 7, часть 16. Панель управления, CRUD-операции для товаров каталога
- Магазин на Laravel 7, часть 15. Панель управления, добавление и редактирование брендов
- Магазин на Laravel 7, часть 14. Панель управления, доп.проверка для родителя категории
- Магазин на Laravel 7, часть 13. Панель управления, обрезка изображения и валидация данных
- Магазин на Laravel 7, часть 12. Панель управления, создание и редактирование категорий
Поиск: Laravel • MySQL • PHP • Web-разработка • База данных • Интернет магазин • Каталог товаров • Панель управления • Практика • Фреймворк