File Upload Action Update Problem

Here is my dilemma, I can upload files, delete files, but update is not working correct. Of course if I change the file then I can update the whole record but If I want to just update the description field then I get of course: Filename cannot be blank. This is supposed to be supplied by a hidden field as a part of activeFileField, but why not just simply return the path back to this field on update. Anyway how do I go about fixing this?

My Form




<?php

/* @var $this UserfilesController */

/* @var $model Userfiles */

/* @var $form CActiveForm */

?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'userfiles-form',

	'enableAjaxValidation'=>false,

	'htmlOptions'=>array('enctype'=>'multipart/form-data')

)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<?php echo $form->errorSummary($model); ?>


	<div class="row">

		<?php echo $form->labelEx($model,'filename'); ?>

		<?php echo CHtml::activeFileField($model, 'filename'); ?>

        <?php //echo $form->textField($model,'filename',array('size'=>60,'maxlength'=>77)); ?>

		<?php echo $form->error($model,'filename'); ?>

	</div>

    <div class="row">

     <?php echo $form->labelEx($model,'description'); ?>

     <?php echo $form->textArea($model,'description',array('rows'=>5,'cols'=>50)); ?>

     <?php echo $form->error($model,'description'); ?>

    

    </div>


	<div class="row">

		<?php echo $form->labelEx($model,'user_id'); ?>

		<?php echo $form->dropDownList($model, 'user_id', CHtml::listData(User::model()->findAll(), 'id', 'username'),array('prompt' => 'Select a User')); ?>

		<?php echo $form->error($model,'user_id'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>

	</div>


<?php $this->endWidget(); ?>


</div><!-- form -->



update function




public function actionUpdate($id)

	{

		$model=$this->loadModel($id);

                $old=$this->loadModel($id);

		// Uncomment the following line if AJAX validation is needed

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


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

		{

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

		if($model->save())

				

		{

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

		

		

              if (!empty($_FILES['Userfiles']['filename']['name'])) {

                if ($old->filename != "") {

                $file= 'images/$old->filename->name';

                                        unlink($file);

                }          

                        } else {

								if(!is_null($model->filename)) {

                                $model->filename->name;

								}

                        }       

            if($model->save())

            {

				

				if(!is_null($model->filename)) {

            	$file= 'images/'.$model->filename->name;

				

            	$model->filename->saveAs($file);

                //model->filename->saveAs(Yii::app()->baseUrl.'/images');

                // redirect to success page

            	}

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

				

			}

            	

				

			

		}

		}


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

			'model'=>$model,

		));

	}



http://www.yiiframework.com/wiki/2/

Sorry if this post would have helped me, I would not have posted here. No offense, I have read that post a 100 times. I am missing something and require a little more direction, thank you though.

Have you tried putting var_dump in the code to verify where code could fail?

Can I see the actionCreate method please, I only say this because my Create and Update are exactly the same. I remember having a similar issue and I think setting attribute in models to unsafe and allow empty to true solved it


array('Thumbnail', 'file', 'types'=>'jpg, gif, png','allowEmpty'=>true),

		    array('Template','unsafe'),



It doesn’t remove the old file if the controller is like the below on update function


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

		{

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

			

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


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

			$model->Template = $Template;

								

			if($model->save())

			{

			    if (is_object($Template))

			 $model->Template->saveAs(Yii::app()->basePath . '/../images' . $model->Template); 

			

				$this->redirect(array('adminproducts/'.$store));

			}

		}

		

		


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

			'model'=>$model,

		));

Hope that helps

Cheers

This was the fix:

Some of the problem was contained in the rules() of the model.

This site was a definite help in cleaning up my function.




public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('description, origfile, public, user_id', 'required'),

			array('user_id', 'numerical', 'integerOnly'=>true),

			array('origfile, filename', 'length', 'max'=>255),

			array('public', 'length', 'max'=>1),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('id, description, origfile, filename, public, user_id', 'safe', 'on'=>'search'),

		);

	}


public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		// Uncomment the following line if AJAX validation is needed

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


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

		{

			

			

			

			

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

			$oldfilename = $model->filename; // let's store original filename (if it was defined)

			

			// Now check if there was anything uploaded and store new name if so

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

						

			//$model->filename = $file;

			

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

				$model->filename = $file;

			} else {

				$model->filename = $oldfilename;

			}  


			//echo print_r($_POST['Userfiles']);

			if($model->save())

			//echo print_r($_POST['Userfiles']);

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

					// again, if anything was uploaded and if we have db done then move the file from tmp to the right place

					//$file->saveAs(Yii::app()->baseUrl.'/images/' . $file->name);

					

                $file= 'images/'.$model->filename->name;

                                                                

                $model->filename->saveAs($file);


					if ($oldfilename != $model->filename->name) {

						//unlink($model->fileWithPath(Yii::app()->baseUrl.'/images/' . $oldfilename));

						

						

						$file= 'images/' . $oldfilename;

                         unlink($file);





					}

				} 

	

	

	

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

		}


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

			'model'=>$model,

		));

	}