Магазин на Yii2, часть 33. Админка: приводим в порядок CRUD-код для страниц
18.09.2019
Теги: CRUD • Web-разработка • Yii2 • ИнтернетМагазин • КаталогТоваров • ПанельУправления • Практика • СтраницаСайта • Фреймворк
Код для работы со страницами уже работает, но нуждается в некоторой доработке. Нужно предоставить возможность выбора родителя для страницы, прикрутить WYSIWYG-редактор, добавить валидатор для slug, изменить надписи на кнопках и так далее. Все это мы уже делали для товаров, категорий и брендов, так что без подробностей.
Модель и контроллер
<?php namespace app\modules\admin\models; use Yii; use yii\db\ActiveRecord; /** * Это модель для таблицы БД `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 { /** * Возвращает имя таблицы базы данных */ public static function tableName() { return 'page'; } /** * Возвращает данные о родительской странице */ public function getParent() { return $this->hasOne(Page::class, ['id' => 'parent_id']); } /** * Возвращает наименование родительской страницы */ public function getParentName() { $parent = $this->parent; return $parent ? $parent->name : ''; } /** * Возвращает массив страниц верхнего уровня для * возможности выбора родителя */ public static function getRootPages($exclude = 0) { $parents = [0 => 'Без родителя']; $root = Page::find()->where(['parent_id' => 0])->all(); foreach ($root as $item) { if ($exclude == $item['id']) { continue; } $parents[$item['id']] = $item['name']; } return $parents; } /** * Правила валидации полей формы при создании и редактировании страницы */ public function rules() { return [ [['parent_id', 'name', 'slug'], 'required'], ['parent_id', 'integer'], // не должно быть двух страниц с одинаковым slug ['slug', 'unique'], // slug может содержать только латиницу, цифры, дефис и подчеркивание ['slug', 'match', 'pattern' => '/^[a-z][-_a-z0-9]*$/i'], ['content', 'string'], [['name', 'slug'], 'string', 'max' => 100], [['keywords', 'description'], 'string', 'max' => 255], ]; } /** * Возвращает имена полей формы для создания и редактирования страницы */ public function attributeLabels() { return [ 'id' => 'ID', 'parent_id' => 'Родитель', 'name' => 'Заголовок', 'slug' => 'Для создания ссылки', 'content' => 'Содержимое', 'keywords' => 'Мета-тег keywords', 'description' => 'Мета-тег description', ]; } }
<?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 { public function behaviors() { return [ 'verbs' => [ 'class' => VerbFilter::class, 'actions' => [ 'delete' => ['POST'], ], ], ]; } /** * Список всех страниц сайта */ public function actionIndex() { $dataProvider = new ActiveDataProvider([ 'query' => Page::find(), ]); return $this->render('index', [ 'dataProvider' => $dataProvider, ]); } /** * Просмотр данных существующей страницы */ public function actionView($id) { return $this->render('view', [ 'model' => $this->findModel($id), ]); } /** * Создание новой страницы сайта */ 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, ]); } /** * Обновление существующей страницы */ 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, ]); } /** * Удаление существующей страницы */ public function actionDelete($id) { $this->findModel($id)->delete(); return $this->redirect(['index']); } /** * Поиск страницы по идентификатору */ protected function findModel($id) { if (($model = Page::findOne($id)) !== null) { return $model; } throw new NotFoundHttpException('The requested page does not exist.'); } }
View-шаблоны для страниц
<?php /* * Страница списка всех страниц, файл modules/admin/views/page/index.php */ use yii\helpers\Html; use yii\grid\GridView; /* @var $this yii\web\View */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = 'Все страницы'; ?> <h1><?= Html::encode($this->title); ?></h1> <p> <?= Html::a('Добавить страницу', ['create'], ['class' => 'btn btn-success']); ?> </p> <?= GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'name', 'slug', [ 'attribute' => 'parent_id', 'value' => function($data) { $parent = $data->getParentName(); return empty($parent) ? 'Без родителя' : $parent; } ], [ 'attribute' => 'keywords', 'value' => function($data) { return empty($data->keywords) ? 'Не задано' : $data->keywords; } ], [ 'attribute' => 'description', 'value' => function($data) { return empty($data->description) ? 'Не задано' : $data->description; } ], ['class' => 'yii\grid\ActionColumn'], ], ]); ?>
<?php /* * Страница просмотра страницы, файл modules/admin/views/page/view.php */ use yii\helpers\Html; use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Page */ $this->title = 'Просмотр страницы: ' . $model->name; ?> <h1><?= Html::encode($this->title); ?></h1> <p> <?= Html::a('Изменить', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> <?= Html::a('Удалить', ['delete', 'id' => $model->id], [ 'class' => 'btn btn-danger', 'data' => [ 'confirm' => 'Вы уверены, что хотите удалить эту страницу?', 'method' => 'post', ], ]) ?> </p> <?= DetailView::widget([ 'model' => $model, 'attributes' => [ 'name', 'slug', [ 'attribute' => 'parent_id', 'value' => $model->getParentName() ], [ 'attribute' => 'content', 'value' => empty($model->content) ? 'Не задано' : $model->content, 'format' => 'html' ], [ 'attribute' => 'keywords', 'value' => empty($model->keywords) ? 'Не задано' : $model->keywords ], [ 'attribute' => 'description', 'value' => empty($model->description) ? 'Не задано' : $model->description ], ], ]); ?>
<?php /* * Страница добавления новой страницы, файл modules/admin/views/page/create.php */ use yii\helpers\Html; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Page */ $this->title = 'Добавить страницу'; ?> <h1><?= Html::encode($this->title) ?></h1> <?= $this->render( '_form', ['model' => $model] ); ?>
<?php /* * Страница редактирования страницы, файл modules/admin/views/page/update.php */ use yii\helpers\Html; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Page */ $this->title = 'Редактирование страницы: ' . $model->name; ?> <h1><?= Html::encode($this->title); ?></h1> <?= $this->render( '_form', ['model' => $model] ); ?>
<?php /* * Форма для добавления и редактирования страницы, файл modules/admin/views/page/_form.php */ use app\modules\admin\models\Page; use mihaildev\ckeditor\CKEditor; use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Page */ /* @var $form yii\widgets\ActiveForm */ ?> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'name')->textInput(['maxlength' => true]); ?> <?= $form->field($model, 'slug')->textInput(['maxlength' => true]); ?> <?php // при редактировании существующей страницы нельзя допустить, // чтобы в качестве родителя была выбрана эта же страница $exclude = 0; if (!empty($model->id)) { $exclude = $model->id; } echo $form->field($model, 'parent_id')->dropDownList(Page::getRootPages($exclude)); ?> <?= $form->field($model, 'content')->widget( CKEditor::class, [ 'editorOptions' => [ // разработанны стандартные настройки basic, standard, full 'preset' => 'basic', 'inline' => false, // по умолчанию false ], ] ); ?> <?= $form->field($model, 'keywords')->textarea(['rows' => 2, 'maxlength' => true]); ?> <?= $form->field($model, 'description')->textarea(['rows' => 2, 'maxlength' => true]); ?> <div class="form-group"> <?= Html::submitButton('Сохранить', ['class' => 'btn btn-success']) ?> </div> <?php ActiveForm::end(); ?>
- Магазин на Yii2, часть 32. Админка: удаление категорий и CRUD для страниц
- Магазин на Yii2, часть 31. Админка: загрузка изображений для категорий и брендов
- Магазин на Yii2, часть 30. Админка: WYSIWYG-редактор и изображение для товара
- Магазин на Yii2, часть 29. Админка: добавляем список товаров категории
- Магазин на Yii2, часть 28. Админка: выбор родителя и список всех категорий
- Магазин на Yii2, часть 27. Админка: приводим в порядок сгенерированный код
- Магазин на Yii2, часть 26. Админка: модели и контроллеры для категорий и товаров
Поиск: CRUD • Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Панель управления • Практика • Страница сайта • Фреймворк