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

Обсуждение документации. Переводы Cookbook и авторские рецепты.

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

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

Сообщение resurtm » 2012.12.02, 14:58

agrail писал(а):Оперативно)
Вам спасибо, что приметили такой ляп. ;)

agrail
Сообщения: 107
Зарегистрирован: 2011.06.19, 23:19

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

Сообщение agrail » 2012.12.03, 14:10

SamDark:"Э, нее. С protected больше не работает. См. описание в master."
Так в чем там причина, можете рассказать?Почему эти методы public сделали?

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

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

Сообщение slavcodev » 2012.12.03, 14:32

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

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

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
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

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

Сообщение slavcodev » 2012.12.03, 14:39

И кстати т.к. в FileValidator создается объект CUploadedFile::getInstance, есть ли смысл создавать его еще раз в модели?
Экономия не важная, но все же экономия. может есть смысл перенести в beforeValidate?
Жду Yii 3!

Аватара пользователя
samdark
Администратор
Сообщения: 8552
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

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

Сообщение samdark » 2012.12.03, 14:42

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

mc-bear
Есть. Он там никуда не присваивается.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

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

Сообщение slavcodev » 2012.12.03, 14:44

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

agrail
Сообщения: 107
Зарегистрирован: 2011.06.19, 23:19

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

Сообщение agrail » 2012.12.03, 14:58

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

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

/**
     * @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 » 2012.12.03, 15:06

mc-bear писал(а):Поэтому я спрашиваю, может в beforeValidate сохранить файл CUploadedFile::getInstance в атрибт модели,
а сохранить в beforeSave
Разумно. Можно, наверное, указать в рецепте.
Хотя с другой стороны CUploadedFile и вправду не особо тяжёлый и большой, чтобы накладно было дважды создавать. :)

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

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

Сообщение slavcodev » 2012.12.03, 15:18

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

raketa
Сообщения: 125
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa » 2012.12.16, 15:23

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

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

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

Сообщение MetalGuardian » 2012.12.16, 16:27

raketa писал(а):а как используя поведение UploadableFileBehavior сделать чтобы при добавлении записи поле с файлом было обязательным?
установить allowEmpty в false

raketa
Сообщения: 125
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa » 2012.12.16, 16:58

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

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

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

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

raketa
Сообщения: 125
Зарегистрирован: 2011.07.28, 17:29

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

Сообщение raketa » 2012.12.16, 17:19

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

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

    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
Сообщения: 74
Зарегистрирован: 2013.04.04, 17:57
Контактная информация:

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

Сообщение dignityinside » 2015.01.03, 00:42

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

UPD нашел сам решение:
array('img','file','types'=>'jpg,jpeg,png,gif', 'allowEmpty'=>true,'on'=>'insert,update', 'maxSize' => 1048576, 'safe'=>false),

spayn
Сообщения: 9
Зарегистрирован: 2015.03.15, 14:01

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

Сообщение spayn » 2015.03.15, 14:49

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

Ответить