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

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Аватара пользователя
resurtm
Сообщения: 299
Зарегистрирован: 2010.12.19, 09:13
Откуда: Казахстан, Алма-Ата
Контактная информация:

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

Сообщение resurtm »

agrail писал(а):Оперативно)
Вам спасибо, что приметили такой ляп. ;)
agrail
Сообщения: 107
Зарегистрирован: 2011.06.19, 23:19

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

Сообщение agrail »

SamDark:"Э, нее. С protected больше не работает. См. описание в master."
Так в чем там причина, можете рассказать?Почему эти методы public сделали?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

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

Сообщение slavcodev »

Если нет желания постоянно следить за моделью и за новыми сценариями :)
Можно вот так

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

protected function beforeSave(){
        if(!parent::beforeSave())
            return false;

        if($this->isAttributeSafe('document')
            && $document=CUploadedFile::getInstance($this,'document')) {
            $this->deleteDocument(); // старый документ удалим, потому что загружаем новый
 
            $this->document=$document;

            // DS - зачем? в unix всегда '/', а винда понимает
            $this->document->saveAs(Yii::getPathOfAlias('webroot.media').'/'.$this->document);
        }

        return true;
}
Жду Yii 3!
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

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

Сообщение slavcodev »

И кстати т.к. в FileValidator создается объект CUploadedFile::getInstance, есть ли смысл создавать его еще раз в модели?
Экономия не важная, но все же экономия. может есть смысл перенести в beforeValidate?
Жду Yii 3!
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

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

Сообщение samdark »

agrail
public сделали ради сильно меньшего съедания памяти.

mc-bear
Есть. Он там никуда не присваивается.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

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

Сообщение slavcodev »

Sam Dark писал(а):mc-bear
Есть. Он там никуда не присваивается.
Я знаю что не присваивается, но создается, а если бы до валидации в атрибут модели уже файл то и не создается.
Поэтому я спрашиваю, может в beforeValidate сохранить файл CUploadedFile::getInstance в атрибт модели,
а сохранить в beforeSave
Жду Yii 3!
agrail
Сообщения: 107
Зарегистрирован: 2011.06.19, 23:19

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

Сообщение agrail »

Я у себя вот так еще сделал:

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

/**
     * @var array scenario applies a validation; in case array('*') validatation will be applied to all scenarios
     */
    public $scenarios = array('*');

    /**
     *
     * @var boolean
     */
    public $allowEmpty = true;

    /**
     *
     * @var int maxSixe of uploaded file. By default 2Mb
     */
    public $maxSize = 2048576;

.................................

    public function attach($owner) {
        parent::attach($owner);
        if (in_array($owner->getScenario(), $this->scenarios) OR $this->scenarios == array('*')) {//если сценарии указаны как array('*'), то валидация будет выполнена в любом случае
            $fileValidator = CValidator::createValidator(
                            'file', $owner, $this->attributeName, array(
                        'types' => $this->fileTypes,
                        'allowEmpty' => $this->allowEmpty,
                        'maxSize' => $this->maxSize,
                        'safe' => false,
                            )
            );
            $owner->validatorList->add($fileValidator);
        }
    }
...........................................
 
Аватара пользователя
resurtm
Сообщения: 299
Зарегистрирован: 2010.12.19, 09:13
Откуда: Казахстан, Алма-Ата
Контактная информация:

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

Сообщение resurtm »

mc-bear писал(а):Поэтому я спрашиваю, может в beforeValidate сохранить файл CUploadedFile::getInstance в атрибт модели,
а сохранить в beforeSave
Разумно. Можно, наверное, указать в рецепте.
Хотя с другой стороны CUploadedFile и вправду не особо тяжёлый и большой, чтобы накладно было дважды создавать. :)
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

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

Сообщение slavcodev »

resurtm писал(а):Хотя с другой стороны CUploadedFile и вправду не особо тяжёлый и большой, чтобы накладно было дважды создавать. :)
Я не вдумывался, я пока в контроллере это делаю, ессно до валидации.
Не тяжелый, значит не тяжелый ;)
Жду Yii 3!
raketa
Сообщения: 131
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa »

а как используя поведение UploadableFileBehavior сделать чтобы при добавлении записи поле с файлом было обязательным?
Аватара пользователя
MetalGuardian
Сообщения: 208
Зарегистрирован: 2011.03.06, 02:42
Откуда: Киев

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

Сообщение MetalGuardian »

raketa писал(а):а как используя поведение UploadableFileBehavior сделать чтобы при добавлении записи поле с файлом было обязательным?
установить allowEmpty в false
raketa
Сообщения: 131
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa »

MetalGuardian писал(а):
raketa писал(а):а как используя поведение UploadableFileBehavior сделать чтобы при добавлении записи поле с файлом было обязательным?
установить allowEmpty в false
Тогда поле будет обязательным всегда, к примеру создали модель с файлом (файл обязательный) дальше пользователь его редактирует, но в этом случае не нужно требовать грузить файл еще раз

Было бы удобнее подключив один раз поведение забыть про него ...
к примеру в rules стандартно писать

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

array('image','required','on'=>'insert'),
но в этом случае происходит для меня что то непонятное и файл не грузится,
Как выход передавать в поведение параметр который определяет при каких сценариях атрибут обязательный, чего не хотелось бы,
либо каким то образом в самом поведении удалять правило валидации required и добавлять allowEmpty = false, но пока не нашел такой возможности
Последний раз редактировалось raketa 2012.12.16, 17:22, всего редактировалось 1 раз.
raketa
Сообщения: 131
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa »

Так-же рецепт при использовании поведения не рабочий

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

    public function rules(){
        return array(
            array('title','required','on'=>'insert,update'),
            // после генерации модели при помощи Gii нужно убрать валидацию
            // у атрибута $document — если этого не сделать, то оно будет
            // препятствовать правильной работе валидации загружаемого файла
        );
    }
атрибут $document получается unsafe

и далее в поведении добавляется валидатор file который по умолчанию с недавних пор тоже unsafe
нужно прописать

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

$fileValidator=CValidator::createValidator('file',$owner,$this->attributeName,
                array('types'=>$this->fileTypes,'allowEmpty'=>true, 'safe'=true));
'safe'=true
Аватара пользователя
dignityinside
Сообщения: 76
Зарегистрирован: 2013.04.04, 17:57
Контактная информация:

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

Сообщение dignityinside »

Почему при редактировании удаляется старая картинка или как сделать так, чтобы если я не выбрал картинку, старая не удалялась?

UPD нашел сам решение:
array('img','file','types'=>'jpg,jpeg,png,gif', 'allowEmpty'=>true,'on'=>'insert,update', 'maxSize' => 1048576, 'safe'=>false),
Мой блог:
https://protonalex.com
spayn
Сообщения: 9
Зарегистрирован: 2015.03.15, 14:01

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

Сообщение spayn »

Скажите, пожалуйста, а как сделать загрузку нескольких файлов, если у поля для загрузки использовать атрибут multiple?
Ответить