Reputation: 437
I got this error when an image file is required: "Preview cannot be blank". Although I filled this field.
My rules:
public function rules()
{
return [
[['name', 'preview', 'date', 'author_id'], 'required', 'on' => 'update'],
[['name', 'preview', 'date', 'author_id'], 'required', 'on' => 'create'],
[['date_create', 'date_update', 'author_id'], 'integer'],
[['preview'], 'file', 'skipOnEmpty' => 'false', 'extensions' => 'png, jpg, jpeg'],
[['date'], 'safe'],
[['name'], 'string', 'max' => 255]
];
}
Controller:
public function actionCreate()
{
$model = new Book();
$model->scenario = 'create';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->preview = UploadedFile::getInstance($model, 'preview');
if ($model->save() && $model->preview->saveAs('uploads/' . $model->preview->baseName . '.' . $model->preview->extension))
{
return $this->redirect(['view', 'id' => $model->id]);
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
If preview
file is not required there is no error and the file is being loaded into the uploads
folder.
Upvotes: 4
Views: 1194
Reputation: 42133
Best thing to do here is to avoid using the same field for different purposes.
In your case you are overwriting preview
with UploadedFile
instance, you could create another field for this and then:
$model->previewFile = UploadedFile::getInstance($model, 'preview');
Then the validation invoked by save()
won't hit any new issues about preview
field as the file is held in previewFile
and original value of preview
passed through the $model->validate()
check already.
Upvotes: 2
Reputation: 1032
I think you can't make this field required, as it only validates $_POST variables inserted. The file upload is entered in the $_FILES superglobal and not in the $_POST superglobal. Requiring this would mean you want it in your $_POST variables.
You run the validation before handling the file upload. So I would recommend handling the file upload before you handle the model validation, so you can set the value to the model and then run validate afterwards:
public function actionCreate()
{
$model = new Book();
$model->load(Yii::$app->request->post());
$model->scenario = 'create';
$model->preview = UploadedFile::getInstance($model, 'preview');
if ($model->validate()) {
if ($model->save() && $model->preview->saveAs('uploads/' . $model->preview->baseName . '.' . $model->preview->extension))
{
return $this->redirect(['view', 'id' => $model->id]);
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
I didn't test it locally, but making the 'preview' field required without any info in it is not going to work for sure.
P.S. I think it should be 'skipOnEmpty' => false, not with '' around the false.
Upvotes: 2