Страница 1 из 2

Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.06.30, 05:47
resurtm
Новый рецепт: http://yiiframework.ru/doc/cookbook/ru/ ... .fat.model

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

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.06.30, 10:42
slavcodev
Так не красивее?

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

public function rules()
    {
        return array(
            array('title','required'),
            array('document','file','types'=>'doc,docx,xls,xlsx,odt,pdf','allowEmpty'=>true, 'safe' => false),
        );
    }

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.06.30, 10:46
slavcodev
// валидируем вручную, потому как изменить метод rules() у $owner мы не можем и правил всего два
почему не можим?

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

public function attach($owner)
{
  $fileValidator = CValidator::create('file', $this->attributeName, $params);
  $owner->validatorList->add($fileValidator);
} 

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.06.30, 15:27
resurtm
Спасибо! :)

Оформил в PR: https://github.com/samdark/yiiframework ... ook/pull/5

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.01, 20:50
samdark
Влил на сайт.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.14, 23:55
SpiLLeR
Фраза: "Так, например, мы не учли ситуацию, когда две разные модели могут иметь два файла с одним и тем-же файлом." кажется взрывает мозг). Наверное два файла с одинаковым именем.

В поведении beforeDelete() не чего не должен возвращать? типа boolean? И я бы удалял файлы в afterDelete(), хотя это уже больше логика приложения.

Еще бы неплохо как-то обозначить момент проверки существования\создания папки где хранятся файлы и на отсутствие кинуть исключение. Я понимаю, что это мб выходит за пределы рецепта, но это по моему неотъемлемая часть.

З.Ы. Странно что есть такой классный метод: getValidatorList(), а для relations такого нет =/

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.19, 11:13
resurtm
Да, спасибо за замечания, на днях поправлю. :-)

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.19, 11:21
slavcodev
SpiLLeR писал(а):З.Ы. Странно что есть такой классный метод: getValidatorList(), а для relations такого нет =/
Почему нет :mrgreen:

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

$model = Post::model();
$model->metaData->addRelation('comments', array(
    ActiveRecord::HAS_MANY, 'Comment', 'postId',
)); 

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.19, 11:45
SpiLLeR
Во спасибо, а я свой велосипед написал.
З.Ы. класса ActiveRecord в ий нет или опять чего не досмотрел...)

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.19, 12:13
slavcodev
нет, извини, это я по привычке у меня свой расширенный ActiveRecord )

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.07.19, 19:35
mihan007
https://github.com/phpnode/YiiBlocks/tr ... /resources - мне вот эта штука по душе, а в частности AResourceful. Идея - внутри модели определяются виртуальные атрибуты - ресурсы. В качестве ресурса может выступать один или несколько файлов. Их загрузка и удаление происходит фактически при массовом присвоении аттрибутов ($model->attributes) и удалении модели соответственно. Кому нужна миграция для создания таблицы под неё - пишите в ЛС.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.05, 22:22
MetalGuardian
нашел небольшой баг в загрузке файла используя поведение:
валидатор вешается только на указанные сценарии, но файлы заливаются в любом случае.
то есть если сценария нет в списке, то можно залить любой файл.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.06, 13:55
ElisDN
MetalGuardian писал(а):если сценария нет в списке, то можно залить любой файл.
Это не совсем уж и баг, а больше специфика работы с файлами в PHP. Просто файлы не через атрибуты передаются и в $_POST отсутствуют. Влиять на элементы массива $_FILES исходя из правил валидации фреймворк не способен. Валидатор CFileValidator - это, можно сказать, некий фиктивный костыль с побочным действием.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.06, 14:07
MetalGuardian
это проблема не пхп.
тут дело в чем: валидатор навешивается только в случае соответствия сценариев, а сохранение происходит в любом случае.
нужна такая же проверка на нужный сценарий и в методе beforeSave - тогда не будет сохранения.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.06, 14:25
ElisDN
Ну это самому можно в своей модели добавить проверку на сценарий

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

class Post extends CActiveRecord
{
    protected function beforeValidate()
    {
        if (parent::beforeValidate())
        {    
            if(!in_array($this->scenario, array('qwert', 'asdf')){
                unset($_FILES['Post']['file']);
            }
            return true;
        } else 
            return false;
    } 
}
 
Просто мне не очень понятно, как при инкапсуляции этой проверки в поведение оно получит список сценариев. Хотя можно либо $this->owner->rules() вручную парсить, либо в параметре поведения список сценариев задавать.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.06, 14:41
MetalGuardian
в поведение и так передаются сценарии в которых должна быть загрузка.
я говорю лишь что нужна проверка в двух местах

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.11.09, 10:11
resurtm
В принципе, поправить может любой, сделав pull request вот тут: https://github.com/samdark/yiiframework_ru_cookbook :)
Сегодня вечером поправлю. Спасибо, что указали на недочёт.

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.12.02, 14:03
agrail
Не очень понятно, почему beforeSave и beforeDelete в поведении являются public-методами

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.12.02, 14:07
MetalGuardian
потому что они так объявлены в CActiveRecordBehavior

Re: Как загрузить файл (толстая модель, тонкий контроллер)

Добавлено: 2012.12.02, 14:19
resurtm
А вот в модели и вправду неправильно, что public, т.к. в CActiveRecord они protected. Сейчас оформлю всё это в PR. :)

UPD: таки в CActiveRecordBehavior все эти методы тоже protected. :D

UPD2: https://github.com/samdark/yiiframework ... ok/pull/13