Yii 1.1: How to use YiiBooster TbFileUpload widget

20 followers

Introduction

The following wiki is to explain how to make use of the TbFileUpload widget from YiiBooster. I have received a couple of requests and I thought was worth writing a wiki for it.

Usage

Preparation

First, we need to make sure we have a folder with write permissions, that will be the place where we are going to save our uploaded files.

I normally create a files folder and I allocate it within my www one, that is where I keep my css, js, images files. So, even though you can place it where ever you wish and for the sake of the example, I will use the files folder name.

I also assume that you have configured a path alias that references the files folder. On this example, the path alias is frontend.www.files.

Note

  • This demo only works if the MyModel class already includes the function getImageUrl($img_type=null). If not, comment the 2 lines inside the data array, where 'url' and 'thumbnail_url' are defined, to make the demo work
  • If the MyModel has a different name, it needs to be replaced 1-2 times inside the upload action
  • The url where we are going to upload our files => upload action

Thanks Don Felipe

Setup your model

The way you handle validation on the server is up to you, the configuration I am going to provide now is just an example.

We are going to add one extra attribute to the model picture, which is going to hold any $_FILE type resource uploaded and validated when model is on upload scenario.

class MyModel extends CActiveRecord {
// ... more code here
/**
* This is the attribute holding the uploaded picture
* @var CUploadedFile
*/
public $picture;
// ... more code
 
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
  return array(
    // ... more rules here
    array('picture', 'length', 'max' => 255, 'tooLong' => '{attribute} is too long (max {max} chars).', 'on' => 'upload'),
    array('picture', 'file', 'types' => 'jpg,jpeg,gif,png', 'maxSize' => 1024 * 1024 * 2, 'tooLarge' => 'Size should be less then 2MB !!!', 'on' => 'upload'),
    // ... more rules here
  );
}

Configuring the Widget

To render the widget on your view is quite straightforward, the are a couple of things very important to configure:

  • the url where we are going to upload our files
  • the file types we are going to accept and their maximum size

Now, lets render it:

<?php $this->widget('bootstrap.widgets.TbFileUpload', array(
    'url' => $this->createUrl("my/upload"),
    'model' => $model,
    'attribute' => 'picture', // see the attribute?
    'multiple' => true,
    'options' => array(
    'maxFileSize' => 2000000,
    'acceptFileTypes' => 'js:/(\.|\/)(gif|jpe?g|png)$/i',
))); ?>

Handling Upload

Everything is ready now but the controller. We have to configure the action that will handle the upload process. Here you go, the upload action of our controller -very, very basic - and not fully tested:

class myController extends CController {
// ... more code here
 
/**
* Handles resource upload
* @throws CHttpException
*/
public function actionUpload()
{
    header('Vary: Accept');
    if (isset($_SERVER['HTTP_ACCEPT']) && 
        (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false))
    {
        header('Content-type: application/json');
    } else {
        header('Content-type: text/plain');
    }
    $data = array();
 
    $model = new MyModel('upload');
    $model->picture = CUploadedFile::getInstance($model, 'picture');
    if ($model->picture !== null  && $model->validate(array('picture')))
    {
        $model->picture->saveAs(
        Yii::getPathOfAlias('frontend.www.files').'/'.$model->picture->name);
        $model->file_name = $model->picture->name;
        // save picture name
        if( $model->save())
        {
            // return data to the fileuploader
            $data[] = array(
                'name' => $model->picture->name,
                'type' => $model->picture->type,
                'size' => $model->picture->size,
                // we need to return the place where our image has been saved
                'url' => $model->getImageUrl(), // Should we add a helper method?
                // we need to provide a thumbnail url to display on the list
                // after upload. Again, the helper method now getting thumbnail.
                'thumbnail_url' => $model->getImageUrl(MyModel::IMG_THUMBNAIL),
                // we need to include the action that is going to delete the picture
                // if we want to after loading 
                'delete_url' => $this->createUrl('my/delete', 
                    array('id' => $model->id, 'method' => 'uploader')),
                'delete_type' => 'POST');
        } else {
            $data[] = array('error' => 'Unable to save model after saving picture');
        }
    } else {
        if ($model->hasErrors('picture'))
        {
            $data[] = array('error', $model->getErrors('picture'));
        } else {
            throw new CHttpException(500, "Could not upload file ".     CHtml::errorSummary($model));
        }
    }
    // JQuery File Upload expects JSON data
    echo json_encode($data);
}
 
// .... more code here 
 
} // end of controller

Resources

Final Notes

The upload action example was not really tested, if any of you had problems with it, please submit your changes to the YiiBooster Forum Topic. Any help would be highly appreciated to improve this wiki.

Total 15 comments

#18272 report it
joepages at 2014/10/09 05:21pm
Need help getting this up to work

@donfelipe

Hello! I've been trying to get this working but now it give me an error "Not found".

error

My model "PortafolioPictures" is:

<?php
 
/**
 * This is the model class for table "portafolioPictures".
 *
 * The followings are the available columns in table 'portafolioPictures':
 * @property integer $id
 * @property string $picture
 * @property string $ruta
 * @property integer $portafolio_id
 * @property integer $principalPicture
 *
 * The followings are the available model relations:
 * @property Portafolio $portafolio
 */
class PortafolioPictures extends CActiveRecord
{
    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'portafolioPictures';
    }
 
    /**
     * @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('portafolio_id', 'required'),
            array('portafolio_id, principalPicture', 'numerical', 'integerOnly'=>true),
            array('picture', 'length', 'max'=>45),
            array('ruta', 'length', 'max'=>3000),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, picture, ruta, portafolio_id, principalPicture', '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(
            'portafolio' => array(self::BELONGS_TO, 'Portafolio', 'portafolio_id'),
        );
    }
 
    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'picture' => 'Picture',
            'ruta' => 'Ruta',
            'portafolio_id' => 'Portafolio',
            'principalPicture' => 'Principal Picture',
        );
    }
 
    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.
 
        $criteria=new CDbCriteria;
 
        $criteria->compare('id',$this->id);
        $criteria->compare('picture',$this->picture,true);
        $criteria->compare('ruta',$this->ruta,true);
        $criteria->compare('portafolio_id',$this->portafolio_id);
        $criteria->compare('principalPicture',$this->principalPicture);
 
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }
 
    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return PortafolioPictures the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
}

My controller is "portafolioController" is:

public function actionCreate()
    {
        $model=new Portafolio;
 
        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);
 
        if(isset($_POST['Portafolio']))
        {
            $model->attributes=$_POST['Portafolio'];
 
            if($model->save()){
                //$this->redirect(array('view','id'=>$model->id));
                $this->redirect(array('portafolioPictures','id'=>$model->id));
            }
 
        }
 
        $this->render('create',array(
            'model'=>$model,
        ));
    }
 
    public function actionPortafolioPictures($id)
    {
        $model = new PortafolioPictures;
 
        $this->render('portafolioPictures', array('model' => $model, 'id' => $id));
    }
 
    public function actionAddPictures()
    {
        header('Vary: Accept');
        if (isset($_SERVER['HTTP_ACCEPT']) &&
            (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false))
        {
            header('Content-type: application/json');
        } else {
            header('Content-type: text/plain');
        }
 
        $data = array();
 
        $model = new PortafolioPictures;
        $model->picture = CUploadedFile::getInstance($model, 'picture');
        $model->portafolio_id = $_GET['id'];
 
        if ($model->picture !== null  && $model->validate(array('picture'))) {
 
            $model->picture->saveAs(Yii::getPathOfAlias('webroot') . '/images/'.$model->picture->name);
            $model->file_name = $model->picture->name;
            $model->ruta = Yii::app()->request->baseUrl . '/images/'.$model->picture->name;
 
            // save picture name
            if($model->save()) {
                // return data to the fileuploader
                $data[] = array(
                    'name' => $model->picture->name,
                    'type' => $model->picture->type,
                    'size' => $model->picture->size,
                    // we need to return the place where our image has been saved
                    'url' => $model->getImageUrl(), // Should we add a helper method?
                    // we need to provide a thumbnail url to display on the list
                    // after upload. Again, the helper method now getting thumbnail.
                    'thumbnail_url' => $model->getImageUrl(MyModel::IMG_THUMBNAIL),
                    // we need to include the action that is going to delete the picture
                    // if we want to after loading
                    'delete_url' => $this->createUrl('my/delete',
                            array('id' => $model->id, 'method' => 'uploader')),
                    'delete_type' => 'POST');
            } else {
                $data[] = array('error' => 'Unable to save model after saving picture');
            }
        } else {
            if ($model->hasErrors('picture'))
            {
                $data[] = array('error', $model->getErrors('picture'));
            } else {
                throw new CHttpException(500, "Could not upload file ".     CHtml::errorSummary($model));
            }
        }
        // JQuery File Upload expects JSON data
        echo json_encode($data);
    }

My view corresponding to the TbFileUpload is:

<?php $this->widget('booster.widgets.TbFileUpload', array(
    'url' => $this->createUrl("portafolioPictures/addPictures", array('id' => $id)),
    'model' => $model,
    'attribute' => 'picture', // see the attribute?
    'multiple' => true,
    'options' => array(
        'maxFileSize' => 2000000,
        'acceptFileTypes' => 'js:/(\.|\/)(gif|jpe?g|png)$/i',
    ))); ?>

Any help with this? what am I missing?

#17895 report it
Don Felipe at 2014/08/07 01:35pm
@joepages

The description is lacking this detail:

"Do not put TbFileUpload inside TbActiveForm."

Make sure you don't have nested forms inside your view file or anywhere. The fileupload widget generates its own form and action hence the extra URL you have to pass to the widget.

#17855 report it
joepages at 2014/07/31 11:14am
I haven't been able to configure this widget to work. Help please

Hello everyone! I've been traying to configure this widget but had no luck. Here is my code to see if you guys can help me.

1.- I set the Yii::setPathOfAlias like this:

Yii::setPathOfAlias('frontend.www.files', dirname(__FILE__) . DIRECTORY_SEPARATOR . '../../images');

2.- I created my model following my db table and using gii module generator: Rules are th ones shown bellow

public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('img_route', 'required'),
            array('title', 'length', 'max'=>45),
            array('content, img_route', 'length', 'max'=>300),
            array('picture', 'file', 'types' => 'jpg,jpeg,gif,png', 'maxSize' => 1024 * 1024 *2, 'tooLarge' => 'La imagen debe pesar menos de 2Mb', 'on' => 'upload'),
            array('picture', 'length', 'max'=>255, 'tooLong' => '{attribute} is too long (max {max} chars.', 'on' => 'upload'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, title, content, img_route, picture', 'safe', 'on'=>'search'),
        );
    }

3.- I added the widget to my _form view (This is a view of all my _form):

<?php
 
    $form = $this->beginWidget(
        'booster.widgets.TbActiveForm',
        array(
            'id' => 'horizontalForm',
            'type' => 'horizontal',
            'htmlOptions' => array('class' => 'well', 'enctype' => 'multipart/form-data'),
        )
    );
 
    ?>
 
    <fieldset>
 
        <p class="note"><?php echo UserModule::t('Fields with <span class="required">*</span> are required.'); ?></p>
 
        <?php echo $form->textFieldGroup($model, 'title'); ?>
 
        <?php echo $form->textFieldGroup($model, 'content'); ?>
 
        <div class="row-fluid">
 
            <?php
                $this->widget('booster.widgets.TbFileUpload',
                    array(
                        'url' => $this->createUrl("inicio/upload"),
                        'model' => $model,
                        'imageProcessing' => true,
                        'previewImages' => true,
                        'attribute' => 'picture', // see the attribute?
                        'multiple' => false,
                        'options' => array(
                            'maxFileSize' => 2000000,
                            'acceptFileTypes' => 'js:/(\.|\/)(gif|jpe?g|png)$/i',
                            )
                        )
                    );
            ?>
 
        </div>
 
 
 
    </fieldset>
 
    <div class="form-actions">
        <?php $this->widget( 'booster.widgets.TbButton',
            array(
                'buttonType' => 'submit',
                'context' => 'primary',
                'label' => $model->isNewRecord ? UserModule::t('Create') : UserModule::t('Save')
            )
        ); ?>
        <?php //echo CHtml::submitButton($model->isNewRecord ? UserModule::t('Create') : UserModule::t('Save')); ?>
        <?php $this->widget(
            'booster.widgets.TbButton',
            array('buttonType' => 'reset', 'label' => UserModule::t('Reset'))
        ); ?>
    </div>
 
 
    <?php
    $this->endWidget();
    ?>

4.- Then I added the action to the MyController (MyController name is: InicioController.php)

public function actionUpload()
    {
        header('Vary: Accept');
        if (isset($_SERVER['HTTP_ACCEPT']) &&
            (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false))
        {
            header('Content-type: application/json');
        } else {
            header('Content-type: text/plain');
        }
        $data = array();
 
        $model = new Inicio('upload');
        $model->picture = CUploadedFile::getInstance($model, 'picture');
        if ($model->picture !== null  && $model->validate(array('picture')))
        {
            $model->picture->saveAs(
                Yii::getPathOfAlias('frontend.www.files').'/'.$model->picture->name);
            $model->file_name = $model->picture->name;
            // save picture name
            if( $model->save())
            {
                // return data to the fileuploader
                $data[] = array(
                    'name' => $model->picture->name,
                    'type' => $model->picture->type,
                    'size' => $model->picture->size,
                    // we need to return the place where our image has been saved
                    'url' => $model->getImageUrl(), // Should we add a helper method?
                    // we need to provide a thumbnail url to display on the list
                    // after upload. Again, the helper method now getting thumbnail.
                    'thumbnail_url' => $model->getImageUrl(Inicio::IMG_THUMBNAIL),
                    // we need to include the action that is going to delete the picture
                    // if we want to after loading
                    'delete_url' => $this->createUrl('my/delete',
                            array('id' => $model->id, 'method' => 'uploader')),
                    'delete_type' => 'POST');
            } else {
                $data[] = array('error' => 'Unable to save model after saving picture');
            }
        } else {
            if ($model->hasErrors('picture'))
            {
                $data[] = array('error', $model->getErrors('picture'));
            } else {
                throw new CHttpException(500, "Could not upload file ".     CHtml::errorSummary($model));
            }
        }
        // JQuery File Upload expects JSON data
        echo json_encode($data);
    }

It isn't even showing me the preview of the images I'm trying to upload. The action that happens when I hit the button "upload images" is some refresh of the current page nothing else..

Can anyone help me getting this to work propertly? Thanks in advance!

#17653 report it
Don Felipe at 2014/07/11 08:03am
@Utopian - thumbnails

It's been a long time since the last time I used this widget and TbFileUpload respectively. When I remember correctly you have to provide the thumbnail's URL via the attribute "thumbnail_url" in the data[] array.

You can use the same action (function) for "url" and "thumbnail_url" or two different functions. When using one and the same action make sure you pass a different param (MyModel::IMG_THUMBNAIL or "thumb"=false|true) to tell the action whether to return the main image's or the thumbnail's url. Obiously, this action needs to save the image twice: 1x original image and 1x resized thumbnail.

So you didn't really do any mistake. You just missed one important detail hence action, I guess. Good luck!

#17652 report it
Utopian at 2014/07/11 07:43am
no uploaded image thumbnails

Thanks for the workout! I have one issue though. The uploaded files are not shown as thumbnails in the page. They are instead shown in their original size. What mistake did I do?

#16779 report it
SivaramAntony at 2014/03/27 03:08am
TbMultiupload

How to upload multiple file in tbupload widget

#14486 report it
Szymon Dudziak at 2013/08/16 09:57am
Missing callbacks ...

So I've added them. Please take a look.

Changes are pasted here (diff): http://pastebin.com/fET6zviZ

Please also read documentation here: https://github.com/blueimp/jQuery-File-Upload/wiki/Options

Here's a sample code how to use callbacks:

(In some view file)

$this->widget('bootstrap.widgets.TbFileUpload', array(
        'url' => $this->createUrl('image/upload'),
        'imageProcessing' => false,
        'name' => 'photo',
        'multiple' => false,
        'callbacks' => array(
                'done' => new CJavaScriptExpression(
                    'function(e, data) { alert(\'done!\'); }'
                ),
                'fail' => new CJavaScriptExpression(
                    'function(e, data) { alert(\'fail!\'); }'
                ),
        ),
    )
);

So, for example you can refresh your list after upload.

Regards, Simon

#14421 report it
kinetic_one at 2013/08/10 08:26am
Model getImageUrl

Hello Antonio,

I really appreciate the effort, but as a newbie reading this:

demo only works if the MyModel class already includes the function getImageUrl($img_type=null)

It leaves me with:

What demo and where is the link to that? What Model ? Can you provide an example with all the necessary and related code ?

Thanks for your help.

#11983 report it
bonnie at 2013/02/18 08:46am
working

I got it working what I needed but with some work around.

#11821 report it
staticblue at 2013/02/06 05:02am
Thanks Don

Hi Don,

Thanks ! I had something wrong with my model, so I used your tips to make it work. Great stuff :)

#11702 report it
bonnie at 2013/01/28 07:56am
Thanks Don

Hi Don what am trying is that I have a yii extension from class.upload.php upload extension. I have been using it in normal html and has been working fine. But now want to add the ajax function tbfileupload. The following is my code but the problem is what to pass in Upload method $handle = new Upload($model->avatar);. The way I use it is $handle = new Upload($_FILES["avatar"]); for normal way and works file but with tbfileupload things are not same I thing because the data is json. Here is what I have been trying to do.

public function actionUpload() {
    header('Vary: Accept');
    if (isset($_SERVER['HTTP_ACCEPT']) && 
        (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false))
    {
        header('Content-type: application/json');
    } else {
        header('Content-type: text/plain');
    }
    $data = array();
 
    $model = new Profile('upload');
    $model->avatar = CUploadedFile::getInstance($model, 'avatar');
    if ($model->avatar !== null  && $model->validate(array('avatar')))
    {
        // import the class
     Yii::import('application.extensions.upload.Upload');
 
     $handle = new Upload($model->avatar);
      if ($handle->uploaded)
      $handle->file_new_name_body   = 'image_resized';
      $handle->image_resize         = true;
      $handle->image_x              = 100;
      $handle->image_ratio_y        = true;
      $handle->process(Yii::app()->getBasePath().'/uploads/avatar/');
 
        $model->image_thumb_path = $model->avatar;
        $model->image_path = $model->avatar;
         if($model->model()->save())
        {
            // return data to the fileuploader
            $data[] = array(
                'name' => $model->avatar->name,
                'type' => $model->avatar->type,
                'size' => $model->avatar->size,
                // we need to return the place where our image has been saved
                //'url' => $model->getImageUrl(), // Should we add a helper method?
                // we need to provide a thumbnail url to display on the list
                // after upload. Again, the helper method now getting thumbnail.
                //'thumbnail_url' => $model->getImageUrl(MyModel::IMG_THUMBNAIL),
                // we need to include the action that is going to delete the avatar
                // if we want to after loading 
                'delete_url' => $this->createUrl('my/delete', 
                    array('id' => $model->id, 'method' => 'uploader')),
                'delete_type' => 'POST');
        } else {
            $data[] = array('error' => 'Unable to save model after saving avatar');
        }
    } else {
        if ($model->hasErrors('avatar'))
        {
            $data[] = array('error', $model->getErrors('avatar'));
        } else {
            throw new CHttpException(500, "Could not upload file ".     CHtml::errorSummary($model));
        }
    }
    // JQuery File Upload expects JSON data
    echo json_encode($data);
    }

From the official page it says. How to process a file uploaded via XMLHttpRequest? Use the class as following, the rest being the same as above:

$handle = new upload('php:'.$_SERVER['HTTP_X_FILE_NAME']);

Prefixing the argument with "php:" tells the class to retrieve the uploaded data in php://input, and the rest is the stream's filename, which is generally in $_SERVER['HTTP_X_FILE_NAME'] class.upload.php

#11613 report it
Don Felipe at 2013/01/23 12:19am
@staticblue @bonnie ... Internal Server Error

The Internal Server Error most likely means there is something wrong with your $model (missing attributes), the database table of the model, or the server side path for the file upload. Please check the following:

1) Make sure the file upload folder exists and the absolute path is set correctly. Ideally the upload folder is under htdocs/ (or Sites/) or even in your webapp-folder (but not inside protected). Then add the absolute path to the config file ./protected/config/main.php

<?php
 
Yii::setPathOfAlias('frontend.www.files','/ABSOLUTE-PATH-TO-UPLOAD-FOLDER');
 
return array(

Alternatively you can set 2 aliases in main config:

Yii::setPathOfAlias('fileupload.path','/ABSOLUTE-PATH-TO-UPLOAD-FOLDER');
Yii::setPathOfAlias('fileupload.url','URL-TO-UPLOAD-FOLDER');

2) Add the 2 attributes $picture and $file_name to the model class accordingly. In fact, we will not use $file_name in 3). Check if you are using the same $model in the view and controller action.

3) Use the following code block in your controller action. We do this only for a quick test that only consists of the file upload and ignores the database. Be careful when replacing the block
from $model = new MyModel up to } else {

$model = new MyModel('upload');
$model->picture = CUploadedFile::getInstance($model, 'picture');
 
if ($model->picture !== null  && $model->validate(array('picture')))
{
    $model->picture->saveAs(
    Yii::getPathOfAlias('frontend.www.files').'/'.$model->picture->name);
    //Yii::getPathOfAlias('fileupload.path').'/'.$model->picture->name);
 
    $data[] = array(
        'name' => $model->picture->name,
        'type' => $model->picture->type,
        'size' => $model->picture->size,
        // we need to return the place where our image has been saved
        'url' => 'URL-TO-WEBAPP'.'/upload/'.$model->picture->name); 
        //Yii::getPathOfAlias('fileupload.url').'/'.$model->picture->name);
    );
} else {
  //...

Adjust URL-TO-WEBAPP!

If it still does not work, then you need to use firebug and post the console output here. If it is working, add everything else step by step again.

Last not least, I will re-do this wiki and add more details asap.

#11609 report it
bonnie at 2013/01/22 08:55pm
Am getting Internal Server Error too.

Did you get any solution staticblue.

#11480 report it
staticblue at 2013/01/16 02:47am
internal server error

Hi Don,

Thanks for the great tutorial. When I click the upload button, I get an internal server error. Is this something you have encountered before ?

Thanks, Jonathan

#10998 report it
Don Felipe at 2012/12/09 11:23pm
just a few things

There's a closing bracket missing at the end of this line

if ($model->picture !== null  && $model->validate(array('picture'))
//should be
if ( $model->picture !== null  && $model->validate(array('picture')) )

Then, of course and to avoid any confusion:

  • this demo only works if the MyModel class already includes the function getImageUrl($img_type=null). If not, comment the 2 lines inside the data array, where 'url' and 'thumbnail_url' are defined, to make the demo work;
  • if the MyModel has a different name, it needs to be replaced 1-2 times inside the upload action;
  • the url where we are going to upload our files => upload action

Adding the jQuery file upload to YiiBooster is awesome and saves a lot of extra work. Thanks, Antonio.

Leave a comment

Please to leave your comment.

Write new article