Разная валидация для create и update

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Paulius22
Сообщения: 16
Зарегистрирован: 2017.07.19, 13:29

Разная валидация для create и update

Сообщение Paulius22 »

Добрый вечер!

Возникла проблема. Через CRUD создал функционал для создания и обновления записей таблицы. В одном из полей добавил ->fileInput для загрузки файлов. Прописал валидацию required для этого поля.
Сложность в том, как сделать, чтобы при создании записи это поле было required, а для обновления нет. Идея в том, чтобы если в update файл не подгружен, то остается тот файл, который уже загружен на сервер, иначе - он обновляется.
Прошу помочь разобраться. Может есть нормальное решение, без кривых костылей!
Paulius22
Сообщения: 16
Зарегистрирован: 2017.07.19, 13:29

Re: Разная валидация для create и update

Сообщение Paulius22 »

Реализовал следующим образом. Наверное кривовато:
-в моделе создал еще одно свойство img2 (в дополнение к img)
-в валидации поставил Img2 safe
-в представлении сделал условие:

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

    if($model->img)
        echo $form->field($model, 'img2')->fileInput();
    else
        echo $form->field($model, 'img')->fileInput();
т.е. если $model->img сущействует, значет это update и создаем fileInput с img2, иначе это create и пускай валидируется по полной

В контроллере в actionUpdate проверка. Загружен ли файл. Если да, то удаляем старый, загружаем новый и т.д.
Если нет, то просто обновляем данные $model->save без загрузки и обработки изображения.

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

$file = UploadedFile::getInstance($model, 'img2');

            // если загружен новый файл, то удаляем старый и загружаем новый
            if ($file && $file->tempName)
            {
                // создаем объект для загрузки картинки
                $file = UploadedFile::getInstance($model, 'img2');
                // получаем уникальное имя для будущего файла
                $nameFile = UsefulClass::getNameDateTime(). '.' . $file->extension;
                // получаем директорию
                $nameDir = Yii::$app->params['upload']['slider'];

                // удаляем файл
                @unlink(Yii::$app->params['upload']['slider'] . '/' . $oldFile);
                // сохраняем файл
                $file->saveAs($nameDir . '/' . $nameFile);
                // обновляем размеры файла до необходимых
                Image::thumbnail($nameDir . '/' . $nameFile, 484, 441)
                    ->save(Yii::getAlias($nameDir . '/' . $nameFile), ['quality' => 90]);

                $model->img = $nameFile;
            }

            $model->save();
Как вам такое решение? Наверное кривовато, да?
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Разная валидация для create и update

Сообщение kawabanga »

сценарии
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Разная валидация для create и update

Сообщение Nex-Otaku »

Можно сделать через "when", или просто напиши свой валидатор.
Аватара пользователя
maleks
Сообщения: 1992
Зарегистрирован: 2012.12.26, 12:56

Re: Разная валидация для create и update

Сообщение maleks »

Paulius22 писал(а): 2017.07.28, 02:17 -в валидации поставил Img2 safe
Я не уверен что это безопасно. По коду вроде как в img2 получится сохранить любой путь.

А вообще примерно то делаете, но несколько моментов:
1) держите 2 поля, одно "внутреннее" fileName, это поле с именем, строка, а второе именно для работы с загрузкой файла - fileObj
2) fileName в рулесах не указывается, оно небезопасное
3) fileObj в рулесах прописываете что файл и еще правило required с when от того что fileName пустое
4) тех проверок во вьюхе делать вам не надо, все равно же вы поле загрузки файла fileObj показываете всегда.
5) В контроллере так много логики можно не писать, чисто получили инстанс файла в fileObj , а все остальное уже в beforeSave модели
ZxcR_777
Сообщения: 21
Зарегистрирован: 2017.02.16, 16:17

Re: Разная валидация для create и update

Сообщение ZxcR_777 »

Используйте сценарии и в контроллере или beforeValidate и тд если атрибут модели null то равно старому значению
Ответить