Магазин на Yii2, часть 32. Админка: удаление категорий и CRUD для страниц
17.09.2019
Теги: CRUD • Web-разработка • Yii2 • ИнтернетМагазин • КаталогТоваров • ПанельУправления • Практика • СтраницаСайта • Удалить • Фреймворк
Перед удалением категории нужно выполнить две проверки. Первая — что категория не содержит товары. Вторая — что категория не имеет дочерних категорий. Если хотя бы одно условие ложно, категорию удалять нельзя. Добавим метод beforeDelete()
в класс модели Category
:
class Category extends ActiveRecord { /*...*/ /** * Проверка перед удалением категории */ public function beforeDelete() { $children = self::find()->where(['parent_id' => $this->id])->all(); $products = Product::find()->where(['category_id' => $this->id])->all(); if (!empty($children) || !empty($products)) { Yii::$app->session->setFlash( 'warning', 'Нельзя удалить категорию, которая имеет товары или дочерние категории' ); return false; } return parent::beforeDelete(); } /*...*/ }
Мы записываем в сессию сообщение об ошибке, которое покажем в layout-шаблоне:
<?php /* * Layout-шаблон, файл modules/views/layouts/main.php */ /* @var $this \yii\web\View */ /* @var $content string */ use yii\helpers\Html; use yii\bootstrap\Nav; use yii\bootstrap\NavBar; use yii\helpers\Url; use app\assets\AppAsset; AppAsset::register($this); ?> <?php $this->beginPage() ?> <!DOCTYPE html> <html lang="<?= Yii::$app->language ?>"> <head> <meta charset="<?= Yii::$app->charset ?>"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <?php $this->registerCsrfMetaTags() ?> <title><?= Html::encode($this->title) ?> | Панель управления</title> <?php $this->head() ?> </head> <body> <?php $this->beginBody() ?> <header> <!-- .......... --> </header> <div class="container"> <?php if (Yii::$app->session->hasFlash('warning')): ?> <div class="alert alert-warning alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Закрыть"> <span aria-hidden="true">×</span> </button> <p><?= Yii::$app->session->getFlash('warning'); ?></p> </div> <?php endif; ?> <?= $content; ?> </div> <footer class="footer"> <!-- .......... --> </footer> <?php $this->endBody() ?> </body> </html> <?php $this->endPage() ?>
По аналогии с категориями, добавим метод beforeDelete()
в класс модели Brand
:
class Brand extends ActiveRecord { /*...*/ /** * Проверка перед удалением бренда */ public function beforeDelete() { $products = Product::find()->where(['brand_id' => $this->id])->all(); if (!empty($products)) { Yii::$app->session->setFlash( 'warning', 'Нельзя удалить бренд, у которого есть товары' ); return false; } return parent::beforeDelete(); } /*...*/ }
Создаем модель и CRUD-контроллер для страниц
У нас по дизайну предусмотрено несколько страниц — «Доставка», «Оплата», «Контакты». Но пока нет возможности добавить эти страницы и динамически показывать список этих страниц в публичной части. Давайте это исправим — создадим таблицу базы данных page
, создадим для нее класс модели и возможность выполнения CRUD-операций над страницами.
CREATE TABLE `page` ( `id` int(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Уникальный идентификатор', `parent_id` int(10) UNSIGNED NOT NULL COMMENT 'Родительская страница', `name` varchar(100) NOT NULL COMMENT 'Заголовок страницы', `slug` varchar(100) NOT NULL UNIQUE KEY COMMENT 'Для создания ссылки', `content` text COMMENT 'Содержимое страницы', `keywords` varchar(255) DEFAULT NULL COMMENT 'Мета-тег keywords', `description` varchar(255) DEFAULT NULL COMMENT 'Мета-тег description' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Как обычно, воспользуемся генератором кода Gii. Переходим по ссылке «Model Generator», задаем имя таблицы БД, имя класса модели и пространство имен:
Table Name: page Model Class Name: Page Namespace: app\modules\admin\models
<?php namespace app\modules\admin\models; use Yii; use yii\db\ActiveRecord; /** * This is the model class for table "page". * * @property int $id Уникальный идентификатор * @property int $parent_id Родительская страница * @property string $name Заголовок страницы * @property string $slug Для создания ссылки * @property string $content Содержимое страницы * @property string $keywords Мета-тег keywords * @property string $description Мета-тег description */ class Page extends ActiveRecord { /** * {@inheritdoc} */ public static function tableName() { return 'page'; } /** * {@inheritdoc} */ public function rules() { return [ [['parent_id', 'name', 'slug'], 'required'], [['parent_id'], 'integer'], [['content'], 'string'], [['name', 'slug'], 'string', 'max' => 100], [['keywords', 'description'], 'string', 'max' => 255], [['slug'], 'unique'], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'parent_id' => 'Parent', 'name' => 'Name', 'slug' => 'Slug', 'content' => 'Content', 'keywords' => 'Keywords', 'description' => 'Description', ]; } }
Теперь используем «CRUD Generator», который создаст нам контроллер и view-шаблоны. И мы получим готовой код для создания, просмотра, редактирования и удаления страниц.
Model Class: app\modules\admin\models\Page Controller Class: app\modules\admin\controllers\PageController View Path: @app/modules/admin/views/page Base Controller Class: app\modules\admin\controllers\AdminController
<?php namespace app\modules\admin\controllers; use Yii; use app\modules\admin\models\Page; use yii\data\ActiveDataProvider; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; /** * PageController implements the CRUD actions for Page model. */ class PageController extends AdminController { /** * {@inheritdoc} */ public function behaviors() { return [ 'verbs' => [ 'class' => VerbFilter::class, 'actions' => [ 'delete' => ['POST'], ], ], ]; } /** * Lists all Page models. * @return mixed */ public function actionIndex() { $dataProvider = new ActiveDataProvider([ 'query' => Page::find(), ]); return $this->render('index', [ 'dataProvider' => $dataProvider, ]); } /** * Displays a single Page model. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found */ public function actionView($id) { return $this->render('view', [ 'model' => $this->findModel($id), ]); } /** * Creates a new Page model. * If creation is successful, the browser will be redirected to the 'view' page. * @return mixed */ public function actionCreate() { $model = new Page(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } return $this->render('create', [ 'model' => $model, ]); } /** * Updates an existing Page model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found */ public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } return $this->render('update', [ 'model' => $model, ]); } /** * Deletes an existing Page model. * If deletion is successful, the browser will be redirected to the 'index' page. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found */ public function actionDelete($id) { $this->findModel($id)->delete(); return $this->redirect(['index']); } /** * Finds the Page model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. * @param integer $id * @return Page the loaded model * @throws NotFoundHttpException if the model cannot be found */ protected function findModel($id) { if (($model = Page::findOne($id)) !== null) { return $model; } throw new NotFoundHttpException('The requested page does not exist.'); } }
- Магазин на Yii2, часть 33. Админка: приводим в порядок CRUD-код для страниц
- Магазин на Yii2, часть 34. Показываем меню страниц в публичной части
- Магазин на Yii2, часть 31. Админка: загрузка изображений для категорий и брендов
- Магазин на Yii2, часть 30. Админка: WYSIWYG-редактор и изображение для товара
- Магазин на Yii2, часть 29. Админка: добавляем список товаров категории
- Магазин на Yii2, часть 28. Админка: выбор родителя и список всех категорий
- Магазин на Yii2, часть 27. Админка: приводим в порядок сгенерированный код
Поиск: Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Панель управления • Удалить • Фреймворк • Gii • CRUD • Практика