NAS Uploader, comment ça marche ?

Très simplement, NAS Uploader est constitué d'un fichier .swf pour gérer l'upload, un fichier .js pour la communication avec les autres éléments de la page et d'un script côté serveur qui va traiter les fichiers uploadés. Les exemples de démonstration sont fournis avec un fichier php mais vous pouvez vous même développer le fichier de traitement pour toute autre plateforme (ASP, JAVA, .NET, etc etc ...).

Côté flash


Voici le script côté flash. la plupart des gestionnaires offerts par le language Action Script sont implémentés. La gestion des erreurs au niveau du script serveur comprends simplement l'affichage du message renvoyé par le script dans le champ de texte du fichier correspondant.

import flash.external.*;
/**** JS / FLASH FUNCTIONS **/
_root.vargetgoupload = '';
// variables get envoyées par JS depuis la fonction goUpload
//
_root.vargetsessions = ''; 
// variables de session php qu'on récup via le fichier 
//getdata.php et qu'on va transformer en variables get

//
//
function goUpload(str:String):Void {
    trace('goUpload');
    _root.vargetgoupload = str;
    varstatusText = "Upload en cours...";
    trace('--');
    uploadImages(event);
}
ExternalInterface.addCallback("goUpload", null, goUpload);


// fonction lancée si on clique sur le bouton uploader dans flash
function goUploadFlash():Void {
    varstatusText = "Upload en cours...";
    uploadImages(event);
}

