Solved: Model Rule Ignored For File?

I have a rule in my model:


array('pdf', 'file', 'types'=>'pdf', 'allowEmpty'=>true, 'wrongType'=>"Only PDF's accepted."),

I would expect this rule to only allow upload of a PDF, however it seems to be ignored and I can upload any file type.

Similarly, if I change ‘types’ to ‘jpg’, I can still upload PDF’s.

Validation is working, and if I remove ‘allowEmpty’ for instance, I get a warning and cannot save the record if I fail to choose a file to upload.

Any ideas?

EDIT:

I figured out my problem…

Because I wanted to save my PDF only after the model was saved, it went something like this:




$model->pdf = CUploadedFile::getInstance($model, 'pdf');

if ($model->save()) {

    if (is_object($model->pdf)) {

        $model->pdf->saveAs($pdfpath. "/$model->pdf");

    }

So the validation was already done at $model->save(). Then I saved the file.

I needed to re-validate after saving the model, to check the file type like this:




$model->pdf = CUploadedFile::getInstance($model, 'pdf');

if ($model->save()) {

    if (is_object($model->pdf)) {

        if ($model->validate()) {

            $model->pdf->saveAs($pdfpath. "/$model->pdf");

        }

    }

EDIT2:

Actually, I’m still sure that validation should have worked at $model->save(), with the line I have above it, but it doesn’t.

What you are saying is that the validation on save() has passed, but on validate() not ?

That could not (should not) happen as the save() method does first call validate() and if the validation has not passed false is returned. Check the save() source - http://www.yiiframework.com/doc/api/1.1/CActiveRecord#save-detail

Could be that something is happening on before/afterSave() ?

Hi, thanks for your reply.

You are correct in that the validation passes on save() but not on validate().

This is a very basic Gii generated model with simple rules and no before/after save going on.

I’ll take a look at the source of save() and validate() later today to see if I can find out what’s happening.

I have used other upload methods in the past but on this occasion I decided to follow this wiki:

http://www.yiiframework.com/wiki/2/how-to-upload-a-file-using-a-model/

It would seem that the file input is not validated, even though the wiki shows the rule to be used.

If I remove the line:


$model->pdf = CUploadedFile::getInstance($model, 'pdf');

validation works as it should but the file is not uploaded.

Still looking into it.

I have made a note on the wiki.

As I pointed above and as you could check on the save() source the validation() is performed by save() in all cases (insert and update)… and only if the validation passes the data is saved by calling respectively insert() or update().

So what seems that is happening in your case is that first time the validation is called it passes but when called for the second time it does not, and that should not happen at all.

But there is a small difference in the "scenario" in those two calls to validate(), the first time scenario is "create" but the second time is "update"… so maybe you have a different scenarios applied to your pdf attribute?

Another thing that comes to mind is the problem with PHP versions before 5.2.0 but that would not explain the second call to validate().