optional upload file when update a record

Hi guys,

I had some problems when I tried update a record on my application without upload again a file.

I have a form and on this form there are two fields for upload files, when I create a new record the valdation requires the files, but on update no.

When I try to update a record I receive the error:




Fatal error: Call to a member function saveAs() on a non-object in /Users/san/src/nagloria/trunk/web/public/protected/controllers/admin/RepertoryController.php on line 74



here are my actions:




  public function actionCreate()

  {

    $piece = new Repertory;

    $piece->scenario = 'create';

    $this->registration($piece, $_POST['Repertory']);

    $this->render('create', array('repertory' => $piece));

  }

  

  public function actionUpdate()

  {

    $piece = $this->loadpiece();

    $this->registration($piece, $_POST['Repertory']);    

    $this->render('update', array('repertory' => $piece));

  }


  private function registration($model, $form)

  {

    if(isset($form))

    {

      $model->attributes = $form;

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

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

      if($model->save())

      {

        exec("mkdir -p " . Yii::app()->basePath . "/../files/repertory/media_file/{$model->id}/");

        exec("mkdir -p " . Yii::app()->basePath . "/../files/repertory/thumbs/{$model->id}/");

        $model->media_file->saveAs(Yii::app()->basePath . "/../files/repertory/media_file/{$model->id}/{$model->media_file->name}");

        $model->thumb->saveAs(Yii::app()->basePath . "/../files/repertory/thumbs/{$model->id}/{$model->thumb->name}");

        $this->redirect('/admin/repertory/list');

      }

    } 

  }




How can I fix up this?

Thanks?

I would try with




if (isset($model->media_file))

  $model->media_file->saveAs(Yii::app()->basePath . "/../files/repertory/media_file/{$model->id}/{$model->media_file->name}");

if (isset($model->thumb))

  $model->thumb->saveAs(Yii::app()->basePath . "/../files/repertory/thumbs/{$model->id}/{$model->thumb->name}");



(CUploadedFile::getInstance() returns null if no file was uploaded)

/Tommy

Hi tri,

I did your sugestion, the application not showed the error again but happened other error, when I updated a record without upload a file, the aplication stored a NULL value on database field rewriting the file name that was stored on this field first.

I need to persist the file name on database if files aren’t uploaded.

Any sugestion?

Thanks.

Hi GodFather, I think you can remove ‘media_file’ and ‘thumb’ from safeAttributes() in your ‘update’ scenario. Assign one by one if set.

(Not tested)

/Tommy

Hi tri,

I not understood you, I’m not using this attributes how safeattributes, actually I just Assing the values on they.

Do you think that I’m doing something wrong?

Could you show me a exemple?

Thanks.

I haven’t tried this myself, but I think manual assignment of the two uploaded fields, if not empty, would be a better solution than to explicitly save the old values.

To me it seems like you massively assign from a form in this statement.




$model->attributes = $form;



Do you use 1.0 or 1.1? If the latter, you have to specify an ‘update’ scenario rule instead.

On second thought, why are the upload fields empty in your ‘update’ scenario? I think I’m going to try this out now. I’m sure somebody else can explain this better.

Edit:

Sorry, in my first answer I erroneously got the impression you saved to local vars. Now I see that you save to the model and I don’t know the semantics of CUploadedFile. Please disregard my answer.

/Tommy

Ok, here is how it works:

(myfile to be replaced by media_file, thumb)

$model->myfile is a string when read back from the db. It is massively assigned as I suspected (default is all attributes). If the getInstance call succeeds, $model->myfile becomes a CUploadedFile object (else it seems to becomes an instance of the current controller !?).

1) safeAttributes




public function safeAttributes()

{

return array(

  'create'=>'media_file, thumb, attr_1, attr_2, attr_n',

  'attr_1, attr_2, attr_n',

);

}



2) don’t overwrite $model->file if invalid object




$myfile = CUploadedFile::getInstance($model,'myfile');

if (is_object($myfile) && get_class($myfile)==='CUploadedFile')

  $model->myfile = $myfile;



3) test before save




if (is_object($model->myfile))

  $model->Picture->saveAs($mypath.'/'.$model->myfile->name);



The logic can be improved (don’t create dir when not neccessary, clear $model->myfile if file cannot be saved, filesize rules)

Hope I got it right this time.

/Tommy

Man, all is running right now.

Thanks for your help, and sorry by the time that you spent with this post.

Thanks alot.

Thanks alot tri really helped me … :D