1 функционал в 2 контроллеах

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Djos
Сообщения: 1
Зарегистрирован: 2019.03.16, 13:07

1 функционал в 2 контроллеах

Сообщение Djos »

Приветствую вас. Мне интересно как бы вы реализовали, но начнем сначала.

Поступила задача, нужно переделать Карту О под новый дизайн. В проекте уже сделаны 3 Карты, Карта Т, Карта Г, а Карта О осталось старой. Карта может быть моей(смотришь свою карту) или пользователя(смотришь у кого-то карту). В моей свой url(/account/card), у пользователя (/user/<ID>/card).  Дизайн Карт у моей и пользователя одинаковый. Отличие минимальные, у моей есть кнопки, и список, а у пользовательской свои кнопки и часть интерфейса скрыта. Между собой Карты по дизайну отличаются сильнее. Поэтому решил что лучше пусть у каждой Карты свои шаблоны. По задачи надо сделать Карту О.

Наследование:
CardController <- AccountController <- MainController – (далее буду писать account\CardController)
CardController <- UserController <- MainController – (далее буду писать user\CardController)

AccountController->user = авторизованный пользователь.
UserController->user = просматриваемы пользователь.

Как реализовано сейчас. Рядом с «user\CardController» лежит «user\CardTrait» в котором был описаны все функции контролер(actionIndex, actionLoadTab). Шаблоны лежали «user\view». В контролерах «user\CardController» и «account\CardController» был подключен trait «user\CardTrait».

account\CardController
 use user\CardTrait

user\CardController
 use user\CardTrait

Изначально я начал разрабатывать мою Карту О. Решил что лучше будет создать свой контроллер для карты «account\cards\OController». Шаблоны положил в «account\views\cards\o». В «user\CardTrait» подправил.

Код: Выделить всё

public function actionIndex()
{
 $user = $this-> user ;

 if ($user->status == 1) {
  return \Yii:: $app ->runAction('account/cards/o'); //перенаправляем Карты О на новый контроллер
 } elseif ($user->status == 2) {
  return $this->_getTaIndex();
 } elseif ($user->status == 3) {
  return $this->_getGuideIndex();
 }

 return null;
}
Все было замечательно, но когда начал делать саму механику моя карта или пользовательская карта, пришел в тупик. При такой реализации, когда заходим по /user/ID/card, в «user\CardTrait->actionIndex()», $user  будет который запрашиваем, но потом идет runAction(), который создает «account\cards\OController» и в нем уже $user авторизованный(т.к. базовый контроллер уже «AccountController»). Тут пошел ко 2 параметру в runAction() и в нем стал передавать $user.
return \Yii::$app->runAction('account/cards/o', ['user' => $user]);

Все было прекрасно, но появилась проблема номер 2. В интерфейсе есть ajax загрузка часть другого интерфейса. Url создавалась через Url::to() и пользовательской Карты О, запросы получались /account/cards/o/<action>. А action есть логика по пользователю, в итоге туда шли данные от авторизованного пользователя, а смотрим мы пользовательскую Карту О.

Как я предложить сделать:

Функционал в «account\cards\OController» положить в «components\cards\OTrait»,
«user\CardTrait» переместить «components\cards\CardTrait».

В классах:

account\cards\CardController
 use components\cards\CardTrait

account\cards\OController
 use components\cards\OTrait

user\cards\CardController
 use components\cards\CardTrait

user\cards\OController
 use components\cards\OTrait

Дальше в account\CardController

Код: Выделить всё

public function actionIndex()
{
 $user = $this->user;

 if ($user->status == 1) {
  return \Yii::$app->runAction('account/cards/o'); //перенаправляем Карты О на новый контроллер
 } else {
  return \Yii::$app->runAction('account/cards/card'); //перенаправляем на Карты Т и Г
 }

}
Дальше в user\CardController

Код: Выделить всё

public function actionIndex()
{
 $user = $this->user ;

 if ($user->status == 1) {
  return \Yii::$app->runAction('user/cards/o'); //перенаправляем Карты О на новый контроллер
 } else {
  return \Yii::$app->runAction('user/cards/card'); //перенаправляем на Карты Т и Г
 }

}
В итоге реализация Карты О в 1 месте, при этом можно у контроллеров «account|user\cards\OController» добавить функционал или изменить его.
Url у моей Карты О - /account/card/, а у ajax - /account/cards/o/<action>.
Url пользовательской Карты О - /user/<ID>/card, ajax - /user/cards/o/<action>?id=<ID>. Сделать /user/<ID>/cards/o/<action> не получилась, сайт незнает такой роутер.

Какие у вас идеи?

Что думаете про мою реализацию?
Ответить