Магазин на Yii2, часть 29. Админка: добавляем список товаров категории
10.09.2019
Теги: CRUD • Web-разработка • Yii2 • ИнтернетМагазин • КаталогТоваров • ПанельУправления • Практика • Фреймворк
Сейчас для действия index
контроллера ProductController
показывается список всех товаров каталога. Найти в этом длинном списке нужный товар, чтобы его отредактировать, довольно проблематично. Давайте на страницу списка всех категорий добавим еще одну ссылку, которая позволит просмотреть список товаров каждой категории. Для этого добавим метод actionProducts()
для контроллера CategoryController
:
<?php namespace app\modules\admin\controllers; use app\modules\admin\models\Product; use Yii; use app\modules\admin\models\Category; use yii\data\ActiveDataProvider; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; /** * Класс CategoryController реализует CRUD для категорий */ class CategoryController extends AdminController { /*...*/ /** * Список всех товаров категории */ public function actionProducts($id) { // получаем массив идентификаторов всех потомков категории, // чтобы запросом выбрать товары и в дочерних категориях $ids = Category::getAllChildIds($id); $ids[] = $id; $products = new ActiveDataProvider([ 'query' => Product::find()->where(['in', 'category_id', $ids]) ]); return $this->render( 'products', [ 'category' => $this->findModel($id), 'products' => $products, ] ); } /*...*/ }
Теперь добавим ссылку для просмотра товаров категории в view-шаблон:
<?php /* * Страница списка всех категорий, файл modules/admin/views/category/index.php */ use yii\helpers\Html; /* @var $this yii\web\View */ $this->title = 'Категории каталога'; ?> <h1><?= Html::encode($this->title); ?></h1> <p> <?= Html::a('Добавить категорию', ['create'], ['class' => 'btn btn-success']); ?> </p> <table class="table table-striped table-bordered"> <thead> <tr> <th>Наименование</th> <th>Мета-тег keywords</th> <th>Мета-тег description</th> <th><span class="glyphicon glyphicon-list"></span></th> <th><span class="glyphicon glyphicon-eye-open"></span></th> <th><span class="glyphicon glyphicon-pencil"></span></th> <th><span class="glyphicon glyphicon-trash"></span></th> </tr> </thead> <tbody> <?php foreach ($categories as $category): ?> <tr> <td><?= $category['name']; ?></td> <td><?= $category['keywords']; ?></td> <td><?= $category['description']; ?></td> <td> <?php echo Html::a( '<span class="glyphicon glyphicon-list"></span>', ['/admin/category/products', 'id' => $category['id']] ); ?> </td> <td> .......... </td> <td> .......... </td> <td> .......... </td> </tr> <?php endforeach; ?> </tbody> </table>
Создадим новый view-шаблон для списка товаров категории:
<?php /* * Страница списка товаров категории, файл modules/admin/views/category/products.php */ use yii\helpers\Url; use yii\helpers\Html; use yii\grid\GridView; /* @var $this yii\web\View */ /* @var $category app\modules\admin\models\Category */ /* @var $products yii\data\ActiveDataProvider */ $this->title = 'Товары категории: ' . $category->name; ?> <h1><?= Html::encode($this->title) ?></h1> <p> <?= Html::a( 'Добавить товар', ['/admin/product/create', 'category' => $category->id], ['class' => 'btn btn-success'] ); ?> </p> <?= GridView::widget([ 'dataProvider' => $products, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'name', [ 'attribute' => 'category_id', 'value' => function($data){ return $data->getCategoryName(); } ], [ 'attribute' => 'brand_id', 'value' => function($data){ return $data->getBrandName(); } ], 'price', [ 'attribute' => 'hit', 'value' => function($data) { return $data->hit ? 'Да' : 'Нет'; } ], [ 'attribute' => 'new', 'value' => function($data) { return $data->new ? 'Да' : 'Нет'; } ], [ 'attribute' => 'sale', 'value' => function($data) { return $data->sale ? 'Да' : 'Нет'; } ], [ 'class' => 'yii\grid\ActionColumn', 'urlCreator' => function ($action, $model, $key, $index) { return Url::to(['/admin/product/'.$action, 'id' => $model->id]); } ], ], ]); ?>
И нам еще потребуется метод в модели Category
, который позволит получить идентификаторы всех потомков категории:
<?php namespace app\modules\admin\models; use yii\db\ActiveRecord; /** * Это модель для таблицы БД `category` */ class Category extends ActiveRecord { /*...*/ /** * Возвращает массив идентификаторов всех потомков категории $id, * т.е. дочерние, дочерние дочерних и так далее */ public static function getAllChildIds($id) { $children = []; $ids = self::getChildIds($id); foreach ($ids as $item) { $children[] = $item; $c = self::getAllChildIds($item); foreach ($c as $v) { $children[] = $v; } } return $children; } /** * Возвращает массив идентификаторов дочерних категорий (прямых * потомков) категории с уникальным идентификатором $id */ protected static function getChildIds($id) { $children = self::find()->where(['parent_id' => $id])->asArray()->all(); $ids = []; foreach ($children as $child) { $ids[] = $child['id']; } return $ids; } /*...*/ }
Обратите внимание, что ссылка на добавление товара в шаблоне products.php
имеет вид:
<p> <?= Html::a( 'Добавить товар', ['/admin/product/create', 'category' => $category->id], ['class' => 'btn btn-success'] ); ?> </p>
Это для того, чтобы в выпадающем списке выбора родителя сразу установить нужное значение. Вот как это работает:
<?php /* * Форма для добавления и редактирования товара, файл modules/admin/views/product/_form.php */ use app\modules\admin\models\Brand; use app\modules\admin\models\Category; use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\modules\admin\models\Product */ /* @var $form yii\widgets\ActiveForm */ ?> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'name')->textInput(['maxlength' => true]); ?> <?php $category = Yii::$app->request->get('category') ?: 0; $param = ['options' => [$category => ['selected' => true]]]; echo $form->field($model, 'category_id')->dropDownList(Category::getTree(), $param); ?> <?= $form->field($model, 'brand_id')->dropDownList( ArrayHelper::map(Brand::find()->all(), 'id', 'name') ); ?> <?= $form->field($model, 'price')->textInput(['maxlength' => true]); ?> <?= $form->field($model, 'image')->textInput(['maxlength' => true]); ?> <?= $form->field($model, 'content')->textarea(['rows' => 6]); ?> <?= $form->field($model, 'keywords')->textarea(['rows' => 2, 'maxlength' => true]); ?> <?= $form->field($model, 'description')->textarea(['rows' => 2, 'maxlength' => true]); ?> <?= $form->field($model, 'hit')->textInput(); ?> <?= $form->field($model, 'new')->textInput(); ?> <?= $form->field($model, 'sale')->textInput(); ?> <div class="form-group"> <?= Html::submitButton('Сохранить', ['class' => 'btn btn-success']) ?> </div> <?php ActiveForm::end(); ?>
- Магазин на Yii2, часть 33. Админка: приводим в порядок CRUD-код для страниц
- Магазин на Yii2, часть 32. Админка: удаление категорий и CRUD для страниц
- Магазин на Yii2, часть 31. Админка: загрузка изображений для категорий и брендов
- Магазин на Yii2, часть 30. Админка: WYSIWYG-редактор и изображение для товара
- Магазин на Yii2, часть 28. Админка: выбор родителя и список всех категорий
- Магазин на Yii2, часть 27. Админка: приводим в порядок сгенерированный код
- Магазин на Yii2, часть 26. Админка: модели и контроллеры для категорий и товаров
Поиск: Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Панель управления • Фреймворк • Практика • CRUD