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


(Djos) #1

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

Поступила задача, нужно переделать «Карту О» под новый дизайн. В проекте уже сделаны 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.
Url пользовательской Карты О - /user/<ID>/card, ajax - /user/cards/o/<action>?id=<ID>. Сделать /user/<ID>/cards/o/<action> не получилась, сайт незнает такой роутер.

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

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