File Upload in action update

Hallo !!

I have small problem with uploading file in update action. In both update and create action file uploading works perfectly. Problem is, that wenn I don’t choose any file on update action, my $model->image is overriden with no value. I’d like to change it. I wish to change my controller to not update my $model->image if no file has been chosen. I alredy tried to mess with my controller, but couldn’t solve it, if anyone has an idea, please help :) I’ve seen in this forum some uploading solution, but neither helped

here is my controller update action:


public function actionUpdate()

	{

		$model=$this->loadModel();


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Company']))

		{

			$folder=Yii::getPathOfAlias('webroot').'/images/company/';// folder for uploaded files

			$model->attributes=$_POST['Company'];

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

			$model->logo=rand(99999, 10) . '_' . $file->name;

			

			if($model->save())

				{

					if(!empty($model->logo))

						{

							if(!is_dir($folder.$model->id)){

								mkdir($folder.$model->id);

							}

							$file->saveAs($folder . $model->id . '/'.$model->logo);

						}

					$this->redirect(array('view','id'=>$model->id));

				}

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}

Regards

lukBB

This will work as long as for the update action, you set the logo field as optional in the model then in the controller you will do an additional check to see if the user added an image or not (probably you will check the $_FILES)




<?php

public function actionUpdate()

{

        $model=$this->loadModel();


        // Uncomment the following line if AJAX validation is needed

        // $this->performAjaxValidation($model);


        if(isset($_POST['Company']))

        {

                $folder=Yii::getPathOfAlias('webroot').'/images/company/';// folder for uploaded files

                $oldLogo=$model->logo;

                

                $model->attributes=$_POST['Company'];

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

                

                if($model->logo===null)

                    $model->logo=$oldLogo;

                else

                    $model->logo=rand(99999, 10) . '_' . $file->name;

                

                if($model->save())

                {

                    if(!empty($model->logo))

                    {

                            if(!is_dir($folder.$model->id)){

                                    mkdir($folder.$model->id);

                            }

                            $file->saveAs($folder . $model->id . '/'.$model->logo);

                    }

                    $this->redirect(array('view','id'=>$model->id));

                }

        }


        $this->render('update',array(

                'model'=>$model,

        ));

}




Ah btw, this is a sample from one of my applications.

Take a look at the code and it’ll help you to make an idea:




/**

 * Updates a particular model.

 * @param integer $id the ID of the model to be updated

 */

public function actionUpdate($id)

{

	$model=File::model()->findByPk($id);

    if($model===null)

		throw new CHttpException(404,Yii::t('app','The requested page does not exist.'));

    

    $this->data['model']=$model;

    $this->data['user']=User::model()->findAll(array('order'=>'user_id DESC'));

    $relation=UserToFile::model()->findAll('file_id=:fid',array(':fid'=>(int)$id));

    

    foreach($relation AS $rel)

        $this->data['userToFile'][]=$rel->user_id;


	if(isset($_FILES['File'])||isset($_POST['User']))

	{

        $userToFile=array();

        if(!empty($_POST['User'])&&is_array($_POST['User']))

        {

            foreach($_POST['User'] AS $uid)

            {

                if(is_numeric($uid) && $uid > 0)

                    $userToFile[]=$uid;

            }

        }

        

        if(empty($userToFile))

            Yii::app()->messageStack->set(array('result'=>'warning','msg'=>'Please assign at least one user for this file.'));    

		

        if(Yii::app()->messageStack->hasMessage()==false)

        {

            UserToFile::model()->deleteAll('file_id=:fid',array(':fid'=>$model->file_id));

            

            if(!empty($_FILES['File']['name']['original_name']))

            {

                $oldFile=$model->secure_name;

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

                if($model->original_name!==null)

                {

                    $mimeFilePath=Yii::getPathOfAlias('application.config').DIRECTORY_SEPARATOR.'mimeTypes.php';

                    $mimes=include($mimeFilePath);

                    $fileMime=CFileHelper::getMimeType($model->original_name->getTempName(),$mimeFilePath);

                    $fileExtension=$model->original_name->getExtensionName();

                    $validMime=false;

                    if(!empty($mimes[$fileExtension]))

                    {

                        if(is_string($mimes[$fileExtension]))

                            $validMime=$mimes[$fileExtension]==$fileMime;

                        elseif(is_array($mimes[$fileExtension]))

                            $validMime=in_array($fileMime, $mimes[$fileExtension]);

                    }

                    if($validMime)

                    {

                        $model->secure_name=md5($model->original_name.time()).'.'.$fileExtension;

                        $model->secure_name=strtolower($model->secure_name);

                        $model->mime_type=$fileMime;

                        $model->size=$model->original_name->getSize();

                        $model->date_added=date('Y-m-d H:i:s');

                        $model->user_id=Yii::app()->user->getId();

                    }

                    else

                        $model->addError('original_name','The file type is not allowed.');

                }

                if(!$model->hasErrors()&&$model->validate()&&$model->save())

                {

                    $model->original_name->saveAs(Yii::getPathOfAlias('application').DIRECTORY_SEPARATOR.'uploaded_files'.DIRECTORY_SEPARATOR.$model->secure_name);

                    if(file_exists($file=Yii::getPathOfAlias('application').DIRECTORY_SEPARATOR.'uploaded_files'.DIRECTORY_SEPARATOR.$oldFile))

                        unlink($file);

                }	

                    

            }

            foreach($userToFile AS $uid)

            {

                $u2f=new UserToFile;

                $u2f->user_id=$uid;

                $u2f->file_id=$model->file_id;

                $u2f->save();

            }

            $this->redirect(array('view','id'=>$model->file_id));   	    

        } 

	}

	$this->render('update',$this->data);

}



Check the tutorial and the second comment here:

How to upload a file using a model

twisted1919 and Attilio thank you for your help, I see I have to rewrite my controller actions

Thank you one more time for help, it works now, it is important to add unsafe rule for file, which I forgot :)

here is working example:


	/**

	 * Updates a particular model.

	 * If update is successful, the browser will be redirected to the 'view' page.

	 * @param integer $id the ID of the model to be updated

	 */

	public function actionUpdate()

	{

		$model=$this->loadModel();

		$folder=Yii::getPathOfAlias('webroot').'/images/ads/';// folder for uploaded files

		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);

		if(isset($_POST['Ad']))

		{

			$model->attributes=$_POST['Ad'];

			$file=CUploadedFile::getInstance($model,'image');

			

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

				$model->image = $file;

			

			if($model->save())

			{

				if(is_object($file))

					$model->image->saveAs($folder . $model->id . '/' . $model->id .'_'. $model->image);

					

				$this->redirect(array('view','id'=>$model->id));

			}		

		}

		

		$this->render('update',array(

			'model'=>$model,

		));

	}