Магазин на Yii2, часть 24. Админка: модель, контроллер и представления для заказов

28.08.2019

Теги: CRUDWeb-разработкаYii2ЗаказИнтернетМагазинКаталогТоваровПанельУправленияПрактикаФреймворк

Чтобы создать модель для работы с заказами в админке — используем генератор кода. Переходим по ссылке «Model Generator», задаем имя таблицы БД, имя класса модели и пространство имен:

Table Name: order
Model Class Name: Order
Namespace: app\modules\admin\models

Далее жмем кнопку «Preview» и после этого — «Generate». В итоге получаем класс модели:

<?php
namespace app\modules\admin\models;

use Yii;

/**
 * This is the model class for table "order".
 *
 * @property int $id Идентификатор заказа
 * @property int $user_id Идентификатор пользователя
 * @property string $name Имя и фамилия покупателя
 * @property string $email Почта покупателя
 * @property string $phone Телефон покупателя
 * @property string $address Адрес доставки
 * @property string $comment Комментарий к заказу
 * @property string $amount Сумма заказа
 * @property int $status Статус заказа
 * @property string $created Дата и время создания
 * @property string $updated Дата и время обновления
 */
class Order extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'order';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['user_id', 'status'], 'integer'],
            [['amount'], 'number'],
            [['created', 'updated'], 'safe'],
            [['name', 'email', 'phone'], 'string', 'max' => 50],
            [['address', 'comment'], 'string', 'max' => 255],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'user_id' => 'User ID',
            'name' => 'Name',
            'email' => 'Email',
            'phone' => 'Phone',
            'address' => 'Address',
            'comment' => 'Comment',
            'amount' => 'Amount',
            'status' => 'Status',
            'created' => 'Created',
            'updated' => 'Updated',
        ];
    }
}

Теперь используем «CRUD Generator», который создаст нам контроллер и view-шаблоны. И мы получим готовой код для создания, просмотра, редактирования и удаления заказов.

Model Class: app\modules\admin\models\Order
Controller Class: app\modules\admin\controllers\OrderController
View Path: @app/modules/admin/views/order
Base Controller Class: app\modules\admin\controllers\AdminController

Перейдем по адресу /admin/order/index и посмотрим на результат работы GRUD генератора:

Хорошо, теперь займемся приведением в порядок того кода, который сформировал герератор. Начнем с класса модели:

<?php
namespace app\modules\admin\models;

use yii\db\ActiveRecord;

/**
 * Это модель для таблицы БД `order`
 *
 * @property int $id Идентификатор заказа
 * @property int $user_id Идентификатор пользователя
 * @property string $name Имя и фамилия покупателя
 * @property string $email Почта покупателя
 * @property string $phone Телефон покупателя
 * @property string $address Адрес доставки
 * @property string $comment Комментарий к заказу
 * @property string $amount Сумма заказа
 * @property int $status Статус заказа
 * @property string $created Дата и время создания
 * @property string $updated Дата и время обновления
 */
class Order extends ActiveRecord {
    /**
     * Возвращает имя таблицы базы данных
     */
    public static function tableName() {
        return 'order';
    }

    /**
     * Правила валидации полей формы при редактировании заказа
     */
    public function rules() {
        return [
            [['user_id', 'status'], 'integer'],
            [['amount'], 'number'],
            [['created', 'updated'], 'safe'],
            [['name', 'email', 'phone'], 'string', 'max' => 50],
            [['address', 'comment'], 'string', 'max' => 255],
        ];
    }

    /**
     * Возвращает имена полей формы для редактирования заказа
     */
    public function attributeLabels() {
        return [
            'id' => 'Номер',
            'user_id' => 'User ID',
            'name' => 'Имя',
            'email' => 'Почта',
            'phone' => 'Телефон',
            'address' => 'Адрес доставки',
            'comment' => 'Комментарий',
            'amount' => 'Сумма',
            'status' => 'Статус',
            'created' => 'Дата создания',
            'updated' => 'Дата обновления',
        ];
    }
}

Отредактируем view-шаблон списка заказов — уберем кнопку «Create Order», поменяем заголовок и изменим состав полей, которые выводятся в таблице:

<?php
/*
 * Файл view-шаблона modules/admin/views/order/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>

<?=
GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        'id',
        'name',
        'email:email',
        'phone',
        'amount',
        [
            'attribute' => 'status',
            'value' => function ($data) {
                switch ($data->status) {
                    case 0: return '<span class="text-danger">Новый</span>';
                    case 1: return '<span class="text-warning">Обработан</span>';
                    case 2: return '<span class="text-warning">Оплачен</span>';
                    case 3: return '<span class="text-warning">Доставлен</span>';
                    case 4: return '<span class="text-success">Завершен</span>';
                    default: return 'Ошибка';
                }
            },
            'format' => 'html'
        ],
        'created',
        'updated',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]);
?>

И вот что у нас получилось в итоге:

Благодаря тому, что мы используем провайдер данных и виджет данных GridView, автоматически получаем постраничное разделение данных. Кроме того, заказы можно отсортировать по любому полю, в том числе по статусу, так что наверху будут новые заказы, а внизу — завершенные.

Но для удобства работы желательно, чтобы заказы изначально были отсортированы по статусу. Для этого внесем изменения в контроллер:

<?php
namespace app\modules\admin\controllers;

use Yii;
use app\modules\admin\models\Order;
use yii\data\ActiveDataProvider;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
 * Класс OrderController реализует CRUD для заказов
 */
class OrderController extends AdminController {

    public function behaviors() {
        return [
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Список всех заказов с постраничной навигацией
     * и сортировкой по статусу
     */
    public function actionIndex() {
        $dataProvider = new ActiveDataProvider([
            'query' => Order::find(),
            'pagination' => [
                'pageSize' => 5 // пять заказов на страницу
            ],
            'sort' => [
                'defaultOrder' => [
                    // сортировка по статусу, по возрастанию
                    'status' => SORT_ASC
                ]
            ]
        ]);
        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Просмотр данных существующего заказа
     */
    public function actionView($id) {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Создание нового заказа, метод не используется
     */
    public function actionCreate() {
        $model = new Order();
        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 = Order::findOne($id)) !== null) {
            return $model;
        }
        throw new NotFoundHttpException('Заказ не найден');
    }
}

Поиск: Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Фреймворк • Панел управления • Заказ • Админка • Gii • CRUD

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.