Массовое присвоение параметров класса из разных источников

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Объект 417
Сообщения: 116
Зарегистрирован: 2012.06.08, 18:56
Контактная информация:

Массовое присвоение параметров класса из разных источников

Сообщение Объект 417 »

Доброго времени суток.

Не всегда удобно использовать в представлении данные из контроллера в том виде, в котором они приходят изначально. Скажем страница с информацией о пользователе. Из контроллера я передаю AR-запись и в нужном месте вставляю

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

<?php echo $user->login; ?>
и получаю логин. Вроде все хорошо. Php-кода, вставленого в HTML мало и с первого взгляда понятно где php, а где html.

Но в некоторых моментах, этого недостаточно. К примеру дата регистрации выводится так:

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

<?php echo LDateTime::formatDate($user->date_reg, true, false, 2); ?>
, а для отрисовки аватара вообще используется виджет с 3 переменными, что дает нам запись php-кода в 3-5 строчек.

Таким образом файлы представления часто становятся запутанными и неаккуратными.

Что бы справится с такой проблемой я использую специальные класс-контейнеры, которые содержат в себе необходимые данные и методы для их корректного вывода. К коде контроллера, я инициализирую этот класс, присваиваю его парамерам полученные из бд данные и отправляю его в представление. Вот пример такого контроллера (упроченный):

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

<?php
/**
 * Пользователь (сущность).
 */
class SUser
{
    /**
     * Id.
     * @var int
     */
    public $id;

    /**
     * Логин.
     * @var string
     */
    public $login;44

    /**
     * Дата регистрации.
     * @var string
     */
    public $dateReg;

    /**
     * Возвращает id пользователя.
     * @return void
     */
    public function getId()
    {
        echo $this->id;
    }

    /**
     * Отрисовывает аватар пользователя.
     * @return void
     */
    public function getAvatar()
    {
        // Здесь вызывается виджет...
    }

    /**
     * Возвращает логин пользователя.
     * @return void
     */
    public function getLogin()
    {
        // Тоже специальный виджет...
    }

    /**
     * Возвращает дату регистрации.
     * @return void
     */
    public function getDateReg()
    {
        echo LDateTime::formatDate($this->dateReg, true);
    }
}
И теперь вместо того, что бы вызывать виджет для отрисовки аватара прямо из html я просто пишу:

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

<?php $user->getAvatar(); ?>
Приходится писать лишний класс, зато в представлении все очень аккуратно и понятно, что для меня важнее.

Но присваивать все параметры вручную неудобно. Хотелось бы реализовать метод на подобии метода в AR. Что бы можно было сделать так: $user->setAttributes($MUser).
Моно было бы слизать метод из AR attributes, но данные не всегда приходят из AR, часто получаются в виде массива (из DAO), а не объекта (AR). Подскажите, как реализовать такое массовое присваивание?

Буду очень благодарен!

Аватара пользователя
aser
Сообщения: 167
Зарегистрирован: 2009.04.02, 14:25
Откуда: Киев

Re: Массовое присвоение параметров класса из разных источник

Сообщение aser »

Ну первое. PHP в шаблоне не так уж и плохо, главное понимать что логика приложения отдельно, а визуализация данных(представление,интерфейс) отдельно.
Второе. Некоторые функции дополнительной обработки данных наверное лучше оставить в модели, таким образом не плодить лишнего и запутанного, не плодя лишних файлов. Если большой самостоятельный кусок шаблона, можно вынести в хелпер, виджет, подшаблон...
Третье и больше по сути вопроса. Функция CModel::setAttributes(array $values, boolean $safeOnly=true) принимает массив, а не объект, так что слизать получиться. Подробнее http://www.yiiframework.com/doc/api/1.1 ... tes-detail

Аватара пользователя
mitaichik
Сообщения: 512
Зарегистрирован: 2010.09.24, 21:18
Откуда: Россия, Санкт-Петербург

Re: Массовое присвоение параметров класса из разных источник

Сообщение mitaichik »

