[SOLVED] File Upload Logic

Hi,

I need some advice on File upload logic. I have form which uploads a single file - this is working fine. When I try to update the record, the file input is obviously empty. When I submit the form the $file attribute is set to empty the property is saved with an empty value. How do I check if the $file property is populated (previously) and only overwrite it if the user has submitted a new file?




    public function actionCreate()

    {

        $model = new Project;


        // Uncomment the following line if AJAX validation is needed

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


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

        {

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

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

            

            if ($model->validate())

            {

                $upload = Yii::app()->basePath . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $model->file->getName();

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


                if ($model->save())

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

            }

        }


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

            'model' => $model,

        ));

    }


    public function actionUpdate($id)

    {

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


        // Uncomment the following line if AJAX validation is needed

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


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

        {

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

            // Need to some validation here to see if $file property is empty & if user has submitted a new file.


            if ($model->save())

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

        }


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

            'model' => $model,

        ));

    }



Thanks a lot,

Matt

I think I’m on the right track but I need some assistance checking if a file was submitted through the HTML file input.




    public function actionUpdate($id)

    {

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


        // Uncomment the following line if AJAX validation is needed

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


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

        {

            $file = $model->file;


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

            

            // I need to check here if a file was submitted,

            if (isset($_FILES['Project']))

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

            else

                $model->file = $file;


            if ($model->save())

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

        }


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

            'model' => $model,

        ));

    }



Cheers,

Matt

I think you need to check your form and see if there is set for multi part form submitting as it is required for file uploading to the web server.

From the api

so if




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

is null, then no new file was submitted

Thanks, not sure why I didn’t think of that. I was trying to work with $_POST and $_FILES array :blink:




    public function actionUpdate($id)

    {

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


        // Uncomment the following line if AJAX validation is needed

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


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

        {

            $originalFile = $model->file;


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


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

            

            if (isset($uploadedFile))

                $model->file = $uploadedFile;

            else

                $model->file = $originalFile;


            if ($model->save())

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

        }


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

            'model' => $model,

        ));

    }



Well, you’re missing a scenario in your file upload logic, when the uploaded file already exists.

it helped me :)

Hi

I’m experiencing a similar issue with CUploadedFile during actionUpdate, but it only occurs when I did not upload a new file during update AND when I have a file rule present in my class declaration. The action is as follows:




    public function actionUpdate($id) {

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


        $existing_image = $model->image;


        if (isset($_POST['Model'])) {

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


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


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

                $model->image = $new_image->name;

            } else {

                $model->image = $existing_image;

            }

}



The code above works fine, but if I include the rule below, my image is stored as NULL if I did not upload a new image during update. My question is, what causes this behavior?




    public function rules() {

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

    }