Upload File With Form

I have a form that a user completes and one field I want to allow the user to attach a file. That file should be uploaded to a directory (e.g. uploads) and the file name saved into the database.

In the form I am able to allow the user to browse for the file however I am unsure how to write the Controller. The problem is that the file is not being uploaded to webroot/uploads/

A small section of the _form view is

<div class="form">

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

‘id’=>‘new-task-form’,

‘enableAjaxValidation’=>false,

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

)); ?>

<div class="row">

<?php echo $form->labelEx($model,‘task_name’); ?>

<?php echo $form->textField($model,‘task_name’,array(‘size’=>60,‘maxlength’=>100)); ?>

<?php echo $form->error($model,‘task_name’); ?>

</div>

<div class="row">

<?php echo $form->labelEx($model,‘file_name’); ?>

<?php echo CHtml::activeFileField($model,‘file_name’); ?>

<?php echo $form->error($model,‘file_name’); ?>

</div>

And this allows the user to browse for a file. My problem is to how to write the controller - I have

public function actionCreate()

{

$model=new NewTask;

$model->client_id = $this->_client->id;

if(isset($_POST[‘NewTask’]))

{

$model->attributes=$_POST[‘NewTask’];

$model->file_name=CUploadedFile::getInstance($model,‘file_name’);

if($model->save())

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

$model->file_name->saveAs($_SERVER[‘DOCUMENT_ROOT’].Yii::app()->request->baseUrl.’/uploads/’.$model->file_name->name);

}

$this->render(‘create’,array(

‘model’=>$model,

));

}

The Model is

<?php

/**

  • This is the model class for table "new_task".

  • The followings are the available columns in table ‘new_task’:

  • @property integer $id

  • @property string $client_id

  • @property string $user_id

  • @property string $task_name

  • @property string $file_name

  • @property string $import_date

  • @property integer $active

  • The followings are the available model relations:

  • @property Client $client

  • @property User $user

  • @property TaskList[] $taskLists

*/

class NewTask extends CActiveRecord

{

public function getUser()

{

//get list of users as available drop down for creating new task

return CHtml::listData(User::model()->findAll(), ‘id’, ‘username’);

}

/**

  • Returns the static model of the specified AR class.

  • @param string $className active record class name.

  • @return NewTask the static model class

*/

public static function model($className=CLASS)

{

return parent::model($className);

}

/**

  • @return string the associated database table name

*/

public function tableName()

{

return ‘new_task’;

}

/**

  • @return array validation rules for model attributes.

*/

public function rules()

{

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

// will receive user inputs.

return array(

array(‘client_id, user_id, task_name, file_name, active’, ‘required’),

array(‘active’, ‘numerical’, ‘integerOnly’=>true),

array(‘client_id, user_id’, ‘length’, ‘max’=>11),

array(‘task_name’, ‘length’, ‘max’=>100),

array(‘file_name’, ‘length’, ‘max’=>200),

array(‘import_date’, ‘default’,

‘value’=>new CDbExpression(‘NOW()’),

‘setOnEmpty’=>false, ‘on’=>‘insert’),

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

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

array(‘id, client_id, user_id, task_name, file_name, import_date, active’, ‘safe’, ‘on’=>‘search’),

);

}

/**

  • @return array relational rules.

*/

public function relations()

{

// NOTE: you may need to adjust the relation name and the related

// class name for the relations automatically generated below.

return array(

‘client’ => array(self::BELONGS_TO, ‘Client’, ‘client_id’),

‘user’ => array(self::BELONGS_TO, ‘User’, ‘user_id’),

‘taskLists’ => array(self::HAS_MANY, ‘TaskList’, ‘task_id’),

);

}

/**

  • @return array customized attribute labels (name=>label)

*/

public function attributeLabels()

{

return array(

‘id’ => ‘ID’,

‘client_id’ => ‘Client’,

‘user_id’ => ‘User’,

‘task_name’ => ‘Task Name’,

‘file_name’ => ‘File Name’,

‘import_date’ => ‘Import Date’,

‘active’ => ‘Active’,

);

}

/**

  • Retrieves a list of models based on the current search/filter conditions.

  • @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

*/

public function search()

{

// Warning: Please modify the following code to remove attributes that

// should not be searched.

$criteria=new CDbCriteria;

$criteria->compare(‘id’,$this->id);

$criteria->compare(‘client_id’,$this->client_id,true);

$criteria->compare(‘user_id’,$this->user_id,true);

$criteria->compare(‘task_name’,$this->task_name,true);

$criteria->compare(‘file_name’,$this->file_name,true);

$criteria->compare(‘import_date’,$this->import_date,true);

$criteria->compare(‘active’,$this->active);

return new CActiveDataProvider($this, array(

‘criteria’=>$criteria,

));

}

}

The end result I want is

  1. The user selects a file to upload with the form

  2. The file is uploaded to a directory /uploads

  3. The file name is saved to the new_task table along with the other form data.

I would be very appreciative is someone could help me out. I am fairly new to YII and I am still learning the syntax.

0

It’s ok - I figured it out - it is the order - I render the view before saving whereas it should be in the controller

$model->file_name->saveAs($_SERVER[‘DOCUMENT_ROOT’].Yii::app()->request->baseUrl.’/uploads/’.$model->file_name->name);

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