Зачем использовать доп. класс, когда все это можно запихнуть в модель юзера? Хотя это конечно не есть гуд, ибо мешаешь логику\представление...
Кто мешает написать хелперы вывода, или сделать виджет аватарки, куда нужно передовать не три параметра, а например, толкько модель юзера?
Вообще, свойства классов можно задавать по умолчанию, что бы в большинстве случаев их не определять, и в виджетах это можно сделать.

Имхо, проблема из пальца высасана.

но по теме: делай метод

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

    public function setAttributes($model){
        foreach ($model->attributeNames() as $key)
            $this->$key = $model->$key;
    }
 

Объект 417
Сообщения: 116
Зарегистрирован: 2012.06.08, 18:56
Контактная информация:

Re: Массовое присвоение параметров класса из разных источник

Сообщение Объект 417 »

Спасибо за ответ.

P.S.
mitaichik писал(а):Зачем использовать доп. класс, когда все это можно запихнуть в модель юзера?
Напихать все это в модель нельзя потому, что иногда данные выбираются при помощи AR, а иногда при помощи DAO (чистым sql запросом), когда как удобнее.
mitaichik писал(а):Кто мешает написать хелперы вывода, или сделать виджет аватарки, куда нужно передовать не три параметра, а например, толкько модель юзера?
Так этот класс по сути и есть хелпер. А передаю отдельные параметры потому, что, как я уже говорим, модель есть не всегда.
mitaichik писал(а): Вообще, свойства классов можно задавать по умолчанию, что бы в большинстве случаев их не определять, и в виджетах это можно сделать.
Свойств, которые можно было бы задать по умолчанию очень мало. Скажем, виджет, который выводит логин пользователя в виде ссылки на профиль и раскрашенный в цвет группы. Передаем ему id пользователя, логин, цвет группы и тип ссылки (url или ajax). Из всего этого по умолчанию можно только тип ссылки задать.

Я бы и не заморачивался на эту тему, но уж много логики в представление пихается. А мой коллега (верстальщик-дизайнер) ругается. Лишний код глаза мозолит.

Объект 417
Сообщения: 116
Зарегистрирован: 2012.06.08, 18:56
Контактная информация:

Re: Массовое присвоение параметров класса из разных источник

Сообщение Объект 417 »

aser писал(а):Ну первое. PHP в шаблоне не так уж и плохо, главное понимать что логика приложения отдельно, а визуализация данных(представление,интерфейс) отдельно.
Второе. Некоторые функции дополнительной обработки данных наверное лучше оставить в модели, таким образом не плодить лишнего и запутанного, не плодя лишних файлов. Если большой самостоятельный кусок шаблона, можно вынести в хелпер, виджет, подшаблон...
Третье и больше по сути вопроса. Функция CModel::setAttributes(array $values, boolean $safeOnly=true) принимает массив, а не объект, так что слизать получиться. Подробнее http://www.yiiframework.com/doc/api/1.1 ... tes-detail
Спасибо большое за развернутый ответ (сразу не заметил :) ). В модули и так довольно много. Буду с модели слизывать...

Аватара пользователя
mitaichik
Сообщения: 512
Зарегистрирован: 2010.09.24, 21:18
Откуда: Россия, Санкт-Петербург

Re: Массовое присвоение параметров класса из разных источник

Сообщение mitaichik »

Объект 417 писал(а):Свойств, которые можно было бы задать по умолчанию очень мало. Скажем, виджет, который выводит логин пользователя в виде ссылки на профиль и раскрашенный в цвет группы. Передаем ему id пользователя, логин, цвет группы и тип ссылки (url или ajax). Из всего этого по умолчанию можно только тип ссылки задать.
Имхо нужно сделать виджет с двумя параметрами: модель юзера и тип ссылки. А логин, ид, группы - это все берется из модели юзера. При этом если хочешь - вместо модели юзера можешь передовать и массив из DAO - CModel поддерживает ArrayAccess, так что с ним можно работать как с массивом.

Ответить