zk546113096 2011-05-17 14:24:43 17636次浏览 34条回复 0 0 0

Agile Web Application Development with Yii 1.1 and PHP5I regularly used SWFUpload in my projects to handle multiple file uploads, most of them picture gallery related functions. Just because I am using Yii now I wasn’t going to change that, so I was ready to build my SWFUpload extension in order to continue with my ‘traditional’ way of doing things. One of the lessons learned along these years of programming is not to reinvent the wheel and first thing I did was searching the Yii extensions repository just to check if anybody has done something like that before; and yes, somebody did: mr ThiagoVidal. That made things easier :)

I made small modifications to the extension as I didn’t like the handlers.js file (is part of the SWFUpload package) to be outside of the extension’s package. I thought that a plug and play extension should be all in one place, so it is easier to use and move around projects. So, for the sake of this example, and if mr ThiagoVidal haven’t updated my modifications, please download the zipped package below. Installation

Once you download the files, unzip the contents of the package and place all in your applications protected/widgets folder. How to use

First of all, we need to tweak our index.php file. This is because SWFUpload requirements with a variable named PHPSESSID that is needed for handling file uploads. Due that is a conditional statement I decided to put it in the main file as won’t affect at all the rest of the application.

if (isset($_POST['PHPSESSID']))
{
    $_COOKIE['PHPSESSID'] = $_POST['PHPSESSID'];
}

Now, we are going to construct a view that will handle the uploads. The following example is extracted from one of my projects that most of the CMS calls are done through AJAX and this view is actually displayed via fancybox . In our view, we first configure the SWFUpload widget and afterwards its HTML like this:

SWFUpload

//'use_query_string'=>true,
// Creating the URL that will handle our uploads
// check the parameter at the end
// $uurl = $this->createUrl('picture/upload',array('yourvarname'=>$yourvar));
$uurl = $this->createUrl('picture/upload');
// here is our widget!
$this->widget('widgets.CSwfUpload', array(
// here you include the post params you want the
// upload function to handle when a file is submitted
//  'postParams'=>array('yourvarname'=>$yourvar),
'config'=>array(
    'use_query_string'=>false,
    //Use $this->createUrl method or define yourself
    'upload_url'=> CHtml::normalizeUrl($uurl),
   // This is a workaround to avoid certain
   // issues (check SWFUpload Forums)
   'file_size_limit'=>'2 gb',
   // Allowed file types
   'file_types'=>'*.jpg;*.png;*.gif',
   // File types description (mine spanish)
   'file_types_description'=>'Imagenes',
   // unlimited number of files
   'file_upload_limit'=>0,
   // refer to handlers.js from here below
   'file_queue_error_handler'=>'js:fileQueueError',
   'file_dialog_complete_handler'=>'js:fileDialogComplete',
   'upload_progress_handler'=>'js:uploadProgress',
   'upload_error_handler'=>'js:uploadError',
   'upload_success_handler'=>'js:uploadSuccess',
   'upload_complete_handler'=>'js:uploadComplete',
   // what is our upload target layer?
   'custom_settings'=>array('upload_target'=>'divFileProgressContainer'),
   // where are we going to place the button?
   'button_placeholder_id'=>'swfupload',
   'button_width'=>230,
   'button_height'=>20,
   'button_text'=>'<span class="button">Selecciona las Imagenes (2 MB Max)</span>',
   'button_text_style'=>'.button { font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; font-size: 11pt; text-align: center; }',
   'button_text_top_padding'=>0,
   'button_text_left_padding'=>0,
   'button_window_mode'=>'js:SWFUpload.WINDOW_MODE.TRANSPARENT',
   'button_cursor'=>'js:SWFUpload.CURSOR.HAND',
   ),
  )
);

HTML

<!-- SPANISH sorry -->
<div id="main-content">
<h2>Cargador de Im&aacute;genes</h2>
<p>Haz click en el siguiente boton para cargar las im&aacute;genes de la Propiedad.
El cargador de Im&aacute;genes las cargar&aacute; y redimensionar&aacute; autom&aacute;ticamente.
</p>
<form>
<div class="form">
    <div class="row">
    <div class="swfupload"  style="display: inline; border: solid 1px #7FAAFF; background-color: #C5D9FF; padding: 2px;">
       <span id="swfupload"></span>
    </div>
    <div id="divFileProgressContainer" style="height: 75px;"></div>
    <div id="thumbnails"></div>
    </div>
</div>
</form>
</div>

Ok, now that we have our view (and placed in its correspondent folder within your application’s protected/view folder), we need to have a controller that handles the file uploads of SWFUpload and the rendering of the view. I have one controller named picture that renders the view on an uploader action and handles the uploads through its upload action. One thing very important is that we remove accessControl’s filters for our Upload action, otherwise our code just won’t work at all. Please, remember to set the rules() of your controller for each action respectively, I have them set only accessible by the administrator in my CMS. Here is the code:

//
// lets remove access control filters
// for our upload action
public function filters()
{
   return array(
     'accessControl -upload',
    );
}
public function actionUploader(){
// In case you wish to  post a variable each time a file
// is uploaded. This is good if a picture is related to an object
// and you wish to pass the ID so to related both picture
// or file to parent.
// $yourvar = 'variabletopost';
// $this->render('uploader',array('yourvar'=>$yourvar));
   $this->render('uploader');
   // In my case is AJAX
   Yii::app()->end();
}
// For the sake of simplicity the following function
// does not have any file validation procedures
// I highly recommend you that you create one
// If you need help, let me know, and I will forward
// mine so you see an example.
public function actionUpload(){
 try{
     // get the file
     $picture_file = CUploadedFile::getInstanceByName('Filedata');
     if(!$picture_file || $picture_file->getHasError()){
    echo 'Error: Documento Invalido';
    Yii::app()->end();
     }
     // remember the post params?
     // $yourvar = Yii::app()->request->getParam('yourvarname');
     $picture_name = $picture_file->name;
     //
     // I normally here I use PhpThumb Library instead of this
     // make sure 'thepathyousavethefile' is a writable path
     $picture_file->saveAs(
         Yii::getPathOfAlias('thepathyousavethefile').
         $picture_name
      );
      // Return the file id to the script
      // This will display the thumbnail of the uploaded file to the view
      echo "FILEID:" . Yii::app()->getBaseUrl() .
         '/thepathyousavethepicture/' .
         $picture_name;
     }
     catch(Exception $e){
    echo 'Error: ' . $e->getMessage();
     }
     Yii::app()->end();
}

Final Words

I would like to remark that the upload action I created above is very simple and some file validations should be applied such as checking their sizes, file types, and so on. I used this approach without problems at all.

[attach]150[/attach]

您需要登录后才可以回复。登录 | 立即注册