FileReferenceList、引数と戻り値

FICC安藤です、遅ればせながらやっとAS3に移行を始めたので習作を兼ねたエントリーです。

個人的な理由でファイルのアップローダーが必要になり何でもかんでもFlashベースに組んでしまうのがFlash使いの悪いクセだと思いhtmlベースのフォームで作ってみると、複数ファイルのアップロードが意外と面倒くさいということに気づきました。

結局Flashの出番です。

Flash8から利用可能になったFileReferenceListは複数ファイルを一気に選択してアップロードができる便利なクラスでしたが放り投げたファイルを追いかけるのが厄介なクラスでもありました。
CS3への変更時にその辺が改善されたので今更感もありますが、画像をFileReferenceListを使ったサンプル「FIleReferenceList、引数と戻り値」です。

サンプルファイル一式はこちら

とりあえず試してみるにはダウンロードしたファイルの中から、PHPファイルだけ実行可能なサーバにアップロードしてFileUploader.as の17行目を書き換えて書き出してみましょう。

PHPはファイルの容量制限や、画像のタイプなどはチェックは省いてますので必要に応じて付け加えてください。

以下コード

FileUploader.as

package{
 import fl.controls.Button;
 import fl.controls.Label;
 import fl.controls.TextArea;
 
 import flash.display.Sprite;
 import flash.events.DataEvent;
 import flash.events.Event;
 import flash.events.FocusEvent;
 import flash.events.MouseEvent;
 import flash.events.ProgressEvent;
 import flash.net.FileFilter;
 import flash.net.URLVariables;
 import flash.text.TextFieldAutoSize;
 
 public class FileUploader extends Sprite{
 public const UPLOAD_PHP_URL:String = 'http://yourdomain/php/sample_uploader.php';
//============================================================================================//
//  COUSTRUCTOR
//============================================================================================//
 public function FileUploader(){
   init();
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  init
//--------------------------------------------------------------------------------------------------------------------------------//
  private function init():void{
   btnBrowse.addEventListener(MouseEvent.CLICK, browse);
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  reset
//--------------------------------------------------------------------------------------------------------------------------------//
  private function resetUploader(_evt:Event):void{
   removeChild(getChildByName('txaResult'));
   removeChild(getChildByName('btnClose'));   
   txiWidth.enabled = true;
   txiHeight.enabled = true;
   btnBrowse.enabled = true;
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  browse
//--------------------------------------------------------------------------------------------------------------------------------//
  private function browse(_evt:Event):void{
   if(txiWidth.text && txiHeight.text){
    var urlVariables:URLVariables = new URLVariables();
    urlVariables.imgMaxWidth = txiWidth.text;
    urlVariables.imgMaxHeight = txiHeight.text;
      var fileRef:CustomFileReferenceList = new CustomFileReferenceList(UPLOAD_PHP_URL, urlVariables);
    fileRef.addEventListener(Event.SELECT, onUploadStart);
    fileRef.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
    fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
    fileRef.browse(new Array(new FileFilter('Images (*.jpg, *.jpeg)', '*.jpg;*.jpeg;'))); 
   }
  }
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadStart
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadStart(_evt:Event):void{
   txiWidth.enabled = false;
   txiHeight.enabled = false;
   btnBrowse.enabled = false;
   var lblProgress:Label = new Label();
   lblProgress.name = 'lblProgress';
   lblProgress.x = Math.round(stage.stageWidth / 2 - lblProgress.width / 2);
   lblProgress.y = 230;
   lblProgress.text = 'アップロード開始';
   lblProgress.autoSize = TextFieldAutoSize.CENTER;
   addChild(lblProgress);
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadProgress
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadProgress(_evt:ProgressEvent):void{
   var progress:int;
   if(_evt.bytesLoaded == _evt.bytesTotal){
    progress = 100;
   }else{
    progress = Math.round(_evt.bytesLoaded / _evt.bytesTotal * 100);
   }
   getChildByName('lblProgress')['text'] = progress + '%';
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadCompleteData
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadCompleteData(_evt:Event):void{
   removeChild(getChildByName('lblProgress'));
   var txaResult:TextArea = new TextArea();
   txaResult.name = 'txaResult';
   txaResult.x = 20;
   txaResult.y = 20;
   txaResult.width = 260;
   txaResult.height = 240;
   addChild(txaResult);
 
   var result = _evt.target.result;
   for(var i:int = 0; i<result.length; i++){
    txaResult.appendText('----------------------------------\n');
    for(var val in result[i]){
     txaResult.appendText(val + '=' + result[i][val] + '\n');
    }
   }
 
   var btnClose:Button = new Button();
   btnClose.name = 'btnClose';
   btnClose.label = 'close';
   btnClose.x = Math.round(stage.stageWidth / 2 - btnClose.width / 2);
   btnClose.y = 270;
   addChild(btnClose);
   btnClose.addEventListener(MouseEvent.CLICK, resetUploader);
  }  
 }
}

CustomFileReferenceList.as

package {
 import flash.events.ProgressEvent;
 import flash.events.DataEvent;
 import flash.events.Event;
 import flash.events.HTTPStatusEvent;
 import flash.events.IOErrorEvent;
 import flash.events.SecurityErrorEvent;
 import flash.net.FileReference;
 import flash.net.FileReferenceList;
 import flash.net.URLRequest;
 import flash.net.URLRequestMethod;
 import flash.net.URLVariables;
 
 class CustomFileReferenceList extends FileReferenceList {
//  VARIABLES
  private const LOADED_SUFFIX:String = "_loaded";
  private const TOTAL_SUFFIX:String = "_total";
  private var urlRequest:URLRequest;
  private var pendingFiles:Array;
  private var objUploadProgress:Object;
  private var _result:Array;
//============================================================================================//
//  CONSTRUCTOR
//============================================================================================//
  public function CustomFileReferenceList(_uploadPHPURL:String, _urlVariables:URLVariables) {
   urlRequest = new URLRequest();
   urlRequest.url = _uploadPHPURL;
   urlRequest.method = URLRequestMethod.POST;
   urlRequest.data = _urlVariables;  
   addEventListener(Event.SELECT, onSelect);
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onSelect
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onSelect(event:Event):void {
   _result = new Array();
   objUploadProgress = new Object();
   pendingFiles = new Array();
 
   var file:FileReference;
   for (var i:uint = 0; i < fileList.length; i++) {
    file = FileReference(fileList[i]);
    objUploadProgress[file.name + LOADED_SUFFIX] = 0;
    objUploadProgress[file.name + TOTAL_SUFFIX] = 0;
    addPendingFile(file);
   }
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  addPendingFIle
//--------------------------------------------------------------------------------------------------------------------------------//
  private function addPendingFile(file:FileReference):void {
   pendingFiles.push(file);
   file.addEventListener(Event.COMPLETE, fileUploadInteraction);
   file.addEventListener(IOErrorEvent.IO_ERROR, fileUploadInteraction);
   file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileUploadInteraction);
   file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
   file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
   file.upload(urlRequest);
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  removePendingFile
//--------------------------------------------------------------------------------------------------------------------------------//
  private function removePendingFile(file:FileReference):void {
   for (var i:uint; i < pendingFiles.length; i++) {
    if (pendingFiles[i].name == file.name) {
     pendingFiles.splice(i, 1);
    return;
    }
   }
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  eventHandlers
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function fileUploadInteraction(_evt):void{
   var file:FileReference = FileReference(_evt.target);
   switch(_evt.type){
    case Event.COMPLETE:
     removePendingFile(file);
     break;
    case IOErrorEvent.IO_ERROR:
     trace("ioErrorHandler: name=" + file.name);
     break;
    case SecurityErrorEvent.SECURITY_ERROR:
     trace("securityErrorHandler: name=" + file.name + " event=" + _evt.toString());
     break;
   }
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadProgress
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadProgress(_evt:ProgressEvent):void{
   var file:FileReference = FileReference(_evt.target);
   objUploadProgress[file.name + LOADED_SUFFIX] = _evt.bytesLoaded;
   objUploadProgress[file.name + TOTAL_SUFFIX] = _evt.bytesTotal;
   var loaded:int = 0;
   var total:int = 0;
   for(var i:int = 0; i<pendingFiles.length; i++){
    var tmpLoaded:int = objUploadProgress[pendingFiles[i].name + LOADED_SUFFIX];
    var tmpTotal:int = objUploadProgress[pendingFiles[i].name + TOTAL_SUFFIX];
    if(tmpLoaded != tmpTotal && tmpTotal != 0){
     loaded += tmpLoaded;
     total += tmpTotal;
    }
   }
   dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, loaded, total));
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploaded
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadCompleteData(_evt:DataEvent):void{
   var resultObj:Object = new Object();
   var splitedDataList:Array = _evt.data.split('&');
   for(var i:int = 0; i<splitedDataList.length; i++){
    var splitedData:Array = splitedDataList[i].split('=');
    resultObj[splitedData[0]] = splitedData[1];
   }
   _result.push(resultObj);
   if (pendingFiles.length == 0) {
    dispatchEvent(new Event(DataEvent.UPLOAD_COMPLETE_DATA));
   }   
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  removePendingFile
//--------------------------------------------------------------------------------------------------------------------------------//  
  public function get result():Array{
   return  _result;
  }
 }
}

参考:Adobe livedoc

トラックバック(0)

このブログ記事を参照しているブログ一覧: FileReferenceList、引数と戻り値

このブログ記事に対するトラックバックURL: http://www.ficc.jp/cgi-bin/mt4/mt-tb.cgi/14

コメントする