Очень часто, для административных целей при работе с пользователями, постами, комментариями и тд. в соответствующих таблицах базы данных создается специальное поле «status». Называться оно может и по другому но выполняет всегда одну роль – в зависимости от указанного в нем значения меняется логика обработки данных.

Например для таблицы posts с постами, данное поле может принимать значения:
  • черновик (draft);
  • опубликован (publish);
и тд.
Таким образом программист может настроить вывод только опубликованных постов для просмотра посетителю сайта.



Сам фреймворк yii2 версии Advanced по-умолчанию так же использует такую схему работы с пользователями, устанавливая им статус "активен" или "удален".

Поэтому стоит подробнее разобраться как настроить работу с полем «status». В данной заметке Разберемся с выводом данного поля с помощью стандартного для yii2 виджета GridView (и не только), которой очень часто используется при создании административной части с помощью CRUD. Для примера будет использоваться таблица posts.


Создание поля в БД.
Создаем поле status для таблицы posts. По аналогии с миграцией создания пользователя для этого в своем файле миграции прописываем строку
'status' => $this->smallInteger()->notNull()->defaultValue(0),
которая создаст поле status со значением по-умолчанию «0». Т.е. для обозначения статусов будем использовать цифровые значения.


Модель(сущность) Post.
Далее создаем или генерируем модель Post, где прописываем все нужные статусы в виде констант:
const STATUS_DRAFT = 0; //черновик
const STATUS_PUBLISH = 10; //опубликован

Таким образом видно, что по-умолчанию используется статус 0, т.е. «черновик», а по завершению редактирования администратор вручную поменяет статус поста и он станет доступным для просмотра посетителями сайта. Сами цифры могут быть любые, не обязательно 0 или 10.

Для валидации в методе rules нам нужны такие правила касающиеся поля 'status':
['status', 'default', 'value' => self::STATUS_DRAFT],
['status', 'in', 'range' => [self::STATUS_DRAFT, self::STATUS_PUBLISH]],
Вторым правилом мы разрешаем выбор одного из указанных значений, что бы в таблицу не попало что-то лишнее.



Вспомогательный класс – helper.
По-умолчанию, при выводе в виджете GridView, в поле фильтрации нужно вручную вводить 0 или 10 или другие числа, которые нужно найти в БД. Так же, в строках снизу выводятся числовые значения, с которыми работать не удобно. Нам же хочется видеть статусы в виде соответствующих слов, а в поле фильтрации не вводить что-то, а выбирать из списка доступных статусов.

Для того, что бы сделать такие удобства необходимо написать нужный функционал. Вынесем его в дополнительный класс – помощник, т.к. не в контроллере не в сущности «Post» ему не место.
Файл common/helpers/PostHelper.php:
<?php

namespace common\helpers;

use common\models\Post;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;

class PostHelper
{
    public static function statusList(): array
    {
        return [
            Post::STATUS_DRAFT => 'Черновик',
            Post::STATUS_PUBLISH => 'Опубликован',
        ];
    }

    public static function statusName($status): string
    {
        return ArrayHelper::getValue(self::statusList(), $status);
    }

    public static function statusLabel($status): string
    {
        switch ($status) {
            case Post::STATUS_DRAFT:
                $class = 'label label-danger';
                break;
            case Post::STATUS_PUBLISH:
                $class = 'label label-success';
                break;
            default:
                $class = 'label label-default';
        }

        return Html::tag('span', ArrayHelper::getValue(self::statusList(), $status), [
            'class' => $class,
        ]);
    }
}

В методе statusList прописываем значения для выпадающего списка. Метод statusName будет получать для виджета GridView значение в виде строки соответствующее числовому значению из БД используя как раз метод statusList. Ну а метод statusLabel используется для создания элемента <span> с классом в зависимости от текущего статуса. Например, статус «черновик» выведем в красной рамке, что бы администратор его не упустил из виду, а статус «опубликован» - в зеленой.


Вывод - корректируем виджеты.

index.php
Для создания/редактирования и др. постов генерируем CRUD, который создаст нам контроллер с соответствующими действиями и видами. Основной файл представления index.php по-умолчанию использует GridView. необходимо найти там подключение поля «status» и заменить на такой блок:
[
    'attribute' => 'status',
    'filter' => \common\helpers\PostHelper::statusList(),
    'value' => function (\common\models\Post $model) {
        return \common\helpers\PostHelper::statusLabel($model->status);
    },
    'format' => 'raw',
],

Пространства имен классов, можно прописать вверху файла используя директиву «use».
В результате получим красивое и человеческое обозначение текущего статуса поста и удобный выпадающий список для фильтрации:


view.php
Стоит подкорректировать вид отвечающий за просмотр отдельного поста - view.php что бы там так же вместо цифр 0 или 10 у нас было человеко-понятное значение в цветной рамке. Для этого вместо
'status', 
вставляем (виджет DetailView):
[
    'attribute' => 'status',
    'value' => function (\common\models\Post $model) {
        return \common\helpers\PostHelper::statusLabel($model->status);
    },
    'format' => 'raw',
],


form.php
При создании новой записи или редактировании существующей подключается файл form.php выводящий поля формы для заполнения. Используя созданный выше помощник создадим там выпадающий список для выбора нужного статуса (виджет ActiveForm):
<?= $form->field($model, 'status')->dropDownList(\common\helpers\PostHelper::statusList()) ?>