@hollanditkzn

Как облегчить код для отображение счетчиков для отображение количество активных записей?

У меня такая рутина, у меня есть повторяющий код везе в шаблонах добавлять количество активных записей на страницах. Пример, есть навигация, где виднеются все страницы и там идет счетчик активных записей
<?php echo Nav::widget([
    'options' => ['class' => 'nav nav-pills headerNav'],
    'items' => [
        ['label' => 'Заказы <span class="badge pull-right">'.$this->params['scoreZakaz'].'</span>', 'encode' => false, 'url' => ['zakaz/admin'], 'visible' => Yii::$app->user->can('seeAdmin')],
    ['label' => 'Заказы <span class="badge pull-right">'.$this->params['scoreDisain'].'</span>', 'encode' => false, 'url' => ['zakaz/disain'], 'visible' => Yii::$app->user->can('disain')],
    ['label' => 'Заказы <span class="badge pull-right">'.$this->params['scoreMaster'].'</span>', 'encode' => false, 'url' => ['zakaz/master'], 'visible' => Yii::$app->user->can('master')],
    ['label' => 'Заказы <span class="badge pull-right">'.$this->params['scoreZakaz'].'</span>', 'encode' => false, 'url' => ['zakaz/shop'], 'visible' => Yii::$app->user->can('seeShop')],
    ['label' => 'Доставки <span class="badge pull-right">'.$this->params['scoreShipping'].'</span>', 'encode' => false, 'url' => ['courier/index'], 'visible' => Yii::$app->user->can('courier')],
    ['label' => 'Задачи <span class="badge pull-right">'.$this->params['scoreTodoist'].'</span>', 'url' => ['todoist/index'], 'encode' => false, 'visible' => Yii::$app->user->can('admin')],
    ['label' => 'Поломки <span class="badge pull-right">'.$this->params['scoreHelp'].'</span>', 'encode' => false, 'url' => ['helpdesk/index'], 'visible' => !Yii::$app->user->can('courier')],
    ['label' => 'Закупки <span class="badge pull-right">'.$this->params['scoreCustom'].'</span>', 'encode' => false, 'url' => ['custom/adop'], 'visible' => Yii::$app->user->can('seeAdop')],
    ['label' => 'Доставки <span class="badge pull-right">'.$this->params['scoreShipping'].'</span>', 'encode' => false, 'url' => ['courier/shipping'], 'visible' => Yii::$app->user->can('admin')],
    ['label' => 'Закупки', 'url' => ['custom/index'], 'visible' => Yii::$app->user->can('zakup')],
    ['label' => 'Задачи <span class="badge pull-right">'.$this->params['scoreTodoist'].'</span>', 'encode' => false,'url' => ['todoist/shop'], 'visible' => Yii::$app->user->can('todoist')],
    ],
]); ?>
<?php endif ?>

И мне приходится в контроллере прописывать вот такую конструкцию для каждого action
public function actionMaster()
    {
        $searchModel = new ZakazSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams, 'master');
        $notification = $this->findNotification();
        $scoreZakaz = $this->findScorezakaz('master');//количество заказов для роли мастер
        $scoreTodoist = $this->findScoretodoist('adop');//количество задач
        $scoreHelp = $this->findScorehelp();//количество запросов

        return $this->render('master', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'scoreZakaz' => $scoreZakaz,
            'scoreTodoist' => $scoreTodoist,
            'scoreHelp' => $scoreHelp,
            'notification' => $notification,
        ]);
    }
/**
     * Finds the Zakaz model based on its role value
     * @param $role
     * @return int|string
     */
    protected function findScorezakaz($role)
    {
        $score = Zakaz::find();
//Пришел какая роль, то выполняется одно из условии и активных заказов в базе данных у данной роли
        switch ($role) {
            case 'admin':
                return $this->view->params['scoreZakaz'] = $score->andWhere(['action' => 1])->count();
                break;
            case 'shop':
                return $this->view->params['scoreZakaz'] = $score->andWhere(['id_sotrud' => Yii::$app->user->id, 'action' => 1])->count();
                break;
            case 'disain':
                return $this->view->params['scoreDisain'] = $score->andWhere(['status' => [Zakaz::STATUS_DISAIN, Zakaz::STATUS_SUC_DISAIN, Zakaz::STATUS_DECLINED_DISAIN], 'action' => 1])->count();
                break;
            case 'master':
                return $this->view->params['scoreMaster'] = $score->andWhere(['status' => [Zakaz::STATUS_MASTER, Zakaz::STATUS_SUC_MASTER, Zakaz::STATUS_DECLINED_MASTER], 'action' => 1])->count();
                break;
        }
    }

    /**
     * Finds the Todoist model based on its role value
     * @param $role
     * @return int|string
     */
    protected function findScoretodoist($role)
    {
        $score = Todoist::find();
//если админ, то количество задач пишут все активные, если пришло что-то другое то высвечиваются все активные задачи для определенного пользователя
        switch ($role) {
            case 'admin':
                return $this->view->params['scoreTodoist'] = $score->andWhere(['activate' => 0])->count();
                break;
            case 'adop':
                return $this->view->params['scoreTodoist'] = $score->andWhere(['id_user' => Yii::$app->user->id, 'activate' => 0])->count();
                break;
        }
    }

    /**
     * Finds the Helpdesk model
     */
    protected function findScorehelp()
    {
        $score = Helpdesk::find();
        $this->view->params['scoreHelp'] = $score->andWhere(['id_user' => Yii::$app->user->id, 'status' => 0])->count();
    }

    /**
     * Finds the Custom model
     */
    protected function findScorecustom()
    {
        $score = Custom::find();
        $this->view->params['scoreCustom'] = $score->andWhere(['id_user' => Yii::$app->user->id, 'action' => 0])->count();
    }

    /**
     * Finds the Courier model
     */
    protected function findScoreshipping()
    {
        $score = Courier::find();
        $this->view->params['scoreShipping'] = $score->andWhere(['<','status', Courier::DELIVERED])->count();
    }

Как можно облегчить данный код, просто думал, может событие, но так как я можно сказать не разу не пользовался ими как можно было их улучшить?
То есть повторяется вот этот код
$scoreZakaz = $this->findScorezakaz('master');
        $scoreTodoist = $this->findScoretodoist('adop');
        $scoreHelp = $this->findScorehelp();
  • Вопрос задан
  • 177 просмотров
Решения вопроса 2
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
Наверное стоит вынести это в компонент, в компоненте предусмотреть кеширование. Выводить используя виджет, который будет получать данные из компонента.
Ответ написан
Комментировать
@k2lhu
Первое что пришло в голову - вынести все в отдельный виджет, сделать папочку components (или любую другую как вам удобнее), и в ней просто сделать свой виджет.
А затем уже его цеплять на необходимых страницах.
Ведь ваш собственный виджет может без проблем использовать собственные контроллеры и представления, и точно так же и как и любой экшн отдавать на отрисовку представление.
Единожды описав виджет, вы просто подцепляете его везде где надо, примерно так
<?= \app\components\NewsWidget::widget(['param' => 'index']) ?>

Данная строка у меня вызывает у меня везде где я ее пропишу блок со списком последних новостей, статистику по количеству новостей (старые, новые, непрочитанные). Виджет имеет собственный контроллер и собственное представление. Модели для виджета спокойно можно использовать уже существующие, либо опять же, добавить свои.

Вариант номер 2 - если у вас много повторяющего кода, вынесите его в модель, и вызывайте его как событие перед рендерингом страницы, т.е. грубо говоря своеобразная middleware. Думаю тут необходимо будет дополнительно почитать про поведение.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы