YiiBooster: How to use TbFileUpload Widget

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 thefiles 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

9 thoughts on “YiiBooster: How to use TbFileUpload Widget

  1. Great tutorial.

    Would it be possible for you to create and publish on your website a tutorial for the TbDateRangePicker, and some off the other YiiBooster widgets, in the very near future.

    Thank you

  2. Will do Lloyd!

    This is the requests by the community:

    – FileUpload with RedactorJS widget (but I am going to use YiiWheels this time :) )
    – Modal on CGridView
    – TbDateRangePicker maybe? Just for you

  3. Thank you for the positive response.

    Can you explain what YiiWheels is and another project YiiStrap, that you are working on.

  4. YiiWheels is a widget library that will enhance YiiStrap. The difference between YiiWheels and YiiBooster is no other than it avoids the registration of all the assets at once, encapsulating them to each of their correspondent widgets. That is, no unnecessary assets will be used.

    Also, YiiWheels takes advantage or the less hierarchical approach of YiiStrap compared to its predecessor, Yii-Bootstrap. Speeding up what it was for YiiBooster a huge issue.

    Finally, YiiWheels will always require YiiStrap, so there are not two versions of the same application (as it was with their correspondent predecessors)

  5. Hi Antonio! I’m following your tutorial, but when I tried the add files widget button, shows me the window to select the file, I select the file and nothing happens on my page! I’m confused if the widget work like the example page you put on resource.

    thank you for your help!

  6. Hi,

    Is there a DateRangePicker widget, in your new YiiWheels extension, and if so is there a complete example (controller, model, view) or tutorial for this widget

    Thank you

  7. HI antonio,

    I have pasted the same code but when i browse the image and select then the thumbnail doesn’t appear in down of the div.

    What should be the error?

Leave a Reply

Your email address will not be published. Required fields are marked *