function getSessionVars() {
    var varEmetteur:LoadVars = new LoadVars();
    var varRecepteur:LoadVars = new LoadVars();
    //on crée un nouvel objet date
    dateCourante = new Date();
    //on attribue à l'objet loadVars émetteur nos paramètres ainsi que la date
    varEmetteur.date = dateCourante.getTime();
    varRecepteur.onLoad = function(succes) {
        if (succes) {
            trace('txt loaded');
                
            _root.vargetsessions = varRecepteur.varsession; 
            trace(_root.vargetsessions);
            //varstatusText = _root.vargetsessions;
        }
    };
    // le chemin de getdata est donné par rapport au chemin de la page dans laquelle se trouve l'animation
    varEmetteur.sendAndLoad('getdata.php', varRecepteur, "POST");
}
//on load une première fois
getSessionVars() ;
/*****************/
stop();
varstatusText = "Choisissez des fichiers à uploader.";
function resetall(event) {
    list = new Array();
    files = new Array();
    browsebtn.enabled = true;
    uploadBtn.enabled = false;
    newfile = 1;
    totalsize = 0;
    _root.total = 0;
    my_sp.refreshPane();
    varstatusText = "Choisissez des fichiers à uploader !";
}
//
function browser(event) {
    fileRefList.browse([{description:"Image files", extension:"*.jpg;*.gif;*.png", macType:"JPEG;jp2_;GIFF"}]);
}
//
function uploadImages(event) {
    browsebtn.enabled = false;
    uploadBtn.enabled = false;
    up(uploadindex);
}
//
function up(num) {
    selectedFile = list[num];
    selectedFile.addListener(this);
    // varget est récupéré dans les flashvars
    // _root.vargetgoupload est potentiellement envoyé en argument dans 
    //la fonction javascript goUpload
    //_root.vargetsessions est potentiellement envoyé par le fichier getdata.php qui 
    // peut servir à renvoyer des variables de session au format get
    
    //
    //
    //le chemin du fichier d'upload est donné par rapport au chemin du fichier swf nasuploader 
    selectedFile.upload("../upload_filemanager.php?"+varget+_root.vargetgoupload+_root.vargetsessions);
    
}
// End of the function
var selectedFile;
var listener = new Object();
var list = new Array();
files = new Array();
var newfile = 0;
var totalsize = 0;
var uploadindex;
uploadBtn.enabled = false;
uploaded = false;
_root.statusText = ""+uploadUrl;
var uploadedfiles = new Array();
var work_id;
var fileIds = new Array();
_root.Title = Title.length != undefined ? (Title) : ("");
listener.onSelect = function(fileRefList) {
    uploadindex = 0;
    browsebtn.enabled = true;
    uploadBtn.enabled = true;
    var _loc4 = new Array();
    _loc4 = fileRefList.fileList;
    for (var _loc3 = 0; _loc3<_loc4.length; ++_loc3) {
        selectedFile = _loc4[_loc3];
        list.push(selectedFile);
        //on envoie le nom du fichier au js
        ExternalInterface.call("Update_File", selectedFile.name);
        //
        selectedFile.addListener(this);
        obj = new Object();
        obj.file_name = selectedFile.name;
        obj.file_size = selectedFile.size;
        totalsize = Number(totalsize)+Number(selectedFile.size);
        obj.upload_bytes = 0;
        obj.status = 0;
        obj.erroruploadtxt = ''; //erreur renvoyée par php en string
        obj.error = "";
        _root.files.push(obj);
        _root.newfile = 1;
        my_sp.refreshPane();
    }
    // 
    _root.total = list.length;
};
var fileRefList = new flash.net.FileReferenceList();
fileRefList.addListener(listener);
browsebtn.addEventListener("click", browser);
uploadBtn.addEventListener("click", goUploadFlash);
resetbtn.addEventListener("click", resetall);
/*********************/
listener.onOpen = function(selectedFile) {
    files[uploadindex].status = 1;
};
listener.onProgress = function(File, bytesLoaded, bytesTotal) {
    trace('uploadindex='+uploadindex);
    files[uploadindex].status = 1;
    files[uploadindex].upload_bytes = bytesLoaded/bytesTotal*100;
    newfile = 1;
    my_sp.refreshPane();
};
listener.onHTTPError = function(file, httpError) {
    files[uploadindex].error = errorString;
    files[uploadindex].status = 3;
    ++uploadindex;
    if (uploadindex<list.length) {
        up(uploadindex);
    }
    //  
};
listener.onIOError = function(file) {
    files[uploadindex].error = errorString;
    files[uploadindex].status = 3;
    ++uploadindex;
    if (uploadindex<list.length) {
        up(uploadindex);
    }
    // 
};
listener.onSecurityError = function(file, errorString) {
    files[uploadindex].status = 3;
    files[uploadindex].error = errorString;
};
listener.onUploadCompleteData = function(selectedFile, errorString:String):Void  {
    trace('uploadindex onUploadCompleteData='+uploadindex);
    if (errorString != '1.') {
        ExternalInterface.call("Upload_File_Finished", 'error : '+errorString);
        //erreur php
        files[uploadindex-1].status = 3;
        files[uploadindex-1].erroruploadtxt = errorString;
        
    } else {
        ExternalInterface.call("Upload_File_Finished", files[uploadindex-1].file_name);
        //ok fichier uploadé
        files[uploadindex-1].status = 2;
        files[uploadindex-1].erroruploadtxt = ''; // pas d'erreur
    }
    my_sp.refreshPane();
};
listener.onComplete = function(selectedFile) {
    trace('uploadindex onComplete='+uploadindex);
    
    if (files[uploadindex].status == 1 ) {
        files[uploadindex].status = 2;
    }
    
    files[uploadindex].upload_bytes = 100;
    newfile = 1;
    my_sp.refreshPane();
    statusArea.text = statusArea.text+("uploadindex :"+uploadindex+"uploaded");
    ++uploadindex;
    if (uploadindex<list.length) {
        up(uploadindex);
    } else {
        uploaded = true;
        varstatusText = "Upload terminé";
        ExternalInterface.call("Upload_Finished");
    }
    // 
};

Attention toutefois, le gestionnaire onUploadCompleteData est une fonctionnalité récente d'Action Script. Aussi il vous faudra une version de flash supérieure à Flash 8 pour que cet événement se déclenche en mode "prévisualisation de l'animation" dans l'interface de développement Flash. En effet la preview de flash utilise le flashplayer associé à la version de flash que vous utilisez (et pas celui de votre navigateur). Donc cet événement peut ne pas être détecté.

Toutefois utiliser Flash 8 pour coder et compiler l'animation ne vous empèche pas de la faire fonctionner parfaitement dans votre navigateur pourvu qu'il ait une version du flash player récente ! Pas de panique, pas besoin d'acheter une nouvelle licence Flash !

Au niveau de l'utilisation le gestionnaire onUploadCompleteData sert à récupérer le message envoyé par votre fichier côté serveur. La réception de ce message sert à mettre à jour l'état du fichier une fois uploadé. Upload OK (réponse = 1.) la barre devient verte, Erreur (réponse = [message texte de l'erreur] : la barre devient rouge et l'erreur s'affiche.

Le taux de pénétration du flash player 9 (prenant en compte ce gestionnaire) étant de 97% à l'heure ou j'écris ces lignes. NAS Uploader devrait fonctionner parfaitement chez la plupart de vos visiteurs... Ce qui est plutôt bien quand on regarde le nombres de bugs qui surviennent sur les diférents navigateurs en terme d'implémentation de mass uploaders en Ajax/javascript...

Côté javascript


Deux petites fonctions toutes simples qui vont vous permettre d'interagir avec le reste de votre code javascript. Avant d'exécuter la première par exemple vous pouvez créer un bouton qui lance une fonction de vérification du formulaire puis la fonction goUpload() si tout est OK.

De même, une fois l'upload terminé, le script appelle la fonction Upload_Finished() et lui passe un, deux ou n paramètres (selon ce que vous aurez défini dans flash). A vous de traiter ensuite avec javascript comme bon vous semble ... Lancez des fonctions Ajax, ouvrez des popups, chargez d'autres fichiers ... la voie est libre !

//lance l'upload ds flash

function goUpload(vargetgoupload) {
    alert ('fonction JS goUplad : debut upload flash - variables GET envoyées : ' + vargetgoupload);
    //en créant la balise flash avec swfobject.js on est plus obligé de tester le navigateur
    document.getElementById('nasuploader').goUpload(vargetgoupload);
}

//function lancée par flash une fois l'up  d'un fichier fini
function Upload_File_Finished(nomfichier) {
    alert('Fonction JS Upload_File_Finished : un upload un fichier fini : ' + nomfichier);    
}  
//function lancée par flash une fois l'up de tous les fichiers fini
function Upload_Finished(param1, param2) {
    alert('Fonction JS Upload_Finished : upload total fini');
    alert ('on soummet le formulaire');
    document.getElementById('form_upload').submit();
}   

//exécuté à chaque ajout d'un fichier 
function Update_File(file) {
    alert('Fonction JS Update_File : Ajout 1 un fichier à la liste : '+ file);
    
}
   

Côté serveur


Voici un exemple de script php simple pour traiter les uploads.
Côté serveur la réponse DOIT ÊTRE 1. si le fichier est bien uploadé (ne pas oublier le point !) s'il y a eu une erreur affichez simplement le message que vous souhaitez voir apparaitre sur la ligne du fichier en erreur. Les messages affichés doivent être encodés UTF-8 car Flash attends ce type d'encodage dans ses variables de retour.


<?php



    
//print_r($_FILES);
    
if (isset($_FILES["Filedata"])) {
     if(
$_FILES["Filedata"]['error'] == 0){ 
     
    
     
           
$tabfile explode('.',  $_FILES['Filedata']['name']);
            
$nomfile $tabfile[0];
            
$extfi $tabfile[1];
            
            
// si par exemple on a passé à l'url d'upload un paramètre en GET
            
$save_path "uploads/".$_GET['dossierup'];        
                
                
    if (
file_exists($save_path $_FILES['Filedata']['name'])) {
     echo 
utf8_encode('Un fichier porte déjà ce nom dans ce dossier');
  } else {
            
        if (
move_uploaded_file($_FILES["Filedata"]["tmp_name"], $save_path.convertion_pour_url(txt_maj($_FILES["Filedata"]["name"])))) {
        
                
         echo 
utf8_encode('1');
             
             
             
             
             } else {
              echo 
utf8_encode('Erreur d\'écriture');
             }
             
             
             
             }
             
             
             
             
        } else {
          switch (
$_FILES["Filedata"]['error']) {
            case 
1:
            echo 
'Fichier trop volumineux';
            break;
            case 
2:
            echo 
'Fichier trop volumineux';
            break;
            case 
3:
            echo 
'Fichier incompley';
            break;
            case 
4:
            echo 
'Pas de fichier';
            break;
            case 
5:
            echo 
'Erreur inconnue';
            break;
            case 
6:
            echo 
'Erreur serveur'//pas de dossier tmp
            
break;
            case 
7:
            echo 
utf8_encode('Erreur d\'écriture');
            break;
            case 
8:
            echo 
'Extension incorrecte';
            break;
            default:
            echo 
'Erreur inconnue';
            break;
          }
        }
    } else {
      echo 
utf8_encode("Pas de fichiers envoyés");
    }
    

        echo 
utf8_encode('.');
?>