diff --git a/gtf.engine/gtf.engines/Traitement.class.inc b/gtf.engine/gtf.engines/Traitement.class.inc
index f00fcf53eaae2f6bc60b93aa4fd6a5ea6f090c8f..1d3c1717b3c43cc014754285190acad1b70a1124 100755
--- a/gtf.engine/gtf.engines/Traitement.class.inc
+++ b/gtf.engine/gtf.engines/Traitement.class.inc
@@ -16,7 +16,10 @@
 require_once ("vmlib/phpUtil.inc");
 require_once ("vmlib/logUtil.inc");
 require_once ("vmlib/stringUtil.inc");
+require_once ("vmlib/cryptUtil.inc");
 require_once ("gtf_lib/GtfFmwParser.class.inc");
+require_once ("vmlib/Email.class.inc");
+require_once ("gtf_lib/gtf_object/Order.class.inc");
 require_once 'string.inc';
 
 class Traitement {
@@ -82,6 +85,37 @@ class Traitement {
     var $sSource;
     var $sSourceTemp = "";
 
+    /**
+     * Paramètres de cryptage du résultat.
+     */
+    var $bDataEncrypt = false;
+    var $sSecretKey;
+    
+    /**
+    Pramaètre pour modifir la GTF_CONNECTION_STRING
+    */
+    var $bUseExternalDbConnection = false;
+    
+    /**
+     * Formatage des paramètres différent si le traitement est envoyé vers Fme Server.
+     */
+    var $bFmeServer = false;
+    
+    /**
+     * Nom de répertoire du résultat de la demande.
+     */
+    var $sResultDirectoryName = '';
+    
+    /**
+     * Chemin vers le répertoire du résultat de la demande.
+     */
+    var $sResultDirectoryPath = '';
+    
+    /**
+     * Tableau contenant la liste des fichiers de destination.
+     */
+    var $aDestinationFiles = array();
+
     /**
      * Cette méthode permet d'initialiser les variables.
      * \param $oBd Connexion à la base de données.
@@ -113,15 +147,6 @@ class Traitement {
      * \param $sFmwFileName Nom du fichier FMW associé à la demande.
      */
 
-    /**
-     * Cette méthode permet de générer un nom de fichier unique.
-     * \return une chaîne de caractères.
-     */
-    function UniqFileName() {
-        $sUniqFileName = date('YmdHis') . rand(1, 100000);
-        return $sUniqFileName;
-    }
-
     /**
      * Cette méthode permet de générer un tableau de paramètres à partir d'une chaîne dont les délimiteurs sont "|" et "=".
      * \param $sAllParams Chaine composé de tous les paramètres.
@@ -132,7 +157,7 @@ class Traitement {
         $aLigne = explode("|", $sAllParams);
         //$aLigne = stringExplode($sAllParams, "|", "\"", "\"");
         foreach ($aLigne as $sValeur) {
-            $aValeurs = explode("=", $sValeur);
+            $aValeurs = explode("=", $sValeur, 2);
             if ($aValeurs[1] == "") {
                 writeToLog(INFO_NULL_ELEMENT . $aValeurs[0] . ".", $this->sRobotLogFile);
             }
@@ -154,6 +179,8 @@ class Traitement {
         $sExeName = "FME";
         if (!$this->bErreur) {
             set_time_limit(0);
+            // Déclaration du tableau de résultat (IMPORTANT!).
+            $aResult = array();
             //$sResultCommande = exec('"'.$this->aProperties["fme_path"].'" APPLY_SETTINGS "Python/Python Interpreter"', $aResult, $iResult);
             $sResultCommande = exec('"' . $this->aProperties["fme_path"] . '" APPLY_SETTINGS "Python/Use Custom Python" false', $aResult, $iResult);
             //writeToLog(INFO_INFORM.$sExeName."| ".'"'.$this->aProperties["fme_path"].'" APPLY_SETTINGS "Python/Python Interpreter"', $this->sRobotLogFile);
@@ -168,7 +195,7 @@ class Traitement {
                 $aResultCommande = explode("|", $sResultCommande);
             }
             //Récupération d'une erreur.
-			if ($iResult !=0){
+            if ($iResult !=0){
             //if ($iResult || ($aResultCommande[0] != 0)) {
                 $this->bErreur = true;
                 if (sizeOf($aResultCommande) == 1)
@@ -184,17 +211,17 @@ class Traitement {
                 } else {
                     $this->sMessageErreur = "Erreur lors de l exécution de la commande. Consultez le log du robot.";
                 }
-				$bExistFMELogFile = true;
-				 if (file_exists($sFMELogFile) === false) {
-					$bExistFMELogFile = false;
-				}
+                $bExistFMELogFile = true;
+                 if (file_exists($sFMELogFile) === false) {
+                    $bExistFMELogFile = false;
+                }
                 foreach ($aResult as $sValeur) {
                     writeToLog(INFO_ERROR . "   " . "| " . $sValeur, $this->sRobotLogFile);
-					if ($bExistFMELogFile === false){
-						$monfichier = fopen($sFMELogFile, 'a');
-						fputs($monfichier, $sValeur. "\n");
-						fclose($monfichier);
-					}
+                    if ($bExistFMELogFile === false){
+                        $monfichier = fopen($sFMELogFile, 'a');
+                        fputs($monfichier, $sValeur. "\n");
+                        fclose($monfichier);
+                    }
                 }
                 writeToLog(INFO_COMMAND_ERROR . $sCommand . ".", $this->sRobotLogFile);
             } else {
@@ -218,7 +245,7 @@ class Traitement {
      */
     function zipFile($sZipDir, $sZipFileDir, $sZipUrl, $sZipFileName) {
         writeToLog(str_replace('[sZipDir]', $sZipDir, INFO_FILE_COMPRESSION), $this->sRobotLogFile);
-        if (createZip($sZipDir, $sZipFileDir . '/' . $sZipFileName . '.zip', 'log')) {
+        if (createZip($sZipDir, $sZipFileDir . '/' . $sZipFileName . '.zip', 'log', $this->sSecretKey, true)) {
             $sZipFile = $sZipUrl . "/" . $sZipFileName . ".zip";
             writeToLog(INFO_COMPRESSED_FILES . $sZipFile . ".", $this->sRobotLogFile);
         } else {
@@ -234,8 +261,11 @@ class Traitement {
     function unZipSource($sParam) {
         $this->sSource = $sParam;
         // Si la chaine contient un accent, la chaine sera en UTF-8, la fonction file_exists et la fonction de dézippage ne gèrent pas utf-8, il faut donc convertir la chaine en ISO-8859-1
-        if (mb_check_encoding($sParam, 'UTF-8'))
+        $bUtf8Param = false;
+        if (mb_check_encoding($sParam, 'UTF-8')) {
             $sParam = utf8_decode($sParam);
+            $bUtf8Param = true;
+        }
         // Si le fichier n'est pas trouvé alors il se trouve dans le répertoire upload
         if (!file_exists($sParam))
             $sParam = $this->aProperties["upload_dir"] . "/" . $sParam;
@@ -248,6 +278,9 @@ class Traitement {
             $sDir = $sParam;
             $this->sSourceTemp = "";
         }
+        // Si le paramètre passé était encodé en UTF-8 il faut le réencoder sinon problème avec les accents.
+        if ($bUtf8Param)
+            $sDir = utf8_encode($sDir);
         return $sDir;
     }
 
@@ -261,7 +294,9 @@ class Traitement {
             writeToLog(INFO_DECOMPRESSING_FILE . $sZipFile . ".", $this->sRobotLogFile);
             // Les backslashes du chemin de la variable d'environnement TEMP sont remplacés par des slashes
             $this->aProperties["extract_dir"] = str_replace("\\", "/", $this->aProperties["extract_dir"]);
-            $sExtractDir = $this->aProperties["extract_dir"] . "/" . $this->UniqFileName() . "/";
+            do {
+                $sExtractDir = $this->aProperties["extract_dir"] . "/" . getUniqRandomId() . "/";
+            }while(file_exists($sExtractDir));
             $this->sSourceTemp = $sExtractDir;
             if (unZip($sZipFile, $sExtractDir)) {
                 writeToLog(INFO_FILE_COMPRESSION_DIRECTORY . $sExtractDir . ".", $this->sRobotLogFile);
@@ -281,40 +316,51 @@ class Traitement {
      * $oGtfFmwParser : Objet GtfFmwParser contenant les GUI
      * $oGui : Objet GUI de la source
      * $sDirSource : Chaine de caractère contenant le chemin d'accés à la source de données
+     * \return Tableau des fichiers pour le paramètre "source".
      */
 
-    function updateSourceParam($oGui, $oGtfFmwParser, $sDirSource) {
-        $sdelimiterFichier = '""';
-        $sdelimiterParam = '""';
-        $sSourceMacro = $sdelimiterFichier;
+    function getSourceParam($oGui, $oGtfFmwParser, $sDirSource, $bUsePattern) {
+        $aSourceMacro = array();
         $i = 0;
-
+        $aSourceFiles = array();
         if (is_dir($sDirSource)) {
             $this->aExtension = $oGui->getExtensionArray($oGui->sFiltreSource);
             $iExtension = count($this->aExtension);
             if (($this->aExtension[0] == "*.*" and $oGui->sType == "FILE_OR_URL") or $oGui->sType == "DIRNAME_SRC" or $oGui->sType == "SOURCE_GEODATABASE") {
                 writeToLog(INFO_VALID_DATA_SOURCE_FILE_EXTENSION . $this->aExtension[0], $this->sRobotLogFile);
-                $sSourceMacro.= $sdelimiterParam . $sDirSource . '/**/' . $sdelimiterParam;
+                $aSourceFiles[] = $sDirSource . '/**/';
             } else {
-                foreach ($this->aExtension as $sExtension) {
-                    if ($sExtension != "*.*" or ( $sExtension == "*.*" and $iExtension == 1)) { // Si le filtre est différent de *.* (ex : *.mdb) ou si le filtre est seulement *.*. Si le filtre est multiple et que l'un d'eux est *.* (ex : *.*, *.mdb...), il ne sera pas pris en compte
-                        $aExtension = explode(".", $sExtension);
-                        if ($this->countFilesExtension($sDirSource, $aExtension[1]) > 0) {
-                            if ($i != 0)
-                                $sSourceMacro.= "<space>";
-                            writeToLog(INFO_VALID_DATA_SOURCE_FILE_EXTENSION . $sExtension, $this->sRobotLogFile);
-                            $sSourceMacro.= $sdelimiterParam . $sDirSource . '/**/' . $sExtension . $sdelimiterParam;
-                            $i++;
+                if ($bUsePattern){
+                        writeToLog(INFO_USE_PATTERN, $this->sRobotLogFile);
+                        foreach ($this->aExtension as $sExtension) {
+                                if ($sExtension != "*.*" or ( $sExtension == "*.*" and $iExtension == 1)) { // Si le filtre est différent de *.* (ex : *.mdb) ou si le filtre est seulement *.*. Si le filtre est multiple et que l'un d'eux est *.* (ex : *.*, *.mdb...), il ne sera pas pris en compte
+                                        $aExtension = explode(".", $sExtension);
+                                        if ($this->countFilesExtension($sDirSource, $aExtension[1]) > 0) {
+                                                writeToLog(INFO_VALID_DATA_SOURCE_FILE_EXTENSION . $sExtension, $this->sRobotLogFile);
+                                                $aSourceFiles[] = $sDirSource . '/**/' . $sExtension;
+                                                $i++;
+                                        }
+                                }
+                        }
+                }else{
+                        writeToLog(INFO_NO_USE_PATTERN, $this->sRobotLogFile);
+                        foreach ($this->aExtension as $sExtension) {
+                                if ($sExtension != "*.*" or ( $sExtension == "*.*" and $iExtension == 1)) { // Si le filtre est différent de *.* (ex : *.mdb) ou si le filtre est seulement *.*. Si le 
+                                        $aExtension = explode(".", $sExtension);
+                                        $aSourceMacroTmp = array_merge($aSourceMacro, $this->returnFileListToString($sDirSource, $aExtension[1]));
+                                        $aSourceMacro = array_unique($aSourceMacroTmp);
+                                        $i++;
+                                }
+                        }
+                        foreach ($aSourceMacro as $source) {
+                                $aSourceFiles[] = $source;
                         }
-                    }
                 }
             }
-        }else {
-            $sSourceMacro.= $sdelimiterParam . $sDirSource . $sdelimiterParam;
-        }
-        $sSourceMacro .= $sdelimiterFichier;
-        $this->aParametre[$oGui->sDefault_Macro] = $sSourceMacro;
-        return $sSourceMacro;
+        }else
+            $aSourceFiles[] = $sDirSource;
+        
+        return $aSourceFiles;
     }
 
     // Compte le nombre de fichier
@@ -324,7 +370,7 @@ class Traitement {
         $num = 0;
         if (!is_dir($sDirSource)) {
             $path_parts = pathinfo($sDirSource);
-            if (is_file($sDirSource) && strtoupper($path_parts['extension']) == strtoupper($sExtension))
+            if (is_file($sDirSource) && $path_parts['extension'] == $sExtension)
                 return 1;
             else
                 return false;
@@ -336,6 +382,26 @@ class Traitement {
         return $num;
     }
 
+    function returnFileListToString($sDirSource, $sExtension) {
+    $aFileList = array();
+    if (!is_dir($sDirSource)) {
+        $path_parts = pathinfo($sDirSource);
+        if (is_file($sDirSource) && strtolower($path_parts['extension']) == strtolower($sExtension)){
+            array_push($aFileList,$sDirSource);
+        }
+
+    }else{
+            foreach (scandir($sDirSource) AS $entry) {
+                    if (!in_array($entry, array('..', '.'))){
+                            $aFileListTmp = $aFileList;
+                            $aFileList = array_merge($aFileListTmp,$this->returnFileListToString($sDirSource . "/" . $entry, $sExtension));
+                    }
+
+            }
+        }
+        return $aFileList;
+    }
+
     /*
      * Fonction qui se charge de la mise à jour du paramètre "source" s'il existe
      * $oGtfFmwParser : Objet GtfFmwParser contenant les GUI
@@ -343,16 +409,15 @@ class Traitement {
      * $sDirSource : Chaine de caractère contenant le chemin d'accés à la source de données
      */
 
-    function updateDestParam($oGui, $oGtfFmwParser, $sNewDir, $sDest) {
+    function updateDestParam($oGui, $oGtfFmwParser, $sDest) {
         $this->aExtension = $oGui->getExtensionArray($oGui->sFiltreDest);
-        if ($sDest == "" && $oGui->sType != "DIRNAME") {
-            $sDest = $sNewDir;
-        }
+        if ($sDest == "" && $oGui->sType != "DIRNAME")
+            $sDest = $this->sResultDirectoryName;
         $this->aParametre[$oGui->sDefault_Macro] = "";
         $sDest = normalizeString($sDest);
         $aDest = explode(".", $sDest);
         if ($oGui->sType == "DIRNAME" or $oGui->sType == "DEST_GEODATABASE") {
-            $this->aParametre[$oGui->sDefault_Macro] = $this->aProperties["dir_export"] . "/gtf/" . $sNewDir . "/" . $sDest;
+            $this->aParametre[$oGui->sDefault_Macro] = $this->aProperties["dir_export"] . "/gtf/" . $this->sResultDirectoryName . "/" . $sDest;
             writeToLog(INFO_OUTPUT_DATA_DIRECTORY . $this->aParametre[$oGui->sDefault_Macro], $this->sRobotLogFile);
         }
         if ($oGui->sType == "FILENAME") {
@@ -361,7 +426,7 @@ class Traitement {
             } else {
                 $sResult = str_replace("*", $sDest, $this->aExtension[0]);
             }
-            $this->aParametre[$oGui->sDefault_Macro].= $this->aProperties["dir_export"] . "/gtf/" . $sNewDir . '/' . $sResult;
+            $this->aParametre[$oGui->sDefault_Macro].= $this->aProperties["dir_export"] . "/gtf/" . $this->sResultDirectoryName . '/' . $sResult;
             $this->sDestination = $sResult;
 
             writeToLog(INFO_OUTPUT_DATA_FILE . $this->aParametre[$oGui->sDefault_Macro], $this->sRobotLogFile);
@@ -419,7 +484,7 @@ class Traitement {
             }
         }
 
-        // on encode les balises UTF-8 		
+        // on encode les balises UTF-8      
 
         $offset = 0;
         $iPos = 0;
@@ -456,7 +521,7 @@ class Traitement {
             }
         }
 
-        // on decode les balises UTF-8 		
+        // on decode les balises UTF-8      
         $matches = array();
 
         preg_match_all("/<u[0-9a-fA-F]{4}>/", $sStr, $matches);
@@ -466,9 +531,6 @@ class Traitement {
             $cChr = $this->unichr($iCode);
             $sReplaced = str_replace($matches[0][$i], $cChr, $sReplaced);
         }
-		if (mb_detect_encoding($sReplaced, "UTF-8, ISO-8859-1") != "ISO-8859-1") {
-			$sReplaced = iconv("UTF-8", "ISO-8859-1", $sReplaced);
-		}
         return $sReplaced;
     }
 
@@ -484,7 +546,6 @@ class Traitement {
     function isEncode($sStr) {
         for ($i = 0; $i < count($this->aReplaceFME); $i++) {
             if (strpos($sStr, $this->aReplaceFME[$i]) === false && strpos($sStr, $this->aReplaceGTF[$i]) !== false) {
-                error_log($this->aReplaceFME[$i]);
                 return false;
             }
         }
@@ -499,89 +560,32 @@ class Traitement {
      *  $oGtfFmwParser : Objet GtfFmwParser contenant les GUI
      */
 
-    function getTclParams($oGtfFmwParser, $sNewDir) {
-        $aTGui = array();
+    function getTclParams($oGtfFmwParser) {
         $sChaine = "";
-        foreach ($oGtfFmwParser->aGuiObject as $aGui) {
-            if ($aGui->sDefault_Macro != "") {
-                array_push($aTGui, $aGui);
-            }
-        }
-        foreach ($aTGui as $oGui) {
-            //Teste si le paramètre est une source
-            if ($oGui->bIsSource) {
-                if ($this->aParametre[$oGui->sDefault_Macro] != "" && substr($this->aParametre[$oGui->sDefault_Macro], 0, 7) != "<quote>") {
-                    $sDirSource = $this->unZipSource($this->aParametre[$oGui->sDefault_Macro]);
-                    $this->updateSourceParam($oGui, $oGtfFmwParser, $sDirSource);
-                }
-            }
-            if ($oGui->bIsDest) {
-                $sDest = $this->aParametre[$oGui->sDefault_Macro];
-                $this->updateDestParam($oGui, $oGtfFmwParser, $sNewDir, $sDest);
-            }
-
-            if ($this->aParametre[$oGui->sDefault_Macro] != "") {
-
-                if (!$oGui->bIsSource) {
-                    // Protection des guillemets de chaque valeur pour qu'ils soient correctement envoyé à traitement.tcl
-                    // Cette protection s'effectue uniquement pour les paramètre qui ne sont pas sources (un paramètre source est de ce type : """"param1"" ""param2"" ""param3"""" : les guillemets seraient donc protégé et cela fait planter l'exécution)
-                    //$this->aParametre[$oGui->sDefault_Macro] = str_replace('"', '""', $this->aParametre[$oGui->sDefault_Macro]);
-                }
-                $aBaliseToReplace = array('<GTF_EQUAL>', '<GTF_PIPE>');
-                $aReplacedBalise = array('=', '|');
-                $sGTFOutput = str_replace($aBaliseToReplace, $aReplacedBalise, $this->aParametre[$oGui->sDefault_Macro]);
-                switch ($oGui->sType) {
-                    case "FLOAT":
-                        $sGTFOutput = str_replace(",", ".", $sGTFOutput);
-                        if (!$this->isDecode($sGTFOutput))
-                            $sGTFOutput = $this->decoderFME($sGTFOutput);
-                        break;
-                    case "LOOKUP_CHOICE":
-                        if (!$this->isEncode($sGTFOutput))
-                            $sGTFOutput = $this->encoderFME($sGTFOutput);
-                        break;
-                    case "TEXT_EDIT" :
-                    case "TEXT_EDIT_OR_NUM" :
-                        if (!$this->isEncode($sGTFOutput)) {
-                            //$sGTFOutput = $this->decoderFME($sGTFOutput);
-                            $sGTFOutput = $this->encoderFME($sGTFOutput);
-                        }
-                        break;
-                    case "CHOICE":
-                    case "LOOKUP_LISTBOX":
-                        $sGTFOutput = str_replace('"', '""', $sGTFOutput);
-                        if (!$this->isDecode($sGTFOutput))
-                            $sGTFOutput = $this->decoderFME($sGTFOutput);
-                        break;
-                    default :
-                        $sGTFOutput = str_replace('"', '""', $sGTFOutput);
-                        if (!$this->isDecode($sGTFOutput))
-                            $sGTFOutput = $this->decoderFME($sGTFOutput);
-                        break;
-                }
-
-                $sChaine .= " --" . $oGui->sDefault_Macro . " \"" . $sGTFOutput . "\"";
-            }
+        $aFmeParameters = $this->getFmeParameters($oGtfFmwParser);
+        foreach ($aFmeParameters as $sFmeParamKey => $sFmeParamValue) {
+            // Echappement des doubles quotes pour FME.
+            $sFmeParamValue = str_replace('"', '\"', $sFmeParamValue);
+            // Ajout du paramètre en ligne de commande.
+            $sChaine .= " --" . $sFmeParamKey . " \"" . $sFmeParamValue . "\"";
         }
-
         // $sChaine = substr($sChaine, 0, -1)."\"";
         //$sChaine = substr($sChaine, 0, -1);
-
         return $sChaine;
     }
 
-    function listDir($sDossier, $iDemandeId) {
-        $ouverture = @opendir($sDossier);
+    function listDir($iDemandeId) {
+        $ouverture = @opendir($this->sResultDirectoryPath);
         if (!$ouverture)
             return false;
         while ($sFichier = readdir($ouverture)) {
             if ($sFichier == '.' || $sFichier == '..')
                 continue;
-            if (is_dir($sDossier . $sFichier)) {
+            if (is_dir($this->sResultDirectoryPath . $sFichier)) {
                 closedir($ouverture);
                 return true;
             } else {
-                $path_parts = pathinfo($sDossier . $sFichier);
+                $path_parts = pathinfo($this->sResultDirectoryPath . $sFichier);
                 if ($sFichier != "fme_" . $iDemandeId . ".log") {
                     closedir($ouverture);
                     return true;
@@ -594,29 +598,27 @@ class Traitement {
 
     /*
      * Fonction qui retourne le nom du fichier résultat qui sera zippé.
-     *  $sDossier correspond au chemin complet dans lequel les fichiers/dossiers résultats seront générés
-     *  $sNewDir correspond au numéro unique du dossier dans lequel les fichiers/dossiers résultats seront générés
      *  $iDemandeId correspond au numéro de la demande
      * \return Retourne NULL (s'il y a plusieurs fichiers résultat à zipper) ou le fichier résultat qui sera zippé sous la forme 20140324141501876/ventes.xlsx
      */
 
-    function CheckResult($sDossier, $sNewDir, $iDemandeId) {
-        $ouverture = @opendir($sDossier);
+    function CheckResult($iDemandeId) {
+        $ouverture = @opendir($this->sResultDirectoryPath);
         $NbFile = 0;
         while ($sFichier = readdir($ouverture)) {
             if ($sFichier == '.' || $sFichier == '..')
                 continue;
-            if (is_dir($sDossier . $sFichier)) {
+            if (is_dir($this->sResultDirectoryPath . $sFichier)) {
                 $NbFile = $NbFile + 2;
             } else {
-                $path_parts = pathinfo($sDossier . $sFichier);
+                $path_parts = pathinfo($this->sResultDirectoryPath . $sFichier);
                 if ($sFichier != "fme_" . $iDemandeId . ".log") {
                     $NbFile = $NbFile + 1;
                 }
             }
         }
         closedir($ouverture);
-        $ouverture = @opendir($sDossier);
+        $ouverture = @opendir($this->sResultDirectoryPath);
         if ($NbFile != 1) {
             return "";
         } else {
@@ -625,8 +627,8 @@ class Traitement {
                 if ($sFichier == '.' || $sFichier == '..')
                     continue;
                 if ($sFichier != "fme_" . $iDemandeId . ".log") {
-                    if (preg_match($pattern, $sFichier)) {
-                        return $sNewDir . "/" . $sFichier;
+                    if (preg_match($pattern, $sFichier) && !$this->bDataEncrypt) {
+                        return $this->sResultDirectoryName . "/" . $sFichier;
                     } else {
                         return "";
                     }
@@ -643,131 +645,142 @@ class Traitement {
 
     function Process() {
         $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName);
-        // Création du répertoire de sortie des données
-        $sNewDir = $this->UniqFileName();
-		 if (!file_exists($this->aProperties["dir_export"] . "/gtf/")){
-			mkdir($this->aProperties["dir_export"] . "/gtf/");
-		}
-        $sDestDir = $this->aProperties["dir_export"] . "/gtf/" . $sNewDir;
-        mkdir($sDestDir);
-        // Création de l'URL de téléchargement des données
-        $sDestUrl = $this->aProperties["url_export"] . "/gtf/" . $sNewDir;
+        // Création du répertoire de résultat.
+        $this->sResultDirectoryName = $this->createResultDirectory();
 
         //1 Initialisation & calcul du chemin d'accés du fichier TCL
         $sCommandLine = '"' . $this->aProperties["fme_path"] . '" "' . getenv("GTF_HOME") . "/" . utf8_decode($this->sFmwFileName) . '"';
 
         //3 Ajout des paramètres propres au traitement
-        $sTclParams = $this->getTclParams($oGtfFmwParser, $sNewDir);
+        $sTclParams = $this->getTclParams($oGtfFmwParser);
         if ($sTclParams != "")
             $sCommandLine .= $sTclParams;
-        // Ajout de trois paramètres GTF_ORDER_ID, GTF_SHARED_DIR et GTF_CONNECTION_STRING qui seront passés à chaque demande de traitement
-        $sCommandLine .= " --GTF_ORDER_ID \"" . $this->iDemandeId . "\" --GTF_SHARED_DIR \"" . $this->aProperties["shared_dir"] . "\" --GTF_CONNECTION_STRING \"" . $this->aProperties["server"] . "," . $this->aProperties["port"] . "," . $this->aProperties["database"] . "," . $this->aProperties["login"] . "\" --GTF_REST_URL \"" . $this->aProperties["web_server_name"] . "/" . $this->aProperties["services_alias"] . "/\"" ;
+        $aTGui = array();
+        $sChaine = "";
+        
+        // Ajout des paramètres GTF_ s'ils sont associés à un paramètre publié du traitement
+        $aGtfParameters = $this->getGtfParameters($oGtfFmwParser);
+        foreach ($aGtfParameters as $sGtfParamKey => $sGtfParamValue) {
+            $sCommandLine .= ' --' . $sGtfParamKey . ' "' . $sGtfParamValue . '"';
+        }
         /*
          * 2 Passage des paramètres généraux
          * - FMWFILENAME : fichier Fmw
          * - LOG_ROBOT : fichier log du robot
          * - LOG_FILENAME : fichier log pour FME
          */
-        $sCommandLine.= " -LOG_FILENAME \"" . $sDestDir . "/fme_" . $this->iDemandeId . ".log\" 2>&1";
+        $sCommandLine.= " -LOG_FILENAME \"" . $this->getFmeLogFilePath($this->sResultDirectoryPath) . "\" 2>&1";
         writeToLog(INFO_GTF_HOME . getenv("GTF_HOME"), $this->sRobotLogFile);
         writeToLog(INFO_FME_PATH . getenv("FME_PATH"), $this->sRobotLogFile);
         writeToLog(INFO_TREATMENT_COMMAND_LINE . $sCommandLine, $this->sRobotLogFile);
 
         //4 Lancement de la ligne de commande
-        $this->sLogFme = $sNewDir . "/fme_" . $this->iDemandeId . ".log";
+        $this->sLogFme = $this->getFmeLogFilePath($this->sResultDirectoryName);
         $sSql = "UPDATE " . $this->aProperties['schema_gtf'] . ".order SET log_url='" . $this->sLogFme . "' WHERE order_id=" . $this->iDemandeId;
         $this->oBd->execute($sSql);
-        $this->execute($sCommandLine, $sDestDir . "/fme_" . $this->iDemandeId . ".log");
+        $this->execute($sCommandLine, $this->getFmeLogFilePath($this->sResultDirectoryPath));
         writeToLog(INFO_TREATMENT_COMMAND_LINE . $sCommandLine, $this->sRobotLogFile);
-        if (file_exists($sDestDir . "/fme_" . $this->iDemandeId . ".log") == false) {
+        if (file_exists($this->getFmeLogFilePath($this->sResultDirectoryPath)) == false) {
             $this->sLogFme = "";
         }
-        $bHasFile = $this->listDir($sDestDir, $this->iDemandeId);
-        if ($this->sSourceTemp != "" && $this->aProperties["debug_mode"] == false) {
-            clearDir($this->sSourceTemp);
-        }
-        if ($bHasFile) {
-            $sIsToZip = $this->CheckResult($sDestDir, $sNewDir, $this->iDemandeId);
-
-            if ($sIsToZip == "") {
-                //Compression en zip des fichiers résultant. Le parametres Array() permet de filtrer les extensions à compresser. Exemples : Array("shp","shx","dbf") ; Array("*")		
-                $sZipFile = $this->zipFile($sDestDir, $sDestDir, $sDestUrl, $this->iDemandeId);
-                $sZipFile = str_replace($sDestUrl, $sNewDir, $sZipFile);
-            } else {
-                $sZipFile = str_replace($sDestUrl, $sNewDir, $sIsToZip);
-            }
-        } else {
-            $sZipFile = "";
-        }
+        // Tous les fichiers de résultat dans une archive .zip.
+        $sZipFile = $this->zipResultFiles();
         return $sZipFile;
     }
     
     /**
-     * Get the log file of a job.
+     * Submit a job on Fme Server.
      * @param {object} $oFmeServer FmeServer class object.
      * @param {array} $aOrder Order parameters.
      * @param {array} $aWorkspace Workpace parameters.
      * @param {array} $aUser User infos.
+     * @param {object} $oAmazonS3 AmazonS3 class object.
+     * @param {boolean} $bAsync Asynchronous job.
+     * @return string
      */
-    function processFmeServerOrder($oFmeServer, $aOrder, $aWorkspace, $aUser, $oAmazonS3 = null) {
-        $sNewDir = $this->UniqFileName();
-        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName);
+    function submitFmeServerJob($oFmeServer, $aOrder, $aWorkspace, $aUser, $oAmazonS3 = null, $bAsync = false) {
+        $this->oFmeServer = $oFmeServer;
+        $this->oAmazonS3 = $oAmazonS3;
+        // Création du répertoire de résultat.
+        $this->sResultDirectoryName = $this->createResultDirectory();
         // Fichiers sources en entrée et sortie.
+        $oGtfFmwParser = new GtfFmwParser($this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName);
+        $aTGui = array();
         $aSourceFiles = array();
-        $aDestinationFiles = '';
+        $aDestinationFiles = array();
         foreach ($oGtfFmwParser->aGuiObject as $oGui) {
             if ($oGui->sDefault_Macro != "") {
+                array_push($aTGui, $oGui);
                 //Teste si le paramètre est une source
                 if ($oGui->bIsSource)
-                    $aSourceFiles[] = $oGui->sDefault_Macro;
+                    $aSourceFiles[$oGui->sDefault_Macro] = $this->aParametre[$oGui->sDefault_Macro];
                 else if ($oGui->bIsDest)
-                    $aDestinationFiles = $oGui->sDefault_Macro;
+                    $aDestinationFiles[] = $oGui->sDefault_Macro;
             }
         }
+        // Sauve la liste des fichiers de destination.
+        $this->aDestinationFiles = $aDestinationFiles;
         // Liste des paramètres publiés.
-        $aWkParams = explode('|', $aOrder['wk_params']);
-        $aPublishedParams = array();
-        foreach($aWkParams as $sWkParam) {
-            $aWkParam = explode('=', $sWkParam);
-            $aPublishedParams[$aWkParam[0]] = $aWkParam[1];
-        }
-        // Création d'un dépot pour l'utilisateur si inexistant.
-        $sRepository = $aUser["login"];
-        $oFmeServer->createRepository($sRepository, $aUser["name"]);
+        $aFmeParameters = $this->getFmeParameters($oGtfFmwParser);
+        // Ajout des paramètres GTF_ s'ils sont associés à un paramètre publié du traitement.
+        $aFmeParameters = array_merge($aFmeParameters, $this->getGtfParameters($oGtfFmwParser));
+        // Création d'un identifiant pour l'instance de GTF (si inexistant).
+        if (empty($this->aProperties["gtf_instance_id"]))
+            $this->aProperties["gtf_instance_id"] = generateGtfInstanceId();
+        // Création d'un dépot pour l'instance de GTF si inexistant.
+        $sRepository = $this->aProperties["gtf_instance_id"];
+        if ($oFmeServer->createRepository($sRepository, '') === false)
+            return false;
         // Création d'un répertoire dans les ressources si inexistant.
         $sResource = 'FME_SHAREDRESOURCE_TEMP';
-        $sPath = 'gtf';
-        $oFmeServer->createResourceConnectionDirectory($sResource, $sPath, $sNewDir);
-        $sPath .= '/' . $sNewDir;
-        // Upload des fichiers sources.
-        foreach($aSourceFiles as $sParamName) {
-            // Si un objet de la classe AmazonS3 est passé, les ressources seront envoyées sur S3 puis téléchargéss dans FME Server.
-            if (empty($oAmazonS3))
-                $oFmeServer->uploadResourceFile($this->aProperties['upload_dir'] . '/' . $aPublishedParams[$sParamName], $sResource, $sPath, true, true);
-            else {
-                // Upload d'un fichier source vers S3.
-                $sBucket = 'dev-gtf-fmecloud';
-                $sKey = $sPath . '/' . $aPublishedParams[$sParamName];
-                $oAmazonS3->uploadFile($sBucket, $sKey, $this->aProperties['upload_dir'] . '/' . $aPublishedParams[$sParamName]);
-                // Upload du fichier S3Downloader.fmw (si inexistant).
-                $oFmeServer->uploadWorkspaceFile('E:\_Docs\GTF moteur serveur\S3Downloader.fmw', $sRepository);
-                // Téléchargement depuis FME Server du fichier envoyé sur S3.
-                $aS3Params = array(
-                    'access_key_id' => $oAmazonS3->sAwsAccessKeyId,
-                    'secret_access_key' => $oAmazonS3->sAwsSecretAccessKey,
-                    'bucket_name' => $sBucket,
-                    'object_key' => $sKey
-                );
-                $oJobResult = $oFmeServer->uploadResourceFileFromS3($aS3Params, $sRepository, $sResource, $sPath);
+        $sPath = $this->aProperties["gtf_instance_id"];
+        if ($oFmeServer->createResourceConnectionDirectory($sResource, $sPath, $this->sResultDirectoryName) === false)
+            return false;
+        $sPath .= '/' . $this->sResultDirectoryName;
+        // Copie locale du fichier .fmw avec la version.
+        $sFmwFilePath = $this->aProperties["workspace_dir"] . "/" . $this->sFmwFileName;
+        $sRepositoryFmwFileName = pathinfo($this->sFmwFileName, PATHINFO_FILENAME) . '_v' . $aWorkspace['version'] . '.' . pathinfo($this->sFmwFileName, PATHINFO_EXTENSION);
+        $sRepositoryFmwFilePath = $this->aProperties["workspace_dir"] . "/" . pathinfo($this->sFmwFileName, PATHINFO_DIRNAME) . "/" . $sRepositoryFmwFileName;
+        if (!file_exists($sRepositoryFmwFilePath)) {
+            copy($sFmwFilePath, $sRepositoryFmwFilePath);
+            // Supprime le fichier de l'ancienne version du projet (GTF + Fme Server).
+            if ($aWorkspace['version'] > 0) {
+                $sRepositoryOldFmwFileName = pathinfo($this->sFmwFileName, PATHINFO_FILENAME) . '_v' . --$aWorkspace['version'] . '.' . pathinfo($this->sFmwFileName, PATHINFO_EXTENSION);
+                unlink($this->aProperties["workspace_dir"] . "/" . pathinfo($this->sFmwFileName, PATHINFO_DIRNAME) . "/" . $sRepositoryOldFmwFileName);
+                //$oFmeServer->serviceRequest('repositories/' . $sRepository . '/items/' . $sRepositoryOldFmwFileName, 'delete');
             }
         }
         // Upload du fichier .fmw.
-        $sFmwFileName = $this->aProperties["workspace_dir"] . "/" .$this->sFmwFileName;
-        $oFmeServer->uploadWorkspaceFile($sFmwFileName, $sRepository, true);
+        if ($oFmeServer->uploadWorkspaceFile($sFmwFilePath, $sRepository, false, $sRepositoryFmwFileName) === false)
+            return false;
+        // Upload des fichiers sources.
+        foreach($aSourceFiles as $sParamName => $sParamValue) {
+            if ($this->uploadFileToResourceConnection($this->aProperties["upload_dir"] . "/" . $sParamValue, $sRepository, $sResource, $sPath) === false)
+                return false;
+            /*
+            // Upload de plusieurs fichiers sources (ex: contenu d'une archive .zip).
+            $aFiles = explode('|', $aFmeParameters[$sParamName]);
+            foreach ($aFiles as $sFilePath) {
+                if ($this->uploadFileToResourceConnection($sFilePath, $sRepository, $sResource, $sPath) === false)
+                    return false;
+            }
+            */
+        }
+        // Upload des ressources complémentaires du projet.
+        $sResourcesDirectory = $this->aProperties["workspace_dir"] . '/' . pathinfo($this->sFmwFileName, PATHINFO_DIRNAME);
+        if (is_dir($sResourcesDirectory)) {
+            foreach (scandir($sResourcesDirectory) as $sFileName) {
+                if (is_file($sResourcesDirectory . '/' . $sFileName) && array_search(pathinfo($sFileName, PATHINFO_EXTENSION), array('fmw', 'bak')) === false) {
+                    if ($oFmeServer->uploadWorkspaceResourceFile($sResourcesDirectory . '/' . $sFileName, $sRepository, $sRepositoryFmwFileName, false) === false)
+                        return false;
+                }
+            }
+        }
         // Paramètres publiés dans les données de la requête.
-        $aJobParams = array(
-            'publishedParameters' => array(),
-            'NMDirectives' => array(
+        $aJobParams = array('publishedParameters' => array());
+        // Traitement asynchrone.
+        if ($bAsync) {
+            $aJobParams['NMDirectives'] = array(
                 'successTopics' => array(
                     'TEST_TOPIC_FRED'
                 ),
@@ -778,38 +791,438 @@ class Traitement {
                     array('name' => 'order_id', 'value' => $this->iDemandeId)
                 )
                 //'subsection' => 'REST_SERVICE'
-            )
-        );
-        foreach ($aPublishedParams as $sParamName => $sParamValue) {
-            if (in_array($sParamName, $aSourceFiles))
-                $aJobParams['publishedParameters'][] = array("name" => $sParamName, "value" => array('$(' . $sResource . ')/' . $sPath . '/' . pathinfo($sParamValue, PATHINFO_BASENAME)));
+            );
+        }
+        // Chemins pour les paramètres publiés qui sont des fichiers.
+        foreach ($aFmeParameters as $sParamName => $sParamValue) {
+            if (array_key_exists($sParamName, $aSourceFiles)) {
+                $aFiles = explode('|', $sParamValue);
+                $aPublishedParametersFiles = array();
+                foreach ($aFiles as $sFilePath)
+                    $aPublishedParametersFiles[] = '$(' . $sResource . ')/' . $sPath . '/' . $sFilePath;
+                $aJobParams['publishedParameters'][] = array("name" => $sParamName, "value" => $aPublishedParametersFiles);
+            }
+            else if (in_array($sParamName, $aDestinationFiles))
+                $aJobParams['publishedParameters'][] = array("name" => $sParamName, "value" => '$(' . $sResource . ')/' . $sPath . '/' . $this->sResultDirectoryName . '.zip/' . pathinfo($sParamValue, PATHINFO_BASENAME));
             else
-                $aJobParams['publishedParameters'][] = array("name" => $sParamName, "value" => '$(' . $sResource . ')/' . $sPath . '/' . $sNewDir . '.zip/' . $sParamValue);
+                $aJobParams['publishedParameters'][] = array("name" => $sParamName, "value" => $sParamValue);
         }
         // Envoi d'une demande sur un traitement.
-        $this->oJobResult = $oFmeServer->submitJob($sRepository, $aWorkspace['fmw_file'], $aJobParams);
-        // Téléchargement du fichier de log du traitement.
+        $this->oJobResult = $oFmeServer->submitJob($sRepository, $sRepositoryFmwFileName, $aJobParams, $bAsync);
+        if ($this->oJobResult === false)
+            return false;
+        // Demande synchrone -> téléchargement des fichiers de log et de résultat du traitement.
+        if ($bAsync) {
+            $this->aJobDestinationFiles = $aDestinationFiles;
+            $this->sJobResource = $sResource;
+            $this->sJobPath = $sPath;
+        }
+        else {
+            $sZipFile = '';
+            if (!empty($this->oJobResult->id))
+                $sZipFile = $this->downloadFmeServerJobResult($this->oJobResult->id, $oFmeServer, $aDestinationFiles, $sResource, $sPath);
+            return $sZipFile;
+        }
+    }
+    
+    /**
+     * Init all the encryption parameters of the user.
+     */
+    function initUserEncryptionParameters() {
+        // Paramètres de cryptage de l'utilisateur.
+        $sSql = 'SELECT "order".user_id, workspace.workspace_id, "user".login, "user".dataencrypt AS user_dataencrypt, workspace.dataencrypt AS workspace_dataencrypt, "user".secretkey FROM [sSchemaGtf].order LEFT JOIN [sSchemaFramework].user ON "order".user_id = "user".user_id LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id = workspace.workspace_id WHERE order_id = [iDemandeId]';
+        $aParams = array();
+        $aParams['sSchemaFramework'] = array('value' => $this->aProperties["schema_framework"], 'type' => 'schema_name');
+        $aParams['sSchemaGtf'] = array('value' => $this->aProperties["schema_gtf"], 'type' => 'schema_name');
+        $aParams['iDemandeId'] = array('value' => $this->iDemandeId, 'type' => 'number');
+        $oPDOResult = $this->oBd->executeWithParams($sSql, $aParams);
+        if (!$this->oBd->enErreur()) {
+            $aUserEncryptParams = $this->oBd->ligneSuivante($oPDOResult);
+            if ($aUserEncryptParams['user_dataencrypt'] === true || $aUserEncryptParams['workspace_dataencrypt'] === true) {
+                // Le résultat de la demande sera crypté.
+                $this->bDataEncrypt = true;
+                // Clé secrète de l'utilisateur (sinon il faut la générer).
+                if ($aUserEncryptParams['user_dataencrypt'] === true && !empty($aUserEncryptParams['secretkey']))
+                    // Décryptage de la clé secrète (suppression des caractères "NULL").
+                    $this->sSecretKey = str_replace(chr(0), '', des($aUserEncryptParams['login'], hexToString($aUserEncryptParams['secretkey']), 0, 0));
+                else {
+                    // Génération de la clé secrète.
+                    $this->sSecretKey = getUniqRandomId();
+                    // Envoi du mail avec la clé secrète générée.
+                    $aObjects = array();
+                    $aObjects['oOrder'] = new OrderLib($this->oBd, $this->iDemandeId, $this->aProperties, "v_order");
+                    $aObjects['oOrder']->formatOrderEmail();
+                    $aObjects['oOrder']->sSecretKey = $this->sSecretKey;
+                    $oEmail = new Email($this->oBd, -1, $this->aProperties, $aObjects);
+                    if (!empty($oEmail->oEmailTemplate->name))
+                        $oEmail->send();
+                }
+            }
+        }
+        else
+            writeToLog(INFO_USER_ENCRYPT_PARAMETERS . "(SQL : $sSql)", $this->sRobotLogFile);
+    }
+    
+    /**
+     * Upload a file to a resource connection on Fme Server.
+     * @param {string} $sFilePath Path of the file to upload.
+     * @param {string} $sRepository Name of the repository.
+     * @param {string} $sResource Name of a resource connection.
+     * @param {string} $sPath Path, relative to the resource connection.
+     */
+    function uploadFileToResourceConnection($sFilePath, $sRepository, $sResource, $sPath) {
+        // Si un objet de la classe AmazonS3 existe, les ressources seront envoyées sur S3 puis téléchargéss dans FME Server.
+        if (empty($this->oAmazonS3)) {
+            if ($this->oFmeServer->uploadResourceFile($sFilePath, $sResource, $sPath, true, true) === false)
+                return false;
+        }
+        else {
+            // Upload d'un fichier source vers S3.
+            //$sS3Bucket = $this->aProperties['fme_cloud_s3_bucket'];
+            $sS3ObjectKey = $sPath . '/' . pathinfo($sFilePath, PATHINFO_BASENAME);
+            if ($this->oAmazonS3->uploadFile($this->sFmeServerS3Bucket, $sS3ObjectKey, $sFilePath) === false)
+                return false;
+            // Upload du fichier S3Downloader.fmw (si inexistant).
+            if ($this->oFmeServer->uploadWorkspaceFile($this->aProperties['workspace_dir'] . '/S3Downloader.fmw', $sRepository, false) === false)
+                return false;
+            // Téléchargement depuis FME Server du fichier envoyé sur S3.
+            $aS3Params = array(
+                'access_key_id' => $this->oAmazonS3->sAwsAccessKeyId,
+                'secret_access_key' => $this->oAmazonS3->sAwsSecretAccessKey,
+                'bucket_name' => $this->sFmeServerS3Bucket,
+                'object_key' => $sS3ObjectKey
+            );
+            $oJobResult = $this->oFmeServer->uploadResourceFileFromS3($aS3Params, $sRepository, $sResource, $sPath);
+            if ($oJobResult === false)
+                return false;
+        }
+    }
+
+    function setUseExternalDbConnection ($bValue){
+        if(is_bool($bValue)){
+            $this->bUseExternalDbConnection = $bValue;
+        }
+    }
+    
+    /**
+     * get GTF parameters.
+     * @param {object} $oGtfFmwParser All the GUI.
+     * @return array
+     */
+    function getGtfParameters($oGtfFmwParser) {
+        // Ajout des paramètres GTF_ s'ils sont associés à un paramètre publié du traitement.
+        $aGtfParams = array();
+        foreach ($oGtfFmwParser->aGuiObject as $aGui) {
+            switch($aGui->sDefault_Macro) {
+                 case 'GTF_ORDER_ID':
+                    $aGtfParams['GTF_ORDER_ID'] = $this->iDemandeId;
+                    break;
+                 case 'GTF_SHARED_DIR':
+                    $aGtfParams['GTF_SHARED_DIR'] = $this->aProperties["shared_dir"];
+                    break;
+                 case 'GTF_CONNECTION_STRING':
+                    if ($aGui->sType == "PASSWORD") {
+                        $sServer = $this->aProperties["server"];
+                        $iPort = $this->aProperties["port"];
+                        if ($this->bUseExternalDbConnection){
+                            $sServer = $this->aProperties["connectionStringExternalIp"];
+                            $iPort = $this->aProperties["connectionStringExternalPort"];
+                        }
+                        $aGtfParams['GTF_CONNECTION_STRING'] = $sServer . "," . $iPort . "," . $this->aProperties["database"] . "," . $this->aProperties["login_scheduler"] . "," . $this->aProperties["password_scheduler"];
+                    }
+                    else
+                        writeToLog(INFO_GTF_CONNECTION_STRING_TYPE_PASSWORD, $this->sRobotLogFile);
+                    break;
+                 case 'GTF_REST_URL':
+                    $aGtfParams['GTF_REST_URL'] = $this->aProperties["web_server_name"] . "/" . $this->aProperties["services_alias"] . '/';
+                    break;
+                 case 'GTF_USER_RESTRICTION':
+                    // Restriction de l'utilisateur.
+                    $sSql = 'SELECT "user".restriction FROM [sSchemaGtf].order LEFT JOIN [sSchemaFramework].user ON "order".user_id = "user".user_id WHERE order_id = [iDemandeId]';
+                    $aParams = array();
+                    $aParams['sSchemaFramework'] = array('value' => $this->aProperties["schema_framework"], 'type' => 'schema_name');
+                    $aParams['sSchemaGtf'] = array('value' => $this->aProperties["schema_gtf"], 'type' => 'schema_name');
+                    $aParams['iDemandeId'] = array('value' => $this->iDemandeId, 'type' => 'number');
+                    $oPDOResult = $this->oBd->executeWithParams($sSql, $aParams);
+                    if (!$this->oBd->enErreur()) {
+                        $aUserRestriction = $this->oBd->ligneSuivante($oPDOResult);
+                        $aGtfParams['GTF_USER_RESTRICTION'] = $aUserRestriction['restriction'];
+                    }
+                    else
+                        writeToLog(INFO_USER_RESTRICTION . "(SQL : $sSql)", $this->sRobotLogFile);
+                    break;
+            }
+        }
+        return $aGtfParams;
+    }
+    
+    /**
+     * format a GUI occurrence (GtfGui).
+     * @param {object} $oGui GUI occurrence.
+     * @return string
+     */
+    function formatGuiOccurrence($oGui) {
+        $aBaliseToReplace = array('<GTF_EQUAL>', '<GTF_PIPE>');
+        $aReplacedBalise = array('=', '|');
+        $sGTFOutput = str_replace($aBaliseToReplace, $aReplacedBalise, $this->aParametre[$oGui->sDefault_Macro]);
+        switch ($oGui->sType) {
+            case "FLOAT":
+                $sGTFOutput = str_replace(",", ".", $sGTFOutput);
+                if (!$this->isDecode($sGTFOutput))
+                    $sGTFOutput = $this->decoderFME($sGTFOutput);
+                break;
+            case "LOOKUP_CHOICE":
+                if (!$this->isEncode($sGTFOutput))
+                    $sGTFOutput = $this->encoderFME($sGTFOutput);
+                break;
+            case "TEXT_EDIT" :
+            case "TEXT_EDIT_OR_NUM" :
+                if (!$this->isEncode($sGTFOutput)) {
+                    //$sGTFOutput = $this->decoderFME($sGTFOutput);
+                    $sGTFOutput = $this->encoderFME($sGTFOutput);
+                }
+                break;
+            case "CHOICE":
+            case "LOOKUP_LISTBOX":
+                $sGTFOutput = str_replace('"', '""', $sGTFOutput);
+                if (!$this->isDecode($sGTFOutput))
+                    $sGTFOutput = $this->decoderFME($sGTFOutput);
+                break;
+            case "LISTBOX":
+                if ($this->bFmeServer)
+                    $sGTFOutput = explode('<space>', $sGTFOutput);
+                else if (!$this->isDecode($sGTFOutput))
+                    $sGTFOutput = $this->decoderFME($sGTFOutput);
+                break;
+            default :
+                //$sGTFOutput = str_replace('"', '""', $sGTFOutput);
+                if (!$this->isDecode($sGTFOutput))
+                    $sGTFOutput = $this->decoderFME($sGTFOutput);
+                break;
+        }
+        return $sGTFOutput;
+    }
+    
+    /**
+     * Compress all the result files to a zip archive.
+     * @return string
+     */
+    function zipResultFiles() {
+        // Tous les fichiers de résultat dans une archive .zip.
+        $bHasFile = $this->listDir($this->iDemandeId);
+        if ($this->sSourceTemp != "" && $this->aProperties["debug_mode"] == false)
+            clearDir($this->sSourceTemp);
+        if ($bHasFile) {
+            // Paramètres de cryptage de l'utilisateur.
+            $this->initUserEncryptionParameters();
+            //
+            $sIsToZip = $this->CheckResult($this->iDemandeId);
+            $sDestUrl = $this->aProperties["url_export"] . "/gtf/" . $this->sResultDirectoryName;
+            if ($sIsToZip == "") {
+                //Compression en zip des fichiers résultant. Le parametres Array() permet de filtrer les extensions à compresser. Exemples : Array("shp","shx","dbf") ; Array("*")      
+                $sZipFile = $this->zipFile($this->sResultDirectoryPath, $this->sResultDirectoryPath, $sDestUrl, $this->iDemandeId);
+                $sZipFile = str_replace($sDestUrl, $this->sResultDirectoryName, $sZipFile);
+            }
+            else
+                $sZipFile = str_replace($sDestUrl, $this->sResultDirectoryName, $sIsToZip);
+        }
+        else
+            $sZipFile = "";
+        return $sZipFile;
+    }
+    
+    /**
+     * Create a directory for the result files.
+     * @return string
+     */
+    function createResultDirectory() {
+        // Création du répertoire de sortie des données
+        if (!file_exists($this->aProperties["dir_export"] . '/gtf/')){
+            mkdir($this->aProperties["dir_export"] . '/gtf/');
+        }
+        Do {
+            $sResultDirectoryName = getUniqRandomId();
+            $this->sResultDirectoryPath = $this->aProperties["dir_export"] . '/gtf/' . $sResultDirectoryName;
+        }while(file_exists($this->sResultDirectoryPath));
+        // Création d'un répertoire pour le fichier de log FME.
+        mkdir($this->sResultDirectoryPath . '/log', 0777, true);
+        return $sResultDirectoryName;
+    }
+    
+    /**
+     * get GTF parameters.
+     * @param {object} $oGtfFmwParser All the GUI.
+     * @return array
+     */
+    function getFmeParameters($oGtfFmwParser) {
+        $aTGui = array();
+        $aFmeParameters = array();
+        $bUsePattern = false;
+        foreach ($oGtfFmwParser->aGuiObject as $aGui) {
+            if ($aGui->sDefault_Macro != "") {
+                array_push($aTGui, $aGui);
+            }
+            if ($aGui->sDefault_Macro == "GTF_FORCE_PATTERN") {
+                if (strtolower($aGui->sDefaultValue) == "true"){
+                        $bUsePattern = true;
+                }
+            }
+        }
+        foreach ($aTGui as $oGui) {
+            //Teste si le paramètre est une source
+            if ($oGui->bIsSource) {
+                if ($this->aParametre[$oGui->sDefault_Macro] != "" && substr($this->aParametre[$oGui->sDefault_Macro], 0, 7) != "<quote>") {
+                    $this->aParametre[$oGui->sDefault_Macro] = str_replace('//', '/', $this->aParametre[$oGui->sDefault_Macro]);
+                    $sSourceFilePath = $this->aParametre[$oGui->sDefault_Macro];
+                    $sDirSource = $this->unZipSource($this->aParametre[$oGui->sDefault_Macro]);
+                    $aSourceFiles = $this->getSourceParam($oGui, $oGtfFmwParser, $sDirSource, $bUsePattern);
+                    // Test si le fichier source est un .zip.
+                    $bZipSource = false;
+                    if (strtolower(pathinfo($sSourceFilePath, PATHINFO_EXTENSION)) == 'zip') {
+                        $bZipSource = true;
+                        // Si le fichier n'est pas trouvé alors il se trouve dans le répertoire upload.
+                        if (!file_exists($sSourceFilePath))
+                            $sSourceFilePath = $this->aProperties["upload_dir"] . "/" . $sSourceFilePath;
+                    }
+                    // Formatage des fichiers sources.
+                    foreach ($aSourceFiles as $iIndex => $sSourceFile) {
+                        // Si le fichier source est un .zip -> paramètre publié = [chemin de l'archive zip]/[nom du fichier].
+                        if ($bZipSource) {
+                            if ($this->bFmeServer) {
+                                $sSourceFile = str_replace($sDirSource, '', $sSourceFile);
+                                $aSourceFiles[$iIndex] = pathinfo($sSourceFilePath, PATHINFO_BASENAME) . '/' . $sSourceFile;
+                            }
+                            else
+                                $aSourceFiles[$iIndex] = '""' . str_replace($sDirSource, $sSourceFilePath, $sSourceFile) . '""';
+                            // Supprime l'archive décompressée.
+                            clearDir($sDirSource);
+                        }
+                        else if ($this->bFmeServer)
+                            $aSourceFiles[$iIndex] = pathinfo($sSourceFile, PATHINFO_BASENAME);
+                        else
+                            $aSourceFiles[$iIndex] = '""' . $sSourceFile . '""';
+                        // Supprime les doubles slashes.
+                        $aSourceFiles[$iIndex] = str_replace('//', '/', $aSourceFiles[$iIndex]);
+                    }
+                    // Paramètre au format chaine de caractère.
+                    if ($this->bFmeServer)
+                        $this->aParametre[$oGui->sDefault_Macro] = implode('|', $aSourceFiles);
+                    else
+                        $this->aParametre[$oGui->sDefault_Macro] = '"' . implode('<space>', $aSourceFiles) . '"';
+                }
+            }
+            if ($oGui->bIsDest) {
+                $sDest = $this->aParametre[$oGui->sDefault_Macro];
+                $this->updateDestParam($oGui, $oGtfFmwParser, $sDest);
+            }
+
+            if ($this->aParametre[$oGui->sDefault_Macro] != "") {
+
+                if (!$oGui->bIsSource) {
+                    // Protection des guillemets de chaque valeur pour qu'ils soient correctement envoyé à traitement.tcl
+                    // Cette protection s'effectue uniquement pour les paramètre qui ne sont pas sources (un paramètre source est de ce type : """"param1"" ""param2"" ""param3"""" : les guillemets seraient donc protégé et cela fait planter l'exécution)
+                    //$this->aParametre[$oGui->sDefault_Macro] = str_replace('"', '""', $this->aParametre[$oGui->sDefault_Macro]);
+                }
+                $sGTFOutput = $this->formatGuiOccurrence($oGui);
+                $aFmeParameters[$oGui->sDefault_Macro] = $sGTFOutput;
+            }
+        }
+        return $aFmeParameters;
+    }
+    
+    /**
+     * Cryptage d'une archive .zip.
+     * @param {string} $sZipFilePath Path to the zip archive File.
+     * @param {string} $sPassword Password for the zip archive.
+     * @return boolean
+     */
+    function encryptZipArchiveFiles($sZipFilePath, $sPassword) {
+        $zip = new ZipArchive;
+        $res = $zip->open($sZipFilePath);
+        if ($res === true) {
+            for ($i = 0; $i < $zip->numFiles; $i++) {
+                $zip->setEncryptionIndex($i, ZipArchive::EM_AES_256, $sPassword);
+            }
+            $zip->close();
+            return true;
+        }
+        else
+            return false;
+    }
+    
+    /**
+     * Return the path for the log file.
+     * @param {string} $sResultDirectoryPath Path to the result directory.
+     * @return string
+     */
+    function getFmeLogFilePath($sResultDirectoryPath) {
+        return $sResultDirectoryPath . "/log/fme_" . $this->iDemandeId . ".log";
+    }
+    
+    /**
+     * Return the record for a job on Fme Server.
+     * @param {string} $iJobId The id of the job.
+     * @param {object} $oFmeServer FmeServer object.
+     * @return object
+     */
+    function getFmeServerJobRecord($iJobId, $oFmeServer) {
+        return $oFmeServer->serviceRequest('transformations/jobs/id/' . $iJobId, 'get');
+    }
+    
+    /**
+     * Download Result and log files of a job on Fme Server.
+     * @param {number} $iJobId The od of the job.
+     * @param {object} $oFmeServer FmeServer object.
+     * @return object
+     */
+    function downloadFmeServerJobResult($iJobId, $oFmeServer, $aDestinationFiles, $sResource, $sPath) {
         $sZipFile = '';
-        if (!empty($this->oJobResult->id)) {
-            // Sauve l'url de log fme.
-            $this->sLogFme = $sNewDir . "/fme_" . $this->iDemandeId . ".log";
-            $sSql = "UPDATE " . $this->aProperties['schema_gtf'] . ".order SET log_url='" . $this->sLogFme . "' WHERE order_id=" . $this->iDemandeId;
-            $this->oBd->execute($sSql);
-            // Création du répertoire de sortie des données
-             if (!file_exists($this->aProperties["dir_export"] . "/gtf/"))
-                mkdir($this->aProperties["dir_export"] . "/gtf/");
-            $sDestDir = $this->aProperties["dir_export"] . "/gtf/" . $sNewDir;
-            mkdir($sDestDir);
-            // Création de l'URL de téléchargement des données
-            $sDestUrl = $this->aProperties["url_export"] . "/gtf/" . $sNewDir;
-            $oFmeServer->getJobLog($this->oJobResult->id, $sDestDir . "/fme_" . $this->iDemandeId . ".log");
-            // Télécharge les fichiers de résultat.
+        // Téléchargement du fichier de log.
+        if ($oFmeServer->getJobLog($this->oJobResult->id, $this->getFmeLogFilePath($this->sResultDirectoryPath)) === false)
+            return false;
+        // Sauve l'url de log fme.
+        $this->sLogFme = $this->getFmeLogFilePath($this->sResultDirectoryName);
+        $sSql = "UPDATE " . $this->aProperties['schema_gtf'] . ".order SET log_url='" . $this->sLogFme . "' WHERE order_id=" . $this->iDemandeId;
+        $this->oBd->execute($sSql);
+        // Téléchargement des fichiers de résultat (si traitement).
+        if ($this->oJobResult->status == 'SUCCESS') {
+            // Télécharge l'archive .zip contenant tous les fichiers de résultat.
             if (!empty($aDestinationFiles)) {
-                $oFmeServer->downloadResourceFile($sResource, $sPath . '/' . $sNewDir . '.zip', $sDestDir . '/' . $this->iDemandeId . '.zip');
-                $sZipFile = $sNewDir . '/' . $this->iDemandeId . '.zip';
+                if ($oFmeServer->downloadResourceFile($sResource, $sPath . '/' . $this->sResultDirectoryName . '.zip', $this->sResultDirectoryPath . '/' . $this->iDemandeId . '.zip') === false)
+                    return false;
+                $sZipFile = $this->sResultDirectoryName . '/' . $this->iDemandeId . '.zip';
+                // Paramètres de cryptage de l'utilisateur.
+                $this->initUserEncryptionParameters();
+                // Cryptage de l'archive .zip de résultat.
+                if ($this->bDataEncrypt)
+                    $this->encryptZipArchiveFiles($this->sResultDirectoryPath . '/' . $this->iDemandeId . '.zip', $this->sSecretKey);
             }
+            // Log. du résultat
+            if (!empty($this->oJobResult->result))
+                $sStatusMessage = $this->oJobResult->result->statusMessage;
+            else
+                $sStatusMessage = $this->oJobResult->statusMessage;
+            writeToLog(INFO_INFORM . 'FME| ' . $sStatusMessage, $this->sRobotLogFile);
+            writeToLog(INFO_SUCCESSFUL_TREATMENT, $this->sRobotLogFile);
+            /*
+            // Télécharge tous les fichiers de résultat.
+            foreach($aDestinationFiles as $sParamName) {
+                $sFileName = $aFmeParameters[$sParamName];
+                $oFmeServer->downloadResourceFile($sResource, $sPath . '/' . $sFileName, $this->sResultDirectoryPath . '/' . $sFileName);
+            }
+            // Tous les fichiers de résultat dans une archive .zip.
+            $sZipFile = $this->zipResultFiles();
+            */
+            return $sZipFile;
+        }
+        else {
+            if (!empty($this->oJobResult->result))
+                $sStatusMessage = $this->oJobResult->result->statusMessage;
+            else
+                $sStatusMessage = $this->oJobResult->statusMessage;
+            writeToLog(INFO_INFORM . 'FME| ' . $sStatusMessage, $this->sRobotLogFile);
+            return false;
         }
-        return $sZipFile;
     }
 }
 ?>
diff --git a/gtf.engine/gtf.engines/engine.exe b/gtf.engine/gtf.engines/engine.exe
index 299a2bc1ca56950134511a6694772126a6f3c03c..dda7116dacf3dfdb9bbc35f07da7d6a9ac26d98b 100755
Binary files a/gtf.engine/gtf.engines/engine.exe and b/gtf.engine/gtf.engines/engine.exe differ
diff --git a/gtf.engine/gtf.engines/engine.php b/gtf.engine/gtf.engines/engine.php
index ecd6de0b583d2e419710b292fc9c2f9a5b6312b2..e044689721da4a4d2b7ec2b8cf450c9fa4ea7bcc 100755
--- a/gtf.engine/gtf.engines/engine.php
+++ b/gtf.engine/gtf.engines/engine.php
@@ -10,10 +10,7 @@
  */
 $properties["id_gtf_engine"] = $_SERVER['argv'][1]; //Identifiant du moteur calculé à partir de la valeur passée en argument
 $ErrorLicense = $_SERVER['argv'][2]; //Identifiant du moteur calculé à partir de la valeur passée en argument
-// Si "$_SERVER["HTTP_HOST"]" n'est pas renseigné -> php notice.
-if (!isset($_SERVER["HTTP_HOST"]))
-    $_SERVER["HTTP_HOST"] = 'localhost';
-//
+
 require_once ("php_engine_conf.inc");
 require_once ("vmlib/BD.class.inc");
 require_once ("vmlib/logUtil.inc");
@@ -33,7 +30,7 @@ require_once 'string.inc';
 
 require_once 'gtf_lib/FmeCloud.class.inc';
 require_once 'gtf_lib/FmeServer.class.inc';
-require_once 'gtf_lib/AmazonS3.class.inc';
+//require_once 'aws_lib/AmazonS3.class.inc';
 require_once 'gtf_lib/FmeCloudForGtf.class.inc';
 
 
@@ -45,8 +42,7 @@ if ($ErrorLicense == "0") {
     $sDateFin = new DateTime(date("Y-m-d H:i:s"));
 
     //Connexion à la base de données de Données gtf : pas de mot de passe pour le robot
-    $oBd = new BD($properties["login"], '', $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
-    //$oBd = new Vm  ('admin', 'admin', $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
+    $oBd = new BD($properties['login_scheduler'], $properties['password_scheduler'], $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
     if ($oBd->erreurRencontree) {
         writeToLog(INFO_BASE_CONNECTION_ERROR . $properties["database"], $properties["engine_log_file"]);
     } else {
@@ -114,6 +110,7 @@ if ($ErrorLicense == "0") {
         if ($properties["nbr_order_max"] < 1)
             $properties["nbr_order_max"] = 1;
         $aParams['iNnbrOrderMax'] = array('value' => $properties["nbr_order_max"], 'type' => 'number');
+        $aParams['sTimeZone'] = array('value' => str_replace('UTC', '', $properties["server_timezone"]), 'type' => 'string');
 
         $sEnErreur = 2;
         
@@ -122,731 +119,645 @@ if ($ErrorLicense == "0") {
         } else { // On est PAS en heure creuse
             $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["boucle_2"], $aParams);
         }
-        
+        $bAsync = true;
+        $properties['running_jobs_file_path'] = __DIR__ . '/' . 'gtf_engine' . $properties["id_gtf_engine"] . '_jobid.txt';
+        // Suppression des traitements asynchrones sur Fme Server dont les demandes ont été supprimées sur GTF.
+        //removeFmeServerDeletedJobs();
+        // Traitement des demandes.
         while ($aDemande = $oBd->ligneSuivante($oPDOResult)) {
-            //test pour connaitre les nombres de tentatives de chaque demande
-            //if ($aDemande['attempt']>=1){    modif par og 26/04/13
-            if ($properties["max_attempt"] == '') {
-                $properties["max_attempt"] = 2;
-            }
-            if ($aDemande['attempt'] >= $properties["max_attempt"]) {
-                writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_TOO_MANY_ORDER_ATTEMPT), $properties["engine_log_file"]);
-                $iStatut = 4;
-
-                /*
-                  //Mise à jour de la demande.
-                  $sDateTraitement = Date('Y-m-d H:i:s');
-                  $sSql = $aSql[$properties["sgbd"]]["update_demande"];
-                  $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                  $sSql = str_replace("[iStatut]", $iStatut, $sSql);
-                  $sSql = str_replace("[iNbSec]", 0, $sSql);
-                  $sSql = str_replace("[sMessage]", $sMessage, $sSql);
-                  $sSql = str_replace("[sDateTraitement]", $sDateTraitement, $sSql);
-                  $sSql = str_replace("[sResultat]", $sResultat, $sSql);
-                  $sSql = str_replace("[sLogFme]", $sLogFme, $sSql);
-
-                  $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                  $oPDOResult2 = $oBd->execute($sSql);
-                  // */
-
-                //Mise à jour de la demande V2
-                // Requete d'update de la demande
-                $aParams = array();
-                $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
-                $aParams['iStatut'] = array('value' => $iStatut, 'type' => 'number');
-                $aParams['iNbSec'] = array('value' => 0, 'type' => 'number');
-                $aParams['sDateTraitement'] = array('value' => $sDateTraitement, 'type' => 'string');
-                $aParams['sResultat'] = array('value' => $sResultat, 'type' => 'string');
-                $aParams['sLogFme'] = array('value' => $sLogFme, 'type' => 'string');
-                $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
-                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande"], $aParams);
-
-                if ($oBd->erreurRencontree) {
-                    writeToLog(INFO_ORDER_UPDATE_ERROR . "(SQL : $sSql)", $properties["engine_log_file"]);
-                } else {
-                    writeToLog(INFO_ORDER_UPDATE, $properties["engine_log_file"]);
-                    // La demande passe en cours
-                    sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
-                        'action' => 'event',
-                        'service' => 'GtfEvents',
-                        'data' => array(
-                            'event' => 'order_started',
-                            'order' => array(
-                                'order_id' => $aDemande['order_id'],
-                                'order_status_id' => $aDemande['order_status_id'],
-                                'user_id' => $aDemande['user_id'],
-                                'workspace_id' => $aDemande['workspace_id']
-                            )
-                        )
-                    ));
+            try {
+                //test pour connaitre les nombres de tentatives de chaque demande
+                //if ($aDemande['attempt']>=1){    modif par og 26/04/13
+                if ($properties["max_attempt"] == '') {
+                    $properties["max_attempt"] = 2;
                 }
-                $oPDOResult2 = $oBd->fermeResultat();
-            } else {
+                if ($aDemande['attempt'] >= $properties["max_attempt"] || empty($aDemande['user_id'])) {
+                    if ($aDemande['attempt'] >= $properties["max_attempt"])
+                        writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_TOO_MANY_ORDER_ATTEMPT), $properties["engine_log_file"]);
+                    else
+                        writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_NO_ASSOCIATED_USER), $properties["engine_log_file"]);
+                    $iStatut = 4;
+                    
+                    //Mise à jour de la demande V2
+                    $sDateTraitement = gmdate('Y-m-d H:i:s');
+                    if (updateOrder($aDemande["order_id"], $iStatut, $sDateTraitement, null, 0)) {
+                        writeToLog(INFO_ORDER_UPDATE, $properties["engine_log_file"]);
+                        // Demande non traitable
+                        sendWebsocketOrderStatusMessage('order_started', $iStatut);
+                    }
+                    //$oPDOResult2 = $oBd->fermeResultat();
+                } else {
 
-                /*
-                  //Vérification des droits de l'utilsateur
-                  $sSql = $aSql[$properties["sgbd"]]["getLogin"];
-                  $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
-                  $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
-                  $oPDOResult2 = $oBd->execute($sSql);
-                  // */
+                    /*
+                      //Vérification des droits de l'utilsateur
+                      $sSql = $aSql[$properties["sgbd"]]["getLogin"];
+                      $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
+                      $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
+                      $oPDOResult2 = $oBd->execute($sSql);
+                      // */
 
-                //Vérification des droits de l'utilsateur
-                // Recuperation des login et droits de l'utilisateur en cour
-                $aParams = array();
-                $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
-                $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
-                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["getLogin"], $aParams);
-
-                $aUser = $oBd->ligneSuivante($oPDOResult2);
-                $sGroupListId = getUserGroupsEngines($aUser["login"], $oBd, $properties["mixed_rights_management"]);
-                // Mise à jour du nombre de tentative dans la base
-                $iTentative = $aDemande['attempt'] + 1;
-                $sTable = $properties["schema_gtf"] . ".order";
-                $sChamp = "attempt";
-                $sWhere = "order_id";
-                $sListDemande = $aDemande['order_id'];
-                $oBd->updateLinkedTable($sTable, $sChamp, $sWhere, $sListDemande, $iTentative);
-
-                // Mise à jour de l'état de la demande de traitement
-                $oBd->updateLinkedTable($sTable, "order_status_id", $sWhere, $sListDemande, 5);
-
-                writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_ORDER_PROCESSING), $properties["engine_log_file"]);
-                // OG 27/03/2013 for table job
-                $sBeginExecutionDate = Date('Y-m-d H:i:s');
-                $date = new DateTime();
-                $iTimeStampBegin = $date->getTimestamp(); // Pour calcul de la durée
-                // fin OG 27/03/2013 for job
-                // $sContenuMail = "";
-                $iNbTraitement = $iNbTraitement + 1;
-                $aUserToRefresh[$iNbTraitement] = $aDemande['user_id'];
-                $aUserToRefresh[$iNbTraitement] = $aDemande['user_id'];
-
-                /*
-                  //Vérification si l'utilisateur a les droits pour faire une demande de ce traitement.
-                  $sSql = $aSql[$properties["sgbd"]]["right_user"];
-                  $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                  $sSql = str_replace("[sGroupListId]", $sGroupListId, $sSql);
-                  $oPDOResult2 = $oBd->execute($sSql);
-                  // */
-
-                ///*
-                //Vérification si l'utilisateur a les droits pour faire une demande de ce traitement.
-                $aParams = array();
-                $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                $aParams['sGroupListId'] = array('value' => str_replace(',', '|', $sGroupListId), 'type' => 'group');
-                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["right_user"], $aParams);
-                //*/
-
-                if ($oBd->erreurRencontree) {
-                    writeToLog(INFO_REQUEST_ERROR . $sSql, $properties["engine_log_file"]);
-                    writeToLog(INFO_PHP_ERROR, $properties["engine_log_file"]);
-                    $sMessage = "Erreur SQL.";
-                    // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
-                    $iStatut = $sEnErreur;
-                } else {
-                    if ($sGroupListId == "0") {
-                        $bAutorisationDemande = true;
+                    //Vérification des droits de l'utilsateur
+                    // Recuperation des login et droits de l'utilisateur en cour
+                    $aParams = array();
+                    $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
+                    $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
+                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["getLogin"], $aParams);
+
+                    $aUser = $oBd->ligneSuivante($oPDOResult2);
+                    $sGroupListId = getUserGroupsEngines($aUser["login"], $oBd, $properties["mixed_rights_management"]);
+                    // Mise à jour du nombre de tentative dans la base
+                    $iTentative = $aDemande['attempt'] + 1;
+                    updateOrderAttempt($aDemande['order_id'], $iTentative);
+                    // Mise a jour du message
+                    $aParams = array();
+                    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                    $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                    $aParams['status'] = array('value' => 2, 'type' => 'number');
+                    $oPDOResult3 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
+                    //*/
+                    if ($oBd->erreurRencontree) {
+                        writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                    }
+                    // Fin - OG 27/03/2013 for table job
+                    $oPDOResult3 = $oBd->fermeResultat();
+                    
+                    // OG 27/03/2013 for table job
+                    $sBeginExecutionDate = Date('Y-m-d H:i:s');
+                    $date = new DateTime();
+                    $iTimeStampBegin = $date->getTimestamp(); // Pour calcul de la durée
+                    // fin OG 27/03/2013 for job
+                    // $sContenuMail = "";
+                    $iNbTraitement = $iNbTraitement + 1;
+                    $aUserToRefresh[$iNbTraitement] = $aDemande['user_id'];
+                    $aUserToRefresh[$iNbTraitement] = $aDemande['user_id'];
+
+                    /*
+                      //Vérification si l'utilisateur a les droits pour faire une demande de ce traitement.
+                      $sSql = $aSql[$properties["sgbd"]]["right_user"];
+                      $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                      $sSql = str_replace("[sGroupListId]", $sGroupListId, $sSql);
+                      $oPDOResult2 = $oBd->execute($sSql);
+                      // */
+
+                    ///*
+                    //Vérification si l'utilisateur a les droits pour faire une demande de ce traitement.
+                    $aParams = array();
+                    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                    $aParams['sGroupListId'] = array('value' => str_replace(',', '|', $sGroupListId), 'type' => 'group');
+                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["right_user"], $aParams);
+                    //*/
+
+                    if ($oBd->erreurRencontree) {
+                        writeToLog(INFO_REQUEST_ERROR . $sSql, $properties["engine_log_file"]);
+                        writeToLog(INFO_PHP_ERROR, $properties["engine_log_file"]);
+                        $sMessage = "Erreur SQL.";
+                        // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
+                        $iStatut = $sEnErreur;
                     } else {
-                        $bAutorisationDemande = false;
-                        while ($aTraitementsAutorise = $oBd->ligneSuivante($oPDOResult2)) {
+                        if ($sGroupListId == "0") {
+                            $bAutorisationDemande = true;
+                        } else {
+                            $bAutorisationDemande = false;
+                            while ($aTraitementsAutorise = $oBd->ligneSuivante($oPDOResult2)) {
 
-                            if ($aTraitementsAutorise['workspace_id'] == $aDemande['workspace_id']) {
-                                $bAutorisationDemande = true;
+                                if ($aTraitementsAutorise['workspace_id'] == $aDemande['workspace_id']) {
+                                    $bAutorisationDemande = true;
+                                }
                             }
                         }
-                    }
-                    if ($bAutorisationDemande == true) {
-                        if (class_exists("Traitement.class.inc") == false) {
-                            include_once ("Traitement.class.inc");
-                        }
+                        if ($bAutorisationDemande == true) {
+                            if (class_exists("Traitement.class.inc") == false) {
+                                include_once ("Traitement.class.inc");
+                            }
 
-                        /*
-                          // recuperer le nom du fichier fmw a traiter
-                          $sSql = $aSql[$properties["sgbd"]]["select_traitement"];
-                          $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                          $sSql = str_replace("[iWorkspaceId]", $aDemande['workspace_id'], $sSql);
-                          $oPDOResult3 = $oBd->execute($sSql);
-                          // */
+                            /*
+                              // recuperer le nom du fichier fmw a traiter
+                              $sSql = $aSql[$properties["sgbd"]]["select_traitement"];
+                              $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                              $sSql = str_replace("[iWorkspaceId]", $aDemande['workspace_id'], $sSql);
+                              $oPDOResult3 = $oBd->execute($sSql);
+                              // */
 
-                        ///*
-                        // recuperer le nom du fichier fmw a traiter
-                        $aParams = array();
-                        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                        $aParams['iWorkspaceId'] = array('value' => $aDemande['workspace_id'], 'type' => 'number');
-                        $oPDOResult3 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_traitement"], $aParams);
-                        //*/
+                            ///*
+                            // recuperer le nom du fichier fmw a traiter
+                            $aParams = array();
+                            $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                            $aParams['iWorkspaceId'] = array('value' => $aDemande['workspace_id'], 'type' => 'number');
+                            $oPDOResult3 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_traitement"], $aParams);
+                            //*/
 
-                        $aTraitement = $oBd->ligneSuivante($oPDOResult3);
-                        $iEmailTemplateId = $aTraitement['email_template_id'];
-                        $oPDOResult3 = $oBd->fermeResultat();
-                        // $sSql = $aSql[$properties["sgbd"]]["select_transit_dir"];
-                        // $oPDOResult4 = $oBd->execute($sSql);
-                        // $aAction = $oBd->ligneSuivante ($oPDOResult4);
-                        // $properties["transit_dir"] = $aAction["value"];
-                        // $oPDOResult4 = $oBd->fermeResultat();
-                        
-                        //Lancement du traitement correspondant à la demande.
-                        $bValidFmeLicence = false;
-                        switch($aFmeEngine['fme_engine_type_id']) {
-                            // Traitement exécuté par une occurrence de FME Cloud via l'api rest.
-                            case 'fme_cloud_for_gtf':
-                                $oFmeCloudForGtf = new FmeCloudForGtf($aFmeEngine['iam_access_key_id'], $aFmeEngine['iam_secret_access_key'], $aFmeEngine['s3_region'], 'u0jtg81u4c', 'te', $properties['gtf_instance_id']);
-                            break;
-                            // Traitement exécuté par une occurrence de FME Cloud via l'api rest.
-                            case 'fme_cloud':
-                                $oFmeCloud = new FmeCloud($aFmeEngine['server_url'], $aFmeEngine['fme_cloud_api_token']);
-                                // Liste des occurrences de FME Server.
-                                $aFmeServerInstances = $oFmeCloud->serviceRequest('instances');
-                                if (!empty($aFmeServerInstances)) {
-                                    //print_r($aFmeServerInstances);
-                                    $oFmeServerInstance = $aFmeServerInstances[0];
-                                    // Démarrage de l'occurence si elle est en pause.
-                                    if ($oFmeServerInstance->state == 'PAUSED') {
-                                        $oFmeCloud->startInstance($oFmeServerInstance->id);
-                                        // Statut = en cours.
-                                        $iStatut = 1;
-                                    }
-                                    else if ($oFmeServerInstance->state == 'RUNNING') {
-                                        //print_r($oFmeServer->getToken());
-                                        $oFmeServer = new FmeServer($oFmeServerInstance->instance_url, $aFmeEngine['login'], $aFmeEngine['password'], 'day', 1);
-                                        // Statut de la licence FME --> erreur avec FME Cloud .
-                                        //$oLicenseStatus = $oFmeServer->serviceRequest('licensing/license/status');
-                                        //if ($oLicenseStatus->isLicensed === true && $oLicenseStatus->isLicenseExpired === false) {
-                                            $bValidFmeLicence = true;
-                                            //
-                                            $oAmazonS3 = new AmazonS3($aFmeEngine['s3_access_key_id'], $aFmeEngine['s3_secret_access_key'], $aFmeEngine['s3_region']);
-                                            //
-                                            $oTraitement = new Traitement($oBd, $aDemande['order_id'], $properties["engine_log_file"], $aDemande['wk_params'], $properties, $aDemande['workspace_id'] . "/fme/" . $aTraitement['fmw_file']);
-                                            if (!$oTraitement->bErreur) {
-                                                $sResultat = $oTraitement->processFmeServerOrder($oFmeServer, $aDemande, $aTraitement, $aUser, $oAmazonS3);
-                                                //$sDateFin = new DateTime(date("Y-m-d H:i:s"));
-                                                $sLogFme = $oTraitement->sLogFme;
+                            $aTraitement = $oBd->ligneSuivante($oPDOResult3);
+                            $iEmailTemplateId = $aTraitement['email_template_id'];
+                            $oPDOResult3 = $oBd->fermeResultat();
+                            // $sSql = $aSql[$properties["sgbd"]]["select_transit_dir"];
+                            // $oPDOResult4 = $oBd->execute($sSql);
+                            // $aAction = $oBd->ligneSuivante ($oPDOResult4);
+                            // $properties["transit_dir"] = $aAction["value"];
+                            // $oPDOResult4 = $oBd->fermeResultat();
+
+                            //Lancement du traitement correspondant à la demande.
+                            $bValidFmeLicence = false;
+                            switch($aFmeEngine['fme_engine_type_id']) {
+                                // Traitement exécuté par une occurrence de FME Cloud via l'api rest.
+                                case 'fme_cloud_for_gtf':
+                                    $oFmeCloudForGtf = new FmeCloudForGtf($aFmeEngine['iam_access_key_id'], $aFmeEngine['iam_secret_access_key'], $aFmeEngine['s3_region'], 'u0jtg81u4c', 'te', $properties['gtf_instance_id']);
+                                break;
+                                // Traitement exécuté par une occurrence de FME Server sur Fme Cloud.
+                                case 'fme_cloud':
+                                    $oFmeCloud = new FmeCloud($aFmeEngine['server_url'], $aFmeEngine['fme_cloud_api_token']);
+                                    $oFmeCloud->sLogFilePath = $properties["engine_log_file"];
+                                    $sMessage = '';
+                                    // Liste des occurrences de FME Server.
+                                    $aFmeServerInstances = $oFmeCloud->serviceRequest('instances');
+                                    if (!empty($aFmeServerInstances)) {
+                                        foreach($aFmeServerInstances as $oInstance) {
+                                            if ($oInstance->name == $aFmeEngine['fme_server_instance_name'])
+                                                $oFmeServerInstance = $oInstance;
+                                        }
+                                        if (empty($oFmeServerInstance)) {
+                                            // Aucune instace active -> mise à jour de la demande (En erreur).
+                                            writeToLog(INFO_FME_CLOUD_INSTANCE_NOT_FOUND, $properties["engine_log_file"]);
+                                            updateOrder($aDemande["order_id"], 2, gmdate('Y-m-d H:i:s'));
+                                            sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+                                            // Envoi un mail de résultat.
+                                            sendOrderResultEmail($iEmailTemplateId);
+                                            writeToLog(INFO_END_ORDER_PROCESSING, $properties["engine_log_file"]);
+                                            // Demande suivante.
+                                            continue 2;
+                                        }
+                                        else {
+                                            writeToLog(INFO_FME_CLOUD_INSTANCE_STATUS . $oFmeServerInstance->state, $properties["engine_log_file"]);
+                                            // Démarrage de l'occurence si elle est en pause.
+                                            if ($oFmeServerInstance->state == 'PAUSED') {
+                                                $oFmeCloud->startInstance($oFmeServerInstance->id);
+                                                writeToLog(INFO_LAUNCHING_FME_CLOUD_INSTANCE, $properties["engine_log_file"]);
+                                                // Nombre de tentative = 0 (instance en pause).
+                                                updateOrderAttempt($aDemande["order_id"], 0);
+                                                // Demande suivante.
+                                                continue 2;
                                             }
-                                            // http 200 : $oFmeServer->aLastCurlRequestInfo->http_code
-                                            if ($oTraitement->oJobResult->status == 'SUCCESS') {
-                                                $sMessage = "";
-                                                $iStatut = 3;
-                                                // Fichier de résultat.
-                                                //if ($sResultat != "")
-                                                    //$sLienResultat = $sResultat;
-                                                $sLienLogFme = $sLogFme;
+                                            else if ($oFmeServerInstance->state == 'RUNNING') {
+                                                writeToLog(INFO_FME_CLOUD_INSTANCE_RUNNING, $properties["engine_log_file"]);
+                                                // Etat de la demande -> en cours.
+                                                $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "order_status_id", "order_id", $aDemande['order_id'], 5);
+                                                sendWebsocketOrderStatusMessage('order_started', 5);
+                                                if (processFmeServerOrder('https://' . $oFmeServerInstance->public_ip, $aFmeEngine['login'], $aFmeEngine['password']) === false)
+                                                    continue 2;
+                                                /*
+                                                // Stockage Amazon S3 qui contiendra les fichiers sources pour le traitement FME.
+                                                $oAmazonS3 = new AmazonS3($aFmeEngine['s3_access_key_id'], $aFmeEngine['s3_secret_access_key'], $aFmeEngine['s3_region']);
+                                                $oAmazonS3->sLogFilePath = $properties["engine_log_file"];
+                                                $oTraitement->sFmeServerS3Bucket = $aFmeEngine['fme_server_s3_bucket'];
+                                                */
+                                                // Mise en pause de l'occurence.
+                                                //$oFmeCloud->pauseInstance($oFmeServerInstance->id);
                                             }
                                             else {
-                                                $sMessage = "";
-                                                $iStatut = $sEnErreur;
+                                                // Nombre de tentative = 0 (instance en cours de démarrage).
+                                                updateOrderAttempt($aDemande["order_id"], 0);
+                                                // Demande suivante.
+                                                continue 2;
                                             }
-                                        //}
-                                        // Mise en pause de l'occurence.
-                                        $oFmeCloud->pauseInstance($oFmeServerInstance->id);
-                                    }
-                                }
-                            break;
-                            // Traitement exécuté par un serveur fme via l'api rest.
-                            case 'fme_server':
-                                $oFmeServer = new FmeServer($aFmeEngine['server_url'], $aFmeEngine['login'], $aFmeEngine['password'], 'day', 1);
-                                // Statut de la licence FME.
-                                $oLicenseStatus = $oFmeServer->serviceRequest('licensing/license/status');
-                                if ($oLicenseStatus->isLicensed === true && $oLicenseStatus->isLicenseExpired === false) {
-                                    $bValidFmeLicence = true;
-                                    $oTraitement = new Traitement($oBd, $aDemande['order_id'], $properties["engine_log_file"], $aDemande['wk_params'], $properties, $aDemande['workspace_id'] . "/fme/" . $aTraitement['fmw_file']);
-                                    if (!$oTraitement->bErreur) {
-                                        $sResultat = $oTraitement->processFmeServerOrder($oFmeServer, $aDemande, $aTraitement, $aUser);
-                                        //$sDateFin = new DateTime(date("Y-m-d H:i:s"));
-                                        $sLogFme = $oTraitement->sLogFme;
-                                    }
-                                    // http 200 : $oFmeServer->aLastCurlRequestInfo->http_code
-                                    if ($oTraitement->oJobResult->status == 'SUCCESS') {
-                                        $sMessage = "";
-                                        $iStatut = 3;
-                                        // Fichier de résultat.
-                                        //if ($sResultat != "")
-                                            //$sLienResultat = $sResultat;
-                                        $sLienLogFme = $sLogFme;
+                                        }
                                     }
                                     else {
-                                        $sMessage = "";
-                                        $iStatut = $sEnErreur;
+                                        // Aucune instace active -> mise à jour de la demande.
+                                        writeToLog(INFO_NO_FME_CLOUD_INSTANCES, $properties["engine_log_file"]);
+                                        updateOrder($aDemande["order_id"], 2, gmdate('Y-m-d H:i:s'));
+                                        sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+                                        // Envoi un mail de résultat.
+                                        sendOrderResultEmail($iEmailTemplateId);
+                                        writeToLog(INFO_END_ORDER_PROCESSING, $properties["engine_log_file"]);
+                                        // Demande suivante.
+                                        continue 2;
                                     }
-                                }
-                            break;
-                            // Traitement exécuté par un fme local.
-                            case 'desktop':
-                                $aLicence = getFmeLicence($properties['fme_path']);
-                                $bLicenceIsValid = $aLicence['valid'];
-                                $aLicence['valid'] = 1;
-                                if ($aLicence['valid'] == 1) {
-                                    $bValidFmeLicence = true;
-                                    $sDateDebut = new DateTime(date("Y-m-d H:i:s"));
-                                    $oTraitement = new Traitement($oBd, $aDemande['order_id'], $properties["engine_log_file"], $aDemande['wk_params'], $properties, $aDemande['workspace_id'] . "/fme/" . $aTraitement['fmw_file']);
-
-                                    if (!$oTraitement->bErreur) {
-                                        $sResultat = $oTraitement->Process();
-                                        $sDateFin = new DateTime(date("Y-m-d H:i:s"));
-                                        $sLogFme = $oTraitement->sLogFme;
-                                    }
-                                    //Gestion des erreurs.
-
-                                    if ($oTraitement->bFmeCrash)
-                                        $iStatut = 1;
-                                    elseif ($oTraitement->bErreur) {
-                                        if ($aTraitement["failed_action_id"] != "" && $oTraitement->sSource != "") {
-                                            $aSource = explode("/", $oTraitement->sSource);
-                                            $sSourceDirectory = $properties["upload_dir"] . $aSource[0];
-
-                                            if ($aTraitement["failed_action_id"] == 1) {
-                                                clearDir($sSourceDirectory);
-                                                writeToLog(INFO_DELETE_DIRECTORY . $sSourceDirectory . '.', $properties["engine_log_file"]);
-                                            } elseif ($aTraitement["failed_action_id"] == 2) {
-                                                /*
-                                                  $sSql = $aSql[$properties["sgbd"]]["select_user"];
-                                                  $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
-                                                  $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
-                                                  $oPDOResult2 = $oBd->execute($sSql);
-                                                  // */
-                                                ///*
-                                                // Selection de l'utilisateur
-                                                $aParams = array();
-                                                $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
-                                                $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
-                                                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_user"], $aParams);
-                                                //*/
-                                                if ($oBd->erreurRencontree) {
-                                                    writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
-                                                } else {
-                                                    $aUser = $oBd->ligneSuivante($oPDOResult2);
-
-                                                    $sUser = userToFolder($aUser["name"]);
-                                                    if (file_exists($properties["transit_dir"])) {
-                                                        if (!file_exists($properties["transit_dir"] . "/failed/")) {
-                                                            mkdir($properties["transit_dir"] . "/failed/");
-                                                        }
-                                                        if (!file_exists($properties["transit_dir"] . "/failed/" . $sUser)) {
-                                                            mkdir($properties["transit_dir"] . "/failed/" . $sUser);
-                                                        }
-                                                        if (!file_exists($properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"])) {
-                                                            mkdir($properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"]);
-                                                        }
-                                                        rename($sSourceDirectory, $properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"]);
-                                                        writeToLog(str_replace('[sSourceDirectory]', $sSourceDirectory, INFO_MOVING_FILE) . $properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"] . '.', $properties["engine_log_file"]);
+                                break;
+                                // Traitement exécuté par un serveur fme via l'api rest.
+                                case 'fme_server':
+                                    // Mise à jour de l'état de la demande de traitement (en cours).
+                                    $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "order_status_id", "order_id", $aDemande['order_id'], 5);
+                                    sendWebsocketOrderStatusMessage('order_started', 5);
+                                    writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_ORDER_PROCESSING), $properties["engine_log_file"]);
+                                    // Lancement du traitement.
+                                    if (processFmeServerOrder($aFmeEngine['server_url'], $aFmeEngine['login'], $aFmeEngine['password']) === false)
+                                        continue 2;
+                                break;
+                                // Traitement exécuté par un fme local.
+                                case 'desktop':
+                                    $aLicence = getFmeLicence($properties['fme_path']);
+                                    $bLicenceIsValid = $aLicence['valid'];
+                                    if ($aLicence['valid'] == 1) {
+                                        $bValidFmeLicence = true;
+                                        $sDateDebut = new DateTime(date("Y-m-d H:i:s"));
+                                        $oTraitement = new Traitement($oBd, $aDemande['order_id'], $properties["engine_log_file"], $aDemande['wk_params'], $properties, $aDemande['workspace_id'] . "/fme/" . $aTraitement['fmw_file']);
+                                        if (!$oTraitement->bErreur) {
+                                            $oTraitement->setUseExternalDbConnection($aFmeEngine['useexternaldbconnection']);
+                                            // Mise à jour de l'état de la demande de traitement (en cours).
+                                            $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "order_status_id", "order_id", $aDemande['order_id'], 5);
+                                            sendWebsocketOrderStatusMessage('order_started', 5);
+                                            writeToLog(str_replace("[aDemande['order_id']]", $aDemande['order_id'], INFO_ORDER_PROCESSING), $properties["engine_log_file"]);
+                                            // Maj du pid dans la base.
+                                            $sPidFilePath = realpath(dirname($_SERVER['SCRIPT_FILENAME'])  . '/pid_' . $properties["id_gtf_engine"] . '.txt');
+                                            if (file_exists($sPidFilePath)) {
+                                                $iPid = file_get_contents($sPidFilePath);
+                                                if (is_numeric($iPid))
+                                                    updateOrderPid($aDemande['order_id'], $iPid);
+                                            }
+                                            // Lancement du traitement.
+                                            $sResultat = $oTraitement->Process();
+                                            $sDateFin = new DateTime(date("Y-m-d H:i:s"));
+                                            $sLogFme = $oTraitement->sLogFme;
+                                        }
+                                        //Gestion des erreurs.
+
+                                        if ($oTraitement->bFmeCrash)
+                                            $iStatut = 1;
+                                        elseif ($oTraitement->bErreur) {
+                                            if ($aTraitement["failed_action_id"] != "" && $oTraitement->sSource != "") {
+                                                $aSource = explode("/", $oTraitement->sSource);
+                                                $sSourceDirectory = $properties["upload_dir"] . $aSource[0];
+
+                                                if ($aTraitement["failed_action_id"] == 1) {
+                                                    clearDir($sSourceDirectory);
+                                                    writeToLog(INFO_DELETE_DIRECTORY . $sSourceDirectory . '.', $properties["engine_log_file"]);
+                                                } elseif ($aTraitement["failed_action_id"] == 2) {
+                                                    /*
+                                                      $sSql = $aSql[$properties["sgbd"]]["select_user"];
+                                                      $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
+                                                      $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
+                                                      $oPDOResult2 = $oBd->execute($sSql);
+                                                      // */
+                                                    ///*
+                                                    // Selection de l'utilisateur
+                                                    $aParams = array();
+                                                    $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
+                                                    $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
+                                                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_user"], $aParams);
+                                                    //*/
+                                                    if ($oBd->erreurRencontree) {
+                                                        writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
                                                     } else {
-                                                        writeToLog(str_replace("[properties['transit_dir']]", $properties['transit_dir'], INFO_DIRECTORY_NOT_FOUND_ENGINE), $properties["engine_log_file"]);
-                                                        $iStatut = $sEnErreur;
+                                                        $aUser = $oBd->ligneSuivante($oPDOResult2);
+
+                                                        $sUser = userToFolder($aUser["name"]);
+                                                        if (file_exists($properties["transit_dir"])) {
+                                                            if (!file_exists($properties["transit_dir"] . "/failed/")) {
+                                                                mkdir($properties["transit_dir"] . "/failed/");
+                                                            }
+                                                            if (!file_exists($properties["transit_dir"] . "/failed/" . $sUser)) {
+                                                                mkdir($properties["transit_dir"] . "/failed/" . $sUser);
+                                                            }
+                                                            if (!file_exists($properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"])) {
+                                                                mkdir($properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"]);
+                                                            }
+                                                            rename($sSourceDirectory, $properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"]);
+                                                            writeToLog(str_replace('[sSourceDirectory]', $sSourceDirectory, INFO_MOVING_FILE) . $properties["transit_dir"] . "/failed/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"] . '.', $properties["engine_log_file"]);
+                                                        } else {
+                                                            writeToLog(str_replace("[properties['transit_dir']]", $properties['transit_dir'], INFO_DIRECTORY_NOT_FOUND_ENGINE), $properties["engine_log_file"]);
+                                                            $iStatut = $sEnErreur;
+                                                        }
                                                     }
                                                 }
                                             }
-                                        }
-                                        $sMessage = $oTraitement->sMessageErreur;
-                                        $iStatut = $sEnErreur;
-                                        $sResultat = '';
-                                        // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
-                                        // $sContenuMail .= "Contactez l'administrateur pour consulter le fichier de log du robot.<br>";
-                                        $sLienLogFme = $sLogFme;
-                                    } else {
-                                        if ($aTraitement["success_action_id"] != "" && $oTraitement->sSource != "") {
-                                            $aSource = explode("/", $oTraitement->sSource);
-                                            $sSourceDirectory = $properties["upload_dir"] . $aSource[0];
-                                            if ($aTraitement["success_action_id"] == 1) {
-                                                clearDir($sSourceDirectory);
-                                                writeToLog(INFO_DELETE_DIRECTORY . $sSourceDirectory . '.', $properties["engine_log_file"]);
-                                            } elseif ($aTraitement["success_action_id"] == 2) {
+                                            $sMessage = $oTraitement->sMessageErreur;
+                                            $iStatut = $sEnErreur;
+                                            $sResultat = '';
+                                            // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
+                                            // $sContenuMail .= "Contactez l'administrateur pour consulter le fichier de log du robot.<br>";
+                                            $sLienLogFme = $sLogFme;
+                                        } else {
+                                            if ($aTraitement["success_action_id"] != "" && $oTraitement->sSource != "") {
+                                                $aSource = explode("/", $oTraitement->sSource);
+                                                $sSourceDirectory = $properties["upload_dir"] . $aSource[0];
+                                                if ($aTraitement["success_action_id"] == 1) {
+                                                    clearDir($sSourceDirectory);
+                                                    writeToLog(INFO_DELETE_DIRECTORY . $sSourceDirectory . '.', $properties["engine_log_file"]);
+                                                } elseif ($aTraitement["success_action_id"] == 2) {
 
-                                                /*
-                                                  $sSql = $aSql[$properties["sgbd"]]["select_user"];
-                                                  $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
-                                                  $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
-                                                  $oPDOResult2 = $oBd->execute($sSql);
-                                                  // */
-                                                ///*
-                                                //Selection de l'utilisateur
-                                                $aParams = array();
-                                                $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
-                                                $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
-                                                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_user"], $aParams);
-                                                //*/
-
-                                                if ($oBd->erreurRencontree) {
-                                                    writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
-                                                } else {
-                                                    $aUser = $oBd->ligneSuivante($oPDOResult2);
-
-                                                    $sUser = userToFolder($aUser["name"]);
-                                                    if (file_exists($properties["transit_dir"])) {
-                                                        if (!file_exists($properties["transit_dir"] . "/success/")) {
-                                                            mkdir($properties["transit_dir"] . "/success/");
-                                                        }
-                                                        if (!file_exists($properties["transit_dir"] . "/success/" . $sUser)) {
-                                                            mkdir($properties["transit_dir"] . "/success/" . $sUser);
-                                                        }
-                                                        if (!file_exists($properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"])) {
-                                                            mkdir($properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"]);
-                                                        }
-                                                        rename($sSourceDirectory, $properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"]);
-                                                        writeToLog(str_replace('[sSourceDirectory]', $sSourceDirectory, INFO_MOVING_FILE) . $properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"] . '.', $properties["engine_log_file"]);
+                                                    /*
+                                                      $sSql = $aSql[$properties["sgbd"]]["select_user"];
+                                                      $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
+                                                      $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
+                                                      $oPDOResult2 = $oBd->execute($sSql);
+                                                      // */
+                                                    ///*
+                                                    //Selection de l'utilisateur
+                                                    $aParams = array();
+                                                    $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
+                                                    $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
+                                                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["select_user"], $aParams);
+                                                    //*/
+
+                                                    if ($oBd->erreurRencontree) {
+                                                        writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
                                                     } else {
-                                                        writeToLog(str_replace("[properties['transit_dir']]", $properties['transit_dir'], INFO_DIRECTORY_NOT_FOUND_ENGINE), $properties["engine_log_file"]);
-                                                        $iStatut = $sEnErreur;
+                                                        $aUser = $oBd->ligneSuivante($oPDOResult2);
+
+                                                        $sUser = userToFolder($aUser["name"]);
+                                                        if (file_exists($properties["transit_dir"])) {
+                                                            if (!file_exists($properties["transit_dir"] . "/success/")) {
+                                                                mkdir($properties["transit_dir"] . "/success/");
+                                                            }
+                                                            if (!file_exists($properties["transit_dir"] . "/success/" . $sUser)) {
+                                                                mkdir($properties["transit_dir"] . "/success/" . $sUser);
+                                                            }
+                                                            if (!file_exists($properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"])) {
+                                                                mkdir($properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"]);
+                                                            }
+                                                            rename($sSourceDirectory, $properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"]);
+                                                            writeToLog(str_replace('[sSourceDirectory]', $sSourceDirectory, INFO_MOVING_FILE) . $properties["transit_dir"] . "/success/" . $sUser . "/" . $aTraitement["workspace_id"] . "/" . $aDemande["order_id"] . '.', $properties["engine_log_file"]);
+                                                        } else {
+                                                            writeToLog(str_replace("[properties['transit_dir']]", $properties['transit_dir'], INFO_DIRECTORY_NOT_FOUND_ENGINE), $properties["engine_log_file"]);
+                                                            $iStatut = $sEnErreur;
+                                                        }
                                                     }
                                                 }
                                             }
+                                            $sMessage = "";
+                                            $iStatut = 3;
+                                            $sLienLogFme = $sLogFme;
                                         }
-                                        $sMessage = "";
-                                        $iStatut = 3;
-                                        // $sContenuMail = "Votre demande de traitement '".$aDemande['workspace_nom']."' a réussi.<br>";
-                                        if ($sResultat != "") {
-                                            // $sContenuMail .= '<A href="'.$properties["url_export"]."/".$sResultat.'">Télécharger le résultat</A><br>';
-                                            $sLienResultat = $sResultat;
-                                        }
-                                        $sLienLogFme = $sLogFme;
+                                        $bDataEncrypt = $oTraitement->bDataEncrypt;
+                                        unset($oTraitement);
                                     }
-                                    unset($oTraitement);
-                                }
-                            break;
-                        }
-                        // Licence invalide.
-                        if (!$bValidFmeLicence) {
-                            $iTentative = $iTentative - 1;
-                            $sTable = $properties["schema_gtf"] . ".order";
-                            $sChamp = "attempt";
-                            $sWhere = "order_id";
-                            $sListDemande = $aDemande['order_id'];
-                            $oBd->updateLinkedTable($sTable, $sChamp, $sWhere, $sListDemande, $iTentative);
-                            writeToLog(INFO_INVALID_FME_LICENCE_FILE, $properties["engine_log_file"]);
+                                break;
+                            }
+                            // Licence invalide.
+                            if (!$bValidFmeLicence) {
+                                $iTentative = $iTentative - 1;
+                                updateOrderAttempt($aDemande['order_id'], $iTentative);
+                                writeToLog(INFO_INVALID_FME_LICENCE_FILE, $properties["engine_log_file"]);
+                                writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["engine_log_file"]);
+                                $sMessage = "Invalid FME licence file. ";
+                                // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
+                                $iStatut = 1;
+                                $sLienLogFme = 'Non disponible';
+                            }
+
+                        } else {
+                            writeToLog(INFO_NO_USER_GRANT . $aDemande['workspace_nom'] . ' n\'a pas été défini.', $properties["engine_log_file"]);
                             writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["engine_log_file"]);
-                            $sMessage = "Invalid FME licence file. ";
+                            $sMessage = "Vous n''avez pas les droits nécessaires pour réaliser ce traitement.";
                             // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
-                            $iStatut = 1;
-                            $sLienLogFme = 'Non disponible';
-                        }
-                        
-                    } else {
-                        writeToLog(INFO_NO_USER_GRANT . $aDemande['workspace_nom'] . ' n\'a pas été défini.', $properties["engine_log_file"]);
-                        writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["engine_log_file"]);
-                        $sMessage = "Vous n''avez pas les droits nécessaires pour réaliser ce traitement.";
-                        // $sContenuMail = 'Votre demande de traitement "'.$aDemande['workspace_nom'].'" a échoué. Voici le message d\'erreur renvoyé : <br><font color="#FF0000">'.$sMessage.'</font><br>';
-                        $iStatut = 6;
+                            $iStatut = 6;
 
-                        if (file_exists($sLogFme)) {
-                            $sLienLogFme = $sLogFme;
-                        } else {
-                            $sLienLogFme = 'Non disponible';
+                            if (file_exists($sLogFme)) {
+                                $sLienLogFme = $sLogFme;
+                            } else {
+                                $sLienLogFme = 'Non disponible';
+                            }
                         }
                     }
-                }
-                $oPDOResult2 = $oBd->fermeResultat();
+                    $oPDOResult2 = $oBd->fermeResultat();
 
-                //Mise à jour de la demande.
+                    //Mise à jour de la demande.
 
-                if ($iStatut == 3) {
-                    /*
-                      $sSql = $aSql[$properties["sgbd"]]["update_message"];
-                      $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                      $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                      $oPDOResult2 = $oBd->execute($sSql);
-                      // */
-                    ///*
-                    // Mise a jour du message
-                    $aParams = array();
-                    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                    $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
-                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
-                    //*/
-                    if ($oBd->erreurRencontree) {
-                        writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                    if ($iStatut == 3) {
+                        /*
+                          $sSql = $aSql[$properties["sgbd"]]["update_message"];
+                          $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                          $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
+                          $oPDOResult2 = $oBd->execute($sSql);
+                          // */
+                        ///*
+                        // Mise a jour du message
+                        $aParams = array();
+                        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                        $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                        $aParams['status'] = array('value' => 1, 'type' => 'number');
+                        $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
+                        //*/
+                        if ($oBd->erreurRencontree) {
+                            writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                        }
+                        // Fin - OG 27/03/2013 for table job
+                        $oPDOResult2 = $oBd->fermeResultat();
                     }
-                    // Fin - OG 27/03/2013 for table job
-                    $oPDOResult2 = $oBd->fermeResultat();
-                }
-                if ($iStatut == 2 || $iStatut == 4) {
+                    if ($iStatut == 2 || $iStatut == 4) {
 
-                    /*
-                      $sSql = $aSql[$properties["sgbd"]]["delete_message"];
-                      $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                      $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                      $oPDOResult2 = $oBd->execute($sSql);
-                      // */
-                    ///*
-                    
-                    // Mise a jour du message
-                    $aParams = array();
-                    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                    $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
-                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
-                    //*/
+                        /*
+                          $sSql = $aSql[$properties["sgbd"]]["delete_message"];
+                          $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                          $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
+                          $oPDOResult2 = $oBd->execute($sSql);
+                          // */
+                        ///*
 
-                    if ($oBd->erreurRencontree) {
-                        writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                        // Mise a jour du message
+                        $aParams = array();
+                        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                        $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                        $aParams['status'] = array('value' => 1, 'type' => 'number');
+                        $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
+                        //*/
+
+                        if ($oBd->erreurRencontree) {
+                            writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                        }
+                        // Fin - OG 27/03/2013 for table job
+                        $oPDOResult2 = $oBd->fermeResultat();
                     }
-                    // Fin - OG 27/03/2013 for table job
-                    $oPDOResult2 = $oBd->fermeResultat();
-                }
-                $sDateTraitement = Date('Y-m-d H:i:s');
-
-                /*
-                $sSql = $aSql[$properties["sgbd"]]["update_demande"];
-                $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                if ($iStatut != 1) {
-                    $timeFirst = strtotime(date_format($sDateDebut, 'Y-m-d H:i:s'));
-                    $timeSecond = strtotime(date_format($sDateFin, 'Y-m-d H:i:s'));
-                    $diff = $timeSecond - $timeFirst;
-                    $iNbSec = $diff;
-                } else {
-                    $iNbSec = "NULL";
-                }
-                // OG 27/03/2013 for table job
-                $date = new DateTime();
-                $iTimeStampEnd = $date->getTimestamp();
-                $iDelay = $iTimeStampEnd - $iTimeStampBegin;
-                $sSql = str_replace("[iNbSec]", $iDelay, $sSql);
-                $sSql = str_replace("[$iStatut]", $iStatut, $sSql);
-                /* $sSql = str_replace("[sMessage]", $sMessage, $sSql); *//*
-                $sSql = str_replace("[sDateTraitement]", $sDateTraitement, $sSql);
-                $sSql = str_replace("[sResultat]", utf8_encode($sResultat), $sSql);
-                $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                if ($sLogFme == "") {
-                    $sSql = str_replace("'[sLogFme]'", "NULL", $sSql);
-                } else {
-                    $sSql = str_replace("[sLogFme]", $sLogFme, $sSql);
-                }
+                    $sDateTraitement = gmdate('Y-m-d H:i:s');
 
-                $oPDOResult2 = $oBd->execute($sSql);
-                //*/
-
-                //*
-                // Mise a jour de la demande
-                  $aParams = array();
-                  $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                  if ($iStatut != 1) {
-                      $timeFirst = strtotime(date_format($sDateDebut, 'Y-m-d H:i:s'));
-                      $timeSecond = strtotime(date_format($sDateFin, 'Y-m-d H:i:s'));
-                      $diff = $timeSecond - $timeFirst;
-                      $iNbSec = $diff;
-                  } else
-                    $iNbSec = "NULL";
-                  // OG 27/03/2013 for table job
-                  $date = new DateTime();
-                  $iTimeStampEnd = $date->getTimestamp();
-                  $iDelay = $iTimeStampEnd - $iTimeStampBegin;
-                  $aParams['iNbSec'] = array('value' => $iDelay, 'type' => 'number');
-                  $aParams['iStatut'] = array('value' => $iStatut, 'type' => 'number');
-                  $aParams['sDateTraitement'] = array('value' => $sDateTraitement, 'type' => 'string');
-                  $aParams['sResultat'] = array('value' =>  utf8_encode($sResultat), 'type' => 'string');
-                  $aParams['iOrderId'] = array('value' =>  $aDemande["order_id"], 'type' => 'number');
-                  if ($sLogFme == "") {
-                  $aParams['sLogFme'] = array('value' =>  "NULL", 'type' => 'string');
-                  } else {
-                  $aParams['sLogFme'] = array('value' =>  $sLogFme, 'type' => 'string');
-                  }
-
-                  $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande"], $aParams);
-                  // */
-
-
-                if ($oBd->erreurRencontree) {
-                    writeToLog(INFO_ORDER_UPDATE_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
-                } else {
-                    writeToLog(INFO_ORDER_UPDATE, $properties["engine_log_file"]);
-                    // La demande est terminée avec un résultat
-                    sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
-                        'action' => 'event',
-                        'service' => 'GtfEvents',
-                        'data' => array(
-                            'event' => 'order_finished_with_result',
-                            'order' => array(
-                                'order_id' => $aDemande['order_id'],
-                                'order_status_id' => $aDemande['order_status_id'],
-                                'user_id' => $aDemande['user_id'],
-                                'workspace_id' => $aDemande['workspace_id']
-                            )
-                        )
-                    ));
-                }
-                if ($iStatut != 1) {
                     /*
-                      $sSql = $aSql[$properties["sgbd"]]["insertJob"];
-                      $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                      $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                      $sSql = str_replace("[iWorkspaceId]", $aDemande["workspace_id"], $sSql);
-                      $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
-                      $sSql = str_replace("[sBeginExecutionDate]", $sBeginExecutionDate, $sSql);
-                      $sSql = str_replace("[iDelay]", $iDelay, $sSql);
-                      $sSql = str_replace("[iGtfEngineId]", $properties["id_gtf_engine"], $sSql);
-                      $sSql = str_replace("[iStatut]", $iStatut, $sSql);
-                      //writeToLog('|INFORM|PHP|Test requête OG : '.$sSql,$properties["engine_log_file"]);
-                      $oPDOResult2 = $oBd->execute($sSql);
-                      // */
-                    ///*
-                    // Insert de schemaGtf
-                    $aParams = array();
-                    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                    $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
-                    $aParams['iWorkspaceId'] = array('value' => $aDemande["workspace_id"], 'type' => 'number');
-                    $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
-                    $aParams['sBeginExecutionDate'] = array('value' => $sBeginExecutionDate, 'type' => 'string');
-                    $aParams['iDelay'] = array('value' => $iDelay, 'type' => 'number');
-                    $aParams['iGtfEngineId'] = array('value' => $properties["id_gtf_engine"], 'type' => 'number');
-                    $aParams['iDelay'] = array('value' => $iDelay, 'type' => 'number');
-                    $aParams['iStatut'] = array('value' => $iStatut, 'type' => 'number');
-                    //writeToLog('|INFORM|PHP|Test requête OG : '.$sSql,$properties["engine_log_file"]);
-                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["insertJob"], $aParams);
-                    //*/
-                    if ($oBd->erreurRencontree) {
-                        writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                    $sSql = $aSql[$properties["sgbd"]]["update_demande"];
+                    $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                    if ($iStatut != 1) {
+                        $timeFirst = strtotime(date_format($sDateDebut, 'Y-m-d H:i:s'));
+                        $timeSecond = strtotime(date_format($sDateFin, 'Y-m-d H:i:s'));
+                        $diff = $timeSecond - $timeFirst;
+                        $iNbSec = $diff;
+                    } else {
+                        $iNbSec = "NULL";
+                    }
+                    // OG 27/03/2013 for table job
+                    $date = new DateTime();
+                    $iTimeStampEnd = $date->getTimestamp();
+                    $iDelay = $iTimeStampEnd - $iTimeStampBegin;
+                    $sSql = str_replace("[iNbSec]", $iDelay, $sSql);
+                    $sSql = str_replace("[$iStatut]", $iStatut, $sSql);
+                    /* $sSql = str_replace("[sMessage]", $sMessage, $sSql); *//*
+                    $sSql = str_replace("[sDateTraitement]", $sDateTraitement, $sSql);
+                    $sSql = str_replace("[sResultat]", utf8_encode($sResultat), $sSql);
+                    $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
+                    if ($sLogFme == "") {
+                        $sSql = str_replace("'[sLogFme]'", "NULL", $sSql);
+                    } else {
+                        $sSql = str_replace("[sLogFme]", $sLogFme, $sSql);
                     }
-                    // Fin - OG 27/03/2013 for table job
-                    $oPDOResult2 = $oBd->fermeResultat();
-                }
-                // Mise à jour de la demande si resultat est vide
-                if ($sResultat == "") {
 
-                    /*
-                      $sSql = $aSql[$properties["sgbd"]]["update_demande_resultat_null"];
-                      $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                      $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
-                      $oPDOResult2 = $oBd->execute($sSql);
-                      // */
+                    $oPDOResult2 = $oBd->execute($sSql);
+                    //*/
 
-                    ///*
-                    // Mise a jour de la demande si resultat null
+                    //*
+                    // Mise a jour de la demande
                     $aParams = array();
                     $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                    $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
-                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande_resultat_null"], $aParams);
-                    //*/
-
-                    if ($oBd->erreurRencontree) {
-                        writeToLog(INFO_ORDER_UPDATE_ERROR . ' (' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
-                    } else {
-                        writeToLog(INFO_INFO_ORDER_UPDATE_NULL, $properties["engine_log_file"]);
-                        // La demande est terminée où en erreur
-                        sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
-                            'action' => 'event',
-                            'service' => 'GtfEvents',
-                            'data' => array(
-                                'event' => 'order_finished_or_error',
-                                'order' => array(
-                                    'order_id' => $aDemande['order_id'],
-                                    'order_status_id' => $aDemande['order_status_id'],
-                                    'user_id' => $aDemande['user_id'],
-                                    'workspace_id' => $aDemande['workspace_id']
-                                )
-                            )
-                        ));
+                    if ($iStatut != 1) {
+                        $timeFirst = strtotime(date_format($sDateDebut, 'Y-m-d H:i:s'));
+                        $timeSecond = strtotime(date_format($sDateFin, 'Y-m-d H:i:s'));
+                        $diff = $timeSecond - $timeFirst;
+                        $iNbSec = $diff;
+                    } else
+                        $iNbSec = "NULL";
+                    // OG 27/03/2013 for table job
+                    $date = new DateTime();
+                    $iTimeStampEnd = $date->getTimestamp();
+                    $iDelay = $iTimeStampEnd - $iTimeStampBegin;
+                    if (updateOrder($aDemande["order_id"], $iStatut, $sDateTraitement, $sLogFme, $iDelay, $sResultat)) {
+                        writeToLog(INFO_ORDER_UPDATE, $properties["engine_log_file"]);
+                        // La demande est terminée avec un résultat
+                        sendWebsocketOrderStatusMessage('order_finished_with_result', $aDemande['order_status_id']);
                     }
-                    $oPDOResult2 = $oBd->fermeResultat();
-                }
-
-                // Notification par e-mail.
-                $bMailToSend = false;
-                switch (strtoupper(trim($aDemande['email_option_id']))) {
-                    case 1:
-                        $bMailToSend = True;
-                        break;
-                    case 2:
-                        $bMailToSend = False;
-                        break;
-                    case 3:
-                        if ($iStatut == $sEnErreur) {
-                            $bMailToSend = True;
-                        }
-                        break;
-                    case 4:
-                        if ($iStatut != $sEnErreur) {
-                            $bMailToSend = True;
+                    if ($iStatut != 1) {
+                        /*
+                          $sSql = $aSql[$properties["sgbd"]]["insertJob"];
+                          $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                          $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
+                          $sSql = str_replace("[iWorkspaceId]", $aDemande["workspace_id"], $sSql);
+                          $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
+                          $sSql = str_replace("[sBeginExecutionDate]", $sBeginExecutionDate, $sSql);
+                          $sSql = str_replace("[iDelay]", $iDelay, $sSql);
+                          $sSql = str_replace("[iGtfEngineId]", $properties["id_gtf_engine"], $sSql);
+                          $sSql = str_replace("[iStatut]", $iStatut, $sSql);
+                          //writeToLog('|INFORM|PHP|Test requête OG : '.$sSql,$properties["engine_log_file"]);
+                          $oPDOResult2 = $oBd->execute($sSql);
+                          // */
+                        ///*
+                        // Insert de schemaGtf
+                        $aParams = array();
+                        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                        $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                        $aParams['iWorkspaceId'] = array('value' => $aDemande["workspace_id"], 'type' => 'number');
+                        $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
+                        $aParams['sBeginExecutionDate'] = array('value' => $sBeginExecutionDate, 'type' => 'string');
+                        $aParams['iDelay'] = array('value' => $iDelay, 'type' => 'number');
+                        $aParams['iGtfEngineId'] = array('value' => $properties["id_gtf_engine"], 'type' => 'number');
+                        $aParams['iDelay'] = array('value' => $iDelay, 'type' => 'number');
+                        $aParams['iStatut'] = array('value' => $iStatut, 'type' => 'number');
+                        //writeToLog('|INFORM|PHP|Test requête OG : '.$sSql,$properties["engine_log_file"]);
+                        $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["insertJob"], $aParams);
+                        //*/
+                        if ($oBd->erreurRencontree) {
+                            writeToLog(INFO_TEST_REQUEST_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
                         }
-                        break;
-                    default:
-                        $bMailToSend = True;
-                }
-
-                // Licence invalide.
-                if ($iStatut == 2 && !$bLicenceIsValid) {
-                    // Mise à jour de l'état de la demande de traitement (en attente).
-                    $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "order_status_id", "order_id", $aDemande['order_id'], 1);
-                    // Licence invalide : 1 mail par jour max.
-                    $sToday = date('d/m/Y');
-                    $sMailLicenceFile = __DIR__ . '\mail_licence.txt';
-                    if (file_exists($sMailLicenceFile))
-                        if (file_get_contents($sMailLicenceFile) == $sToday)
-                            $bMailToSend = false;
-                    file_put_contents($sMailLicenceFile, $sToday);
-                    // Mise à jour du nombre de tentative dans la base.
-                    $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "attempt", "order_id", $aDemande['order_id'], 0);
-                }
-                
-                // Envoi du mail.
-                if ($bMailToSend == true) {
-                    /*
-                      $sSql = $aSql[$properties["sgbd"]]["select_user"];
-                      $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
-                      $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
-                      $oPDOResult2 = $oBd->execute($sSql);
-                      // */
-                    ///*
-                    
-                    //Mise a jour de la demande si resultat null
-                    $aParams = array();
-                    $aParams['iUserId'] = array('value' => $aDemande['user_id'], 'type' => 'number');
-                    $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
-                    $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande_resultat_null"], $aParams);
-                    //*/
-                    if ($oBd->erreurRencontree) {
-                        writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
-                    } else {
-                        // $aUser = $oBd->ligneSuivante ($oPDOResult2);
-                        // $sContenuMail = "Bonjour ".$aUser["name"].",<br><br><br>".$sContenuMail;
-                        // $sContenuMail .= "<br><br><cite><h6>Cet e-mail a été envoyé par un robot, merci de ne pas répondre.</h6></cite><br>";
-                        //	
-
-                        if (empty($iEmailTemplateId))
-                            $iEmailTemplateId = $properties['default_mail_model'];
+                        // Fin - OG 27/03/2013 for table job
+                        $oPDOResult2 = $oBd->fermeResultat();
+                    }
+                    // Mise à jour de la demande si resultat est vide
+                    if ($sResultat == "") {
 
                         /*
-                          // Nom des moteurs GTF et FME
-                          $sSql = $aSql[$properties["sgbd"]]["get_gtf_engine_name"];
+                          $sSql = $aSql[$properties["sgbd"]]["update_demande_resultat_null"];
                           $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
-                          $sSql = str_replace('[gtf_engine_id]', $aDemande['gtf_engine_id'], $sSql);
+                          $sSql = str_replace("[iOrderId]", $aDemande["order_id"], $sSql);
                           $oPDOResult2 = $oBd->execute($sSql);
                           // */
+
                         ///*
-                        // Nom des moteurs GTF et FME
+                        // Mise a jour de la demande si resultat null
                         $aParams = array();
                         $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
-                        $aParams['gtf_engine_id'] = array('value' => $aDemande['gtf_engine_id'], 'type' => 'number');
-                        $oPDOResult2 = $oBd->executeWithParams($sSql = $aSql[$properties["sgbd"]]["get_gtf_engine_name"], $aParams);
+                        $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                        $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande_resultat_null"], $aParams);
                         //*/
 
+                        if ($oBd->erreurRencontree) {
+                            writeToLog(INFO_ORDER_UPDATE_ERROR . ' (' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+                        } else {
+                            writeToLog(INFO_INFO_ORDER_UPDATE_NULL, $properties["engine_log_file"]);
+                            // La demande est terminée où en erreur
+                            sendWebsocketOrderStatusMessage('order_finished_or_error', $aDemande['order_status_id']);
+                        }
+                        $oPDOResult2 = $oBd->fermeResultat();
+                    }
+
+                    // Notification par e-mail.
+                    $bMailToSend = false;
+                    switch (strtoupper(trim($aDemande['email_option_id']))) {
+                        case 1:
+                            $bMailToSend = True;
+                            break;
+                        case 2:
+                            $bMailToSend = False;
+                            break;
+                        case 3:
+                            if ($iStatut == $sEnErreur) {
+                                $bMailToSend = True;
+                            }
+                            break;
+                        case 4:
+                            if ($iStatut != $sEnErreur) {
+                                $bMailToSend = True;
+                            }
+                            break;
+                        default:
+                            $bMailToSend = True;
+                    }
+
+                    // Licence invalide.
+                    if ($iStatut == 2 && !$bLicenceIsValid) {
+                        // Mise à jour de l'état de la demande de traitement (en attente).
+                        $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "order_status_id", "order_id", $aDemande['order_id'], 1);
+                        // Licence invalide : 1 mail par jour max.
+                        $sToday = date('d/m/Y');
+                        $sMailLicenceFile = __DIR__ . '\mail_licence.txt';
+                        if (file_exists($sMailLicenceFile))
+                            if (file_get_contents($sMailLicenceFile) == $sToday)
+                                $bMailToSend = false;
+                        file_put_contents($sMailLicenceFile, $sToday);
+                        // Mise à jour du nombre de tentative dans la base.
+                        updateOrderAttempt($aDemande['order_id'], 0);
+                    }
 
+                    // Envoi du mail.
+                    if ($bMailToSend == true) {
+                        /*
+                          $sSql = $aSql[$properties["sgbd"]]["select_user"];
+                          $sSql = str_replace("[iUserId]", $aDemande['user_id'], $sSql);
+                          $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
+                          $oPDOResult2 = $oBd->execute($sSql);
+                          // */
+                        ///*
+
+                        //Mise a jour de la demande si resultat null
+                        /*
+                        $aParams = array();
+                        $aParams['iOrderId'] = array('value' => $aDemande['order_id'], 'type' => 'number');
+                        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                        $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande_resultat_null"], $aParams);
+                        //
                         if ($oBd->erreurRencontree) {
-                            writeToErrorLog(ERROR_0001);
-                        } else
-                            $aRow = $oBd->ligneSuivante($oPDOResult2);
-
-                        // URL de téléchargement du résultat
-                        $sResultUrl = '';
-                        if ($sResultat != "")
-                            $sResultUrl = '<a href="' . $properties["url_export"] . "/gtf/" . $sResultat . '">Télécharger le résultat</a>';
-
-                        // Dates
-                        $sOrderDate = date_format(date_create($aDemande['order_date']), 'd/m/Y H:i:s');
-
-                        // Envoi du mail
-                        $aObjects = array();
-                        if (!empty($sMessage))
-                            $aObjects['error'] = $sMessage;
-                        $aObjects['oOrder'] = new OrderLib($oBd, $aDemande["order_id"], $properties, "v_order");
-                        $aObjects['oOrder']->formatOrderEmail();
-                        $oEmail = new Email($oBd, $iEmailTemplateId, $properties, $aObjects);
-                        if (!empty($oEmail->oEmailTemplate->name))
-                            $oEmail->send();
+                            writeToLog(INFO_GET_USER_INFO_ERROR . $aDemande['user_id'] . ". (SQL = " . $sSql . ")", $properties["engine_log_file"]);
+                        } else {
+                        */
+                            // $aUser = $oBd->ligneSuivante ($oPDOResult2);
+                            // $sContenuMail = "Bonjour ".$aUser["name"].",<br><br><br>".$sContenuMail;
+                            // $sContenuMail .= "<br><br><cite><h6>Cet e-mail a été envoyé par un robot, merci de ne pas répondre.</h6></cite><br>";
+                            //  
+                            // Envoi du mail
+                            sendOrderResultEmail($iEmailTemplateId, $sMessage);
+                        //}
+                        $oPDOResult2 = $oBd->fermeResultat();
+                    } else {
+                        // pas d'envoi de mail
+                        writeToLog(INFO_NO_MAIL_SEND, $properties["engine_log_file"]);
                     }
-                    $oPDOResult2 = $oBd->fermeResultat();
-                } else {
-                    // pas d'envoi de mail
-                    writeToLog(INFO_NO_MAIL_SEND, $properties["engine_log_file"]);
-                }
-            } //fin du if sur les tentatives
-            //fin de while	
+                } //fin du if sur les tentatives
+                //fin de while  
+            }
+            catch (Exception $e) {
+                writeToErrorLog($e->getMessage());
+                // Mise a jour du message
+                $aParams = array();
+                $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+                $aParams['iOrderId'] = array('value' => $aDemande["order_id"], 'type' => 'number');
+                $aParams['status'] = array('value' => 1, 'type' => 'number');
+                $oPDOResult2 = $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_message"], $aParams);
+                // Mise a jour de la demande.
+                updateOrder($aDemande["order_id"], 2, gmdate('Y-m-d H:i:s'), null, 0);
+                sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+            }
         }
         if ($iNbTraitement >= 1) {
             //Crée ou modifie le fichier de maj de l'application pour l'utilisateur.
@@ -893,4 +804,414 @@ function TesteHeureCreuse($sHeureMin, $sHeureMax) {
     }
 }
 
+/**
+ * Mise à jour d'une demande.
+ * @param {number} $iOrderId Id de la demande.
+ * @param {number} $iStatut Statut de la demande.
+ * @param {string} $sExecutionDate Date de la demande.
+ * @param {number} $iNbSec Durée de la demande en secondes.
+ * @param {string} $sResultUrl Url du résultat de la demande.
+ * @param {string} $sLogUrl Url du log de la demande.
+ */
+function updateOrder($iOrderId, $iStatut, $sExecutionDate, $sLogUrl = null, $iNbSec = null, $sResultUrl = null) {
+    // Variables globales.
+    global $oBd, $properties, $aSql;
+    // Requete d'update de la demande.
+    if (empty($sLogUrl))
+        $sLogUrl = null;
+    if (empty($sResultUrl))
+        $sResultUrl = null;
+    $aParams = array();
+    $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
+    $aParams['iOrderId'] = array('value' => $iOrderId, 'type' => 'number');
+    $aParams['iStatut'] = array('value' => $iStatut, 'type' => 'number');
+    $aParams['sDateTraitement'] = array('value' => $sExecutionDate, 'type' => 'string');
+    $aParams['iNbSec'] = array('value' => $iNbSec, 'type' => 'number');
+    $aParams['sResultat'] = array('value' => $sResultUrl, 'type' => 'string');
+    $aParams['sLogFme'] = array('value' => $sLogUrl, 'type' => 'string');
+    $oBd->executeWithParams($aSql[$properties["sgbd"]]["update_demande"], $aParams);
+    if ($oBd->erreurRencontree) {
+        writeToLog(INFO_ORDER_UPDATE_ERROR . '(' . $oBd->getBDMessage() . ')', $properties["engine_log_file"]);
+        return false;
+    }
+    else
+        return true;
+}
+
+/**
+ * Envoi un mail de résultat du traitement FME.
+ * @param {number} $iEmailTemplateId Id du template de mail.
+ * @param {string} $sMessage Message.
+ */
+function sendOrderResultEmail($iEmailTemplateId, $sMessage = '') {
+    // Variables globales.
+    global $oBd, $properties, $aDemande, $oTraitement;
+    if (!empty($oTraitement))
+        $oTraitement = $oTraitement;
+    // Envoi du mail
+    $aObjects = array();
+    if (!empty($sMessage))
+        $aObjects['error'] = $sMessage;
+    $aObjects['oOrder'] = new OrderLib($oBd, $aDemande["order_id"], $properties, "v_order");
+    $aObjects['oOrder']->formatOrderEmail();
+    if (!empty($oTraitement))
+        $aObjects['oOrder']->aFields['bDataEncrypt'] = $oTraitement->bDataEncrypt;
+    $aObjects['oOrder']->aFields['sApplicationUrl'] = $properties['web_server_name'] . '/' . $properties['application_name'];
+    if (empty($iEmailTemplateId))
+        $iEmailTemplateId = $properties['default_mail_model'];
+    $oEmail = new Email($oBd, $iEmailTemplateId, $properties, $aObjects);
+    if (!empty($oEmail->oEmailTemplate->name))
+        $oEmail->send();
+}
+
+/**
+ * Mise à jour du nombre de tentatives de la demande.
+ * @param {number} $iOrderId Id de la demande.
+ * @param {number} $iAttempt Nombre de tentatives.
+ */
+function updateOrderAttempt($iOrderId, $iAttempt) {
+    // Variables globales.
+    global $oBd, $properties;
+    // Mise à jour du nombre de tentatives de la demande.
+    $oBd->updateLinkedTable($properties["schema_gtf"] . ".order", "attempt", "order_id", $iOrderId, $iAttempt);
+}
+
+/**
+ * Envoi un message au websocket contenant le statut de la demande.
+ * @param {string} $sEvent Nom de l'évènement.
+ * @param {number} $iStatut Statut de la demande.
+ */
+function sendWebsocketOrderStatusMessage($sEvent, $iStatut) {
+    // Variables globales.
+    global $properties, $aDemande;
+    // Envoi du message.
+    sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
+        'action' => 'event',
+        'service' => 'GtfEvents',
+        'data' => array(
+            'event' => $sEvent,
+            'order' => array(
+                'order_id' => $aDemande['order_id'],
+                'order_status_id' => $iStatut,
+                'user_id' => $aDemande['user_id'],
+                'workspace_id' => $aDemande['workspace_id']
+            )
+        )
+    ));
+}
+
+/**
+ * Ajoute un traitement asynchrone en cours d'exécution.
+ * @param {object} $oTraitement Objet de la classe Traitement.
+ * @param {string} $sServerUrl Url to Fme Server.
+ * @param {string} $sLogin User login.
+ * @param {string} $sPassword User password.
+ */
+function addFmeServerRunningJob($oTraitement, $sServerUrl, $sLogin, $sPassword) {
+    // Variables globales.
+    global $properties, $aDemande, $aFmeEngine;
+    // Liste des demandes asynchrones en cours.
+    $aRunningJobs = getFmeServerRunningJobs();
+    // Paramètres de la demande asynchrone à ajouter.
+    $aRunningJob = array(
+        'order_id' => $aDemande['order_id'],
+        'fme_engine_type_id' => $aFmeEngine['fme_engine_type_id'],
+        'job_id' => $oTraitement->oJobResult->id,
+        'result_directory_name' => $oTraitement->sResultDirectoryName,
+        'result_directory_path' => $oTraitement->sResultDirectoryPath,
+        'destination_files' => $oTraitement->aJobDestinationFiles,
+        'resource' => $oTraitement->sJobResource,
+        'path' => $oTraitement->sJobPath,
+        'fme_server_url' => $sServerUrl,
+        'login' => $sLogin,
+        'password' => $sPassword
+    );
+    $aRunningJobs[] = $aRunningJob;
+    // Sauve la liste.
+    file_put_contents($properties['running_jobs_file_path'], serialize($aRunningJobs));
+    // Mise à jour du job id.
+    updateOrderPid($aDemande['order_id'], $oTraitement->oJobResult->id);
+}
+
+/**
+ * Retourne la liste des traitements asynchrones en cours d'exécution.
+ * return array
+ */
+function getFmeServerRunningJobs() {
+    // Variables globales.
+    global $properties;
+    // Retourne la liste des demandes asynchrones en cours ou un tableau vide.
+    if (file_exists($properties['running_jobs_file_path']))
+        return unserialize(file_get_contents($properties['running_jobs_file_path']));
+    else
+        return array();
+}
+
+/**
+ * Vérification de la présence d'un traitement dans la liste des traitements asynchrones en cours d'exécution.
+ * @param {number} $iOrderId Id de la demande en cours.
+ * @param {array} $aRunningJobs Tableau contenant la liste des traitements asynchrones en cours d'exécution.
+ * return boolean
+ */
+function isFmeServerJobRunning($iOrderId, $aRunningJobs) {
+    foreach ($aRunningJobs as $aRunningJob) {
+        if ($aRunningJob['order_id'] == $iOrderId)
+            return true;
+    }
+    return false;
+}
+
+/**
+ * Retourne les infos d'un traitement asynchrones en cours d'exécution.
+ * @param {number} $iOrderId I de la demande en cours.
+ * @param {array} $aRunningJobs Tableau contenant la liste des traitements asynchrones en cours d'exécution.
+ * return array
+ */
+function getFmeServerRunningJob($iOrderId, $aRunningJobs) {
+    foreach ($aRunningJobs as $aRunningJob) {
+        if ($aRunningJob['order_id'] == $iOrderId)
+            return $aRunningJob;
+    }
+    return false;
+}
+
+/**
+ * Supprime un traitement asynchrone en cours d'exécution.
+ * @param {number} $iOrderId Id de la demande en cours.
+ */
+function removeFmeServerRunningJob($iOrderId, $oFmeServer = null) {
+    // Variables globales.
+    global $properties;
+    // Liste des demandes asynchrones en cours.
+    $iJobIndex = null;
+    $aRunningJobs = getFmeServerRunningJobs();
+    foreach ($aRunningJobs as $iIndex => $aRunningJob) {
+        if ($aRunningJob['order_id'] == $iOrderId) {
+            $iJobIndex = $iIndex;
+            break;
+        }
+    }
+    // Sauve la liste.
+    if ($iJobIndex !== null) {
+        // Sauve la liste des demandes asynchrones en cours.
+        $aRunningJob = array_splice($aRunningJobs, $iJobIndex, 1)[0];
+        if (empty($aRunningJobs))
+            unlink($properties['running_jobs_file_path']);
+        else
+            file_put_contents($properties['running_jobs_file_path'], serialize($aRunningJobs));
+        // Supprime le job id.
+        //updateOrderPid($iOrderId);
+        // Ecriture dans les logs.
+        writeToLog(INFO_FME_SERVER_ASYNCHRONOUS_JOB_REMOVED_FROM_LIST . " (demande $iOrderId).", $properties["engine_log_file"]);
+        // Supprime le traitement sur Fme Server.
+        if (is_object($oFmeServer)) {
+            if (!empty($aRunningJob['job_id']))
+                $oFmeServer->deleteJob($aRunningJob['job_id']);
+            // Supprime le répertoire des ressources de la demande sur Fme Server.
+            if (!empty($aRunningJob['resource']) && !empty($aRunningJob['path']))
+                $oFmeServer->serviceRequest('resources/connections/' . $aRunningJob['resource'] . '/filesys/' . $aRunningJob['path'], 'delete');
+        }
+    }
+}
+
+/**
+ * Traitement d'une demande sur Fme Server.
+ * @param {string} $sServerUrl Url to Fme Server.
+ * @param {string} $sLogin User login.
+ * @param {string} $sPassword User password.
+ * return boolean
+ */
+function processFmeServerOrder($sServerUrl, $sLogin, $sPassword) {
+    // Variables globales utilisées.
+    global $oFmeServer, $properties, $oBd, $aFmeEngine, $aDemande, $aTraitement, $aUser, $iEmailTemplateId, $bAsync, $sEnErreur, $iTentative, $sDateDebut, $sDateFin;
+    // Variables globales modifiées.
+    global $oTraitement, $sMessage, $bValidFmeLicence, $sResultat, $sLogFme, $iStatut, $sLienLogFme;
+    // Paramètres de connexion vers Fme Server pour la demande (si elle est dans la liste des traitements asynchrones en cours).
+    $aRunningJobs = getFmeServerRunningJobs();
+    $aRunningJob = getFmeServerRunningJob($aDemande['order_id'], $aRunningJobs);
+    if ($aRunningJob !== false) {
+        $sServerUrl = $aRunningJob['fme_server_url'];
+        $sLogin = $aRunningJob['login'];
+        $sPassword = $aRunningJob['password'];
+    }
+    // 
+    $oFmeServer = new FmeServer($sServerUrl, $sLogin, $sPassword, 'day', 1);
+    $oFmeServer->sLogFilePath = $properties["engine_log_file"];
+    $sMessage = '';
+    // Statut de la licence Fme Server (pas pour Fme Cloud).
+    $oLicenseStatus = '';
+    if ($aFmeEngine['fme_engine_type_id'] == 'fme_server')
+        $oLicenseStatus = $oFmeServer->serviceRequest('licensing/license/status');
+    if ($oLicenseStatus === false)
+        return false;
+    else if ($aFmeEngine['fme_engine_type_id'] == 'fme_cloud' || (!empty($oLicenseStatus) && $oLicenseStatus->isLicensed === true && $oLicenseStatus->isLicenseExpired === false)) {
+        $bValidFmeLicence = true;
+        $oTraitement = new Traitement($oBd, $aDemande['order_id'], $properties["engine_log_file"], $aDemande['wk_params'], $properties, $aDemande['workspace_id'] . "/fme/" . $aTraitement['fmw_file']);
+        $oTraitement->bFmeServer = true;
+        // Demande suivante si le traitement est déja en cours d'exécution.
+        if ($aRunningJob !== false) {
+            // Chemin et nom du répertoire de résultat déja crée.
+            $oTraitement->sResultDirectoryName = $aRunningJob['result_directory_name'];
+            $oTraitement->sResultDirectoryPath = $aRunningJob['result_directory_path'];
+            // Vérification du statut de la demande.
+            $oJobRecord = $oTraitement->getFmeServerJobRecord($aRunningJob['job_id'], $oFmeServer);
+            // Si le job id n'existe pas : 2 essais puis suppression de la demande dans la liste des traitements asynchrones en cours -> non traitable.
+            if ($oFmeServer->aLastCurlRequestInfo['http_code'] == 404) {
+                if ($iTentative >= $properties["max_attempt"])
+                    removeFmeServerRunningJob($aDemande['order_id']);
+            }
+            if ($oJobRecord === false) {
+                return false;
+            }
+            $oTraitement->oJobResult = $oJobRecord;
+            $aRunningStatus = array('SUBMITTED', 'QUEUED', 'DELAYED', 'PAUSED', 'IN_PROCESS', 'PULLED');
+            $aErrorStatus = array('DELETED', 'ABORTED', 'FME_FAILURE', 'JOB_FAILURE');
+            writeToLog(INFO_FME_SERVER_JOB_STATUS . $oJobRecord->status, $properties["engine_log_file"]);
+            // En cours de traitement.
+            if (in_array($oJobRecord->status, $aRunningStatus)) {
+                writeToLog(INFO_FME_SERVER_ASYNCHRONOUS_JOB_IN_PROGRESS, $properties["engine_log_file"]);
+                // Nombre de tentative = 0 (traitement en cours d'exécution).
+                updateOrderAttempt($aDemande["order_id"], 0);
+                return false;
+            }
+            else {
+                // Supprime la demande dans la liste des traitements asynchrones en cours.
+                removeFmeServerRunningJob($aDemande['order_id']);
+                // Télécharge les fichiers de log (et le résultat si présent).
+                $sResultat = $oTraitement->downloadFmeServerJobResult($aRunningJob['job_id'], $oFmeServer, $aRunningJob['destination_files'], $aRunningJob['resource'], $aRunningJob['path']);
+                $oDateDebut = date_create($oJobRecord->timeStarted);
+                $oDateFin = date_create($oJobRecord->timeFinished);
+                // Terminé en erreur.
+                if (in_array($oJobRecord->status, $aErrorStatus) || $sResultat === false) {
+                    updateOrder($aDemande["order_id"], 2, $oJobRecord->timeStarted, $oTraitement->sLogFme, date_diff($oDateDebut, $oDateFin)->format('%s'));
+                    sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+                    // Envoi d'un mail de résultat.
+                    sendOrderResultEmail($iEmailTemplateId);
+                    // Ecriture dans les log.
+                    writeToLog(INFO_TREATMENT_FAILURE, $oTraitement->sRobotLogFile);
+                    // Demande suivante.
+                    return false;
+                }
+                else if ($oJobRecord->status == 'SUCCESS') {
+                    $iStatut = 3;
+                    $sLogFme = $oTraitement->sLogFme;
+                }
+            }
+        }
+        else {
+            $oTraitement->setUseExternalDbConnection($aFmeEngine['useexternaldbconnection']);
+            $sResultat = $oTraitement->submitFmeServerJob($oFmeServer, $aDemande, $aTraitement, $aUser, null, $bAsync);
+            if ($bAsync) {
+                $iStatut = 5;
+                addFmeServerRunningJob($oTraitement, $sServerUrl, $sLogin, $sPassword);
+                writeToLog(INFO_FME_SERVER_JOB_ID . $oTraitement->oJobResult->id, $properties["engine_log_file"]);
+                // Nombre de tentative = 0 (traitement en cours d'exécution).
+                updateOrderAttempt($aDemande["order_id"], 0);
+                // Demande suivante.
+                return false;
+            }
+            else {
+                // Erreur retournée par FME Server.
+                if ($sResultat === false) {
+                    updateOrder($aDemande["order_id"], 2, gmdate('Y-m-d H:i:s'), $oTraitement->sLogFme);
+                    sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+                    writeToLog(INFO_TREATMENT_FAILURE, $oTraitement->sRobotLogFile);
+                    // Envoi d'un mail de résultat.
+                    sendOrderResultEmail($iEmailTemplateId);
+                    // Demande suivante.
+                    return false;
+                }
+                //$sDateFin = new DateTime(date("Y-m-d H:i:s"));
+                $sLogFme = $oTraitement->sLogFme;
+            }
+        }
+        // http 200 : $oFmeServer->aLastCurlRequestInfo['http_code']
+        $sDateDebut = $oJobRecord->timeStarted;
+        $sDateFin = $oJobRecord->timeFinished;
+        if ($oTraitement->oJobResult->status == 'SUCCESS') {
+            $iStatut = 3;
+            $sLienLogFme = $sLogFme;
+        }
+        else
+            $iStatut = $sEnErreur;
+    }
+    else {
+        // Erreur dans la vérification du statut de la licence FME ou expiration.
+        if ($oLicenseStatus->isLicenseExpired)
+            $ErrorMessage = INFO_FME_SERVER_EXPIRED_LICENCE;
+        else
+            $ErrorMessage = INFO_LICENCE_STATUS_VERIFICATION_ERROR;
+        writeToLog($ErrorMessage, $properties["engine_log_file"]);
+        writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["engine_log_file"]);
+        updateOrder($aDemande["order_id"], 2, gmdate('Y-m-d H:i:s'));
+        sendWebsocketOrderStatusMessage('order_finished_or_error', 2);
+        // Envoi d'un mail de résultat.
+        if ($oLicenseStatus->isLicenseExpired === true)
+            $sMessage = 'Invalid FME licence file';
+        sendOrderResultEmail($iEmailTemplateId, $sMessage);
+        // Demande suivante.
+        return false;
+    }
+}
+
+/**
+ * Mise à jour du processus ou job id d'une demande.
+ * @param {number} $iOrderId Id de la demande.
+ * @param {number} $iPid Id du processus (ou job id) de la demande.
+ */
+function updateOrderPid($iOrderId, $iPid = null) {
+    // Variables globales.
+    global $oBd, $properties, $aSql;
+    // Requete d'update de la demande.
+    $aParams = array();
+    $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
+    $aParams['iOrderId'] = array('value' => $iOrderId, 'type' => 'number');
+    $aParams['iPid'] = array('value' => $iPid, 'type' => 'number');
+    $oBd->executeWithParams($aSql[$properties['sgbd']]['update_order_pid'], $aParams);
+    if ($oBd->erreurRencontree)
+        writeToLog(INFO_ORDER_PID_UPDATE_ERROR . "(SQL : {$aSql[$properties['sgbd']]['update_order_pid']})", $properties['engine_log_file']);
+}
+
+/**
+ * Supprime tous les traitements sur Fme Server dont la demande a été supprimée dans GTF.
+ */
+/*
+function removeFmeServerDeletedJobs() {
+    // Variables globales.
+    global $properties, $oBd, $aSql;
+    // Requete d'update de la demande.
+    $aParams = array();
+    $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
+    $oPDOResult = $oBd->executeWithParams($aSql[$properties['sgbd']]['getRunningOrders'], $aParams);
+    if ($oBd->erreurRencontree)
+        writeToLog(INFO_RUNNING_JOBS_ERROR . "(SQL : {$aSql[$properties['sgbd']]['getRunningOrders']})", $properties['engine_log_file']);
+    else {
+        $aOrders = array();
+        while ($aOrder = $oBd->ligneSuivante($oPDOResult))
+            $aOrders[] = $aOrder['order_id'];
+        // Liste des demandes asynchrones en cours.
+        $aRunningJobs = getFmeServerRunningJobs();
+        foreach ($aRunningJobs as $iIndex => $aRunningJob) {
+           if (!in_array($aRunningJob['order_id'], $aOrders)) {
+                $oFmeServer = null;
+                // Supprime le traitement sur Fme Server.
+                if (!empty($aRunningJob['job_id'])) {
+                    $oFmeServer = new FmeServer($aRunningJob['fme_server_url'], $aRunningJob['login'], $aRunningJob['password'], 'day', 1);
+                    $oFmeServer->sLogFilePath = $properties["engine_log_file"];
+                    // Statut de la licence Fme Server (pas pour Fme Cloud).
+                    if ($aRunningJob['fme_engine_type_id'] == 'fme_server') {
+                        $oLicenseStatus = $oFmeServer->serviceRequest('licensing/license/status');
+                        if ($oLicenseStatus === false)
+                            $oFmeServer = null;
+                        else if (is_object($oLicenseStatus) && ($oLicenseStatus->isLicensed === false || $oLicenseStatus->isLicenseExpired === true))
+                            $oFmeServer = null;
+                    }
+                }
+                // Supprime le traitement sur Fme Server.
+                removeFmeServerRunningJob($aRunningJob['order_id'], $oFmeServer);
+            }
+        }
+    }
+}
+*/
 ?>
diff --git a/gtf.engine/gtf.engines/engine.sql.inc b/gtf.engine/gtf.engines/engine.sql.inc
index 9238c05f34c70114a95d81de0ce93e15aad66ef5..24039bdf7d2614239fa52a2d26cb875c51257bcd 100755
--- a/gtf.engine/gtf.engines/engine.sql.inc
+++ b/gtf.engine/gtf.engines/engine.sql.inc
@@ -1,7 +1,7 @@
 <?php
 //Requête pour engine.php pgsql
-$aSql['pgsql']['boucle_1']='SELECT "order".*, rt_priority.priority_id, rt_priority.label_id as priorite_libelle_id, workspace.name as workspace_nom FROM ([sSchemaGtf]."order" LEFT JOIN [sSchemaGtf].rt_priority ON "order".priority_id = rt_priority.priority_id) LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id WHERE (order_status_id = 1 or order_status_id = 5) AND "order".period_id IS NULL AND "order".deleted IS not TRUE AND "order".gtf_engine_id=[iIdGtfEngine] AND "order".priority_id >= [iPriorityId] ORDER BY "order".priority_id ASC, "order".order_id ASC LIMIT [iNnbrOrderMax]';
-$aSql['pgsql']['boucle_2']='SELECT "order".*, rt_priority.priority_id, rt_priority.label_id as priorite_libelle_id, workspace.name as workspace_nom FROM ([sSchemaGtf]."order" LEFT JOIN [sSchemaGtf].rt_priority ON "order".priority_id = rt_priority.priority_id) LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id WHERE (order_status_id = 1 or order_status_id = 5) AND "order".period_id IS NULL AND "order".deleted IS not TRUE AND "order".gtf_engine_id=[iIdGtfEngine] AND "order".priority_id >  [iPriorityId] ORDER BY "order".priority_id ASC, "order".order_id ASC LIMIT [iNnbrOrderMax]';
+$aSql['pgsql']['boucle_1']='SELECT "order".*, rt_priority.priority_id, rt_priority.label_id as priorite_libelle_id, workspace.name as workspace_nom FROM ([sSchemaGtf]."order" LEFT JOIN [sSchemaGtf].rt_priority ON "order".priority_id = rt_priority.priority_id) LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id WHERE (order_status_id = 1 or order_status_id = 5) AND "order".period_id IS NULL AND "order".deleted IS not TRUE AND "order".gtf_engine_id=[iIdGtfEngine] AND "order".priority_id >= [iPriorityId] AND (minexecdate IS NULL or minexecdate AT TIME ZONE [sTimeZone] <=now() AT TIME ZONE [sTimeZone]) ORDER BY "order".priority_id ASC, "order".order_id ASC LIMIT [iNnbrOrderMax]';
+$aSql['pgsql']['boucle_2']='SELECT "order".*, rt_priority.priority_id, rt_priority.label_id as priorite_libelle_id, workspace.name as workspace_nom FROM ([sSchemaGtf]."order" LEFT JOIN [sSchemaGtf].rt_priority ON "order".priority_id = rt_priority.priority_id) LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id WHERE (order_status_id = 1 or order_status_id = 5) AND "order".period_id IS NULL AND "order".deleted IS not TRUE AND "order".gtf_engine_id=[iIdGtfEngine] AND "order".priority_id >  [iPriorityId] AND (minexecdate IS NULL or minexecdate AT TIME ZONE [sTimeZone] <=now() AT TIME ZONE [sTimeZone]) ORDER BY "order".priority_id ASC, "order".order_id ASC LIMIT [iNnbrOrderMax]';
 $aSql['pgsql']['right_user']='SELECT workspace."workspace_id" FROM [sSchemaGtf].workspace RIGHT JOIN [sSchemaGtf].workspace_group ON workspace.workspace_id = workspace_group.workspace_id  GROUP BY workspace."workspace_id", workspace_group."group_id" HAVING workspace_group."group_id" IN ([sGroupListId]) ORDER BY workspace."workspace_id" ASC';
 $aSql['pgsql']['update_demande']="UPDATE [sSchemaGtf].order SET length_sec = [iNbSec], order_status_id=[iStatut], execution_date=[sDateTraitement], result_url=[sResultat], log_url=[sLogFme] WHERE order_id=[iOrderId]";
 $aSql['pgsql']['update_demande_resultat_null']="UPDATE [sSchemaGtf].order SET result_url=NULL WHERE order_id=[iOrderId]";
@@ -9,10 +9,12 @@ $aSql['pgsql']['select_user']='SELECT * FROM [sSchemaFramework].user WHERE "user
 $aSql['pgsql']['select_traitement']='SELECT * FROM [sSchemaGtf].workspace WHERE workspace_id=[iWorkspaceId]';
 //$aSql['pgsql']['select_transit_dir']='SELECT value FROM [sSchemaGtf].property WHERE property=\'$properties["transit_dir"]\'';
 $aSql['pgsql']['select_fme_path']='select local_path as fme_path from [sSchemaGtf].gtf_engine, [sSchemaGtf].fme_engine where fme_engine.fme_engine_id = gtf_engine.fme_engine_id AND gtf_engine.gtf_engine_id = [gtf_engine_id]';
-$aSql['pgsql']['update_message']="UPDATE [sSchemaGtf].message SET status=1 WHERE order_id=[iOrderId]";
+$aSql['pgsql']['update_message']="UPDATE [sSchemaGtf].message SET status=[status] WHERE order_id=[iOrderId]";
 $aSql['pgsql']['delete_message']="DELETE FROM [sSchemaGtf].message where order_id=[iOrderId]";
 $aSql['pgsql']['get_gtf_engine_name'] = 'SELECT gtf_engine.name AS gtf_engine_name,fme_engine.name AS fme_engine_name FROM [sSchemaGtf].gtf_engine,[sSchemaGtf].fme_engine WHERE gtf_engine.fme_engine_id=fme_engine.fme_engine_id AND gtf_engine_id=[gtf_engine_id]';
 $aSql['pgsql']["getLogin"] = 'SELECT "login" from [sSchemaFramework]."user" where user_id = [iUserId]';
 $aSql['pgsql']["insertJob"] = 'INSERT INTO [sSchemaGtf].job(order_id, workspace_id, "user_id", execution_date, length_sec, engine_id, order_status_id) VALUES ([iOrderId], [iWorkspaceId], [iUserId], [sBeginExecutionDate] , [iDelay], [iGtfEngineId], [iStatut])';
 $aSql['pgsql']["getFmeEngine"] = 'SELECT * from [sSchemaGtf].fme_engine WHERE fme_engine_id = (SELECT fme_engine_id FROM [sSchemaGtf].gtf_engine WHERE gtf_engine_id = [gtf_engine_id])';
+$aSql['pgsql']['update_order_pid']="UPDATE [sSchemaGtf].order SET pid=[iPid] WHERE order_id=[iOrderId]";
+$aSql['pgsql']['getRunningOrders'] = 'SELECT order_id FROM [sSchemaGtf]."order" WHERE order_status_id IN (1, 5)';
 ?>
diff --git a/gtf.engine/gtf.engines/lang_engines/fr-lang.inc b/gtf.engine/gtf.engines/lang_engines/fr-lang.inc
index 7d5d50467c79c859e3bbc9b6426827a4d139e006..7b0356cd23a061e8f5d51d1f2d6f2c574a6fedf0 100755
--- a/gtf.engine/gtf.engines/lang_engines/fr-lang.inc
+++ b/gtf.engine/gtf.engines/lang_engines/fr-lang.inc
@@ -1,8 +1,8 @@
 <?php
 
 //Error Licence
-define('E001', "Demandes non trait�es : Fichier de licence invalide");
-define('E002', "Demandes non trait�es : Fichier de licence expir�");
-define('E003', "Demandes non trait�es : Num�ro du moteur GTF sup�rieur au nombre de moteurs disponibles");
+define('E001', "Demandes non traitées : Fichier de licence invalide");
+define('E002', "Demandes non traitées : Fichier de licence expiré");
+define('E003', "Demandes non traitées : Numéro du moteur GTF supérieur au nombre de moteurs disponibles");
 
 ?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/licenses/license.txt b/gtf.engine/gtf.engines/licenses/license.txt
deleted file mode 100755
index 3c36fb544038981697144e6b626959999445908d..0000000000000000000000000000000000000000
--- a/gtf.engine/gtf.engines/licenses/license.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-#GTF  License file
-Product: GTF
-License number: Sgtf-0001
-Expiry date: Permanent
-Engines: 5
-Owner: Veremes
-Key: 295C919B 5A83DA4D 23CC819F 68CB7E3A A41BB54F 
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/php_engine_conf.inc b/gtf.engine/gtf.engines/php_engine_conf.inc
index f43c4cc8e9e90bd3b0113870ae1a1155623a6118..6985372b36c29afb9c6db09e3c4867eb379ea49b 100755
--- a/gtf.engine/gtf.engines/php_engine_conf.inc
+++ b/gtf.engine/gtf.engines/php_engine_conf.inc
@@ -1,4 +1,4 @@
 <?php
-set_include_path('C:\svn\gtf_next_version\gtf.engines;C:\svn\vitis_next_version\vas\rest\conf;C:\svn\vitis_next_version\vas\rest\class');
-ini_set ('error_log', 'C:/svn/gtf_next_version/gtf.engines/php/log/php_errors.log');
+set_include_path(dirname($_SERVER["PHP_SELF"]). PATH_SEPARATOR .dirname($_SERVER["PHP_SELF"]).'/../vas/rest/conf'. PATH_SEPARATOR .dirname($_SERVER["PHP_SELF"]).'/../vas/rest/class');
+ini_set ('error_log', dirname($_SERVER["PHP_SELF"]).'/php/log/php.log');
 ?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/string.inc b/gtf.engine/gtf.engines/string.inc
index 26ffca304f8d99f30136f889c18a8ec11f367835..6a6a266f2cd47f53f5cdce05cd110706cd9ede60 100755
--- a/gtf.engine/gtf.engines/string.inc
+++ b/gtf.engine/gtf.engines/string.inc
@@ -39,6 +39,10 @@
 	define('INFO_GTF_HOME', '|INFORM|PHP| GTF_HOME=');
 	define('INFO_FME_PATH', '|INFORM|PHP| FME_PATH=');
 	define('INFO_TREATMENT_COMMAND_LINE', '|INFORM|PHP| Ligne de commande exécutant le traitement : ');
+	define('INFO_NO_USE_PATTERN', '|INFORM|PHP| Utilisation des noms de fichier, sans utilisation des motifs');
+	define('INFO_USE_PATTERN', '|INFORM|PHP|  Utilisation des motifs ');
+	define('INFO_USER_RESTRICTION', '|ERROR|PHP| Impossible de récupérer la paramètre "restriction" de l\'utilisateur.');
+	define('INFO_GTF_CONNECTION_STRING_TYPE_PASSWORD', '|WARNING|PHP| Le paramètre "GTF_CONNECTION_STRING" doit-être de type "PASSWORD".');
 	
 // engine.php
 	define('INFO_BASE_CONNECTION', '|INFORM|PHP| Connexion à la base de données ');
@@ -54,4 +58,20 @@
 	define('INFO_TEST_REQUEST_ERROR', '|ERROR|PHP|Requête test en erreur. ');
 	define('INFO_INFO_ORDER_UPDATE_NULL', '|INFORM|PHP| Mise à jour de la demande (resultat null).');
 	define('INFO_NO_MAIL_SEND', "|INFORM|PHP| Aucun mail n'a été envoyé ");
+	define('INFO_NO_ASSOCIATED_USER', "|INFORM|PHP| La demande [aDemande['order_id']] n'a pas été traitée car aucun utilisateur est associé.");
+	define('INFO_USER_ENCRYPT_PARAMETERS', '|ERROR|PHP| Impossible de récupérer les paramètres de cryptage de l\'utilisateur et du projet.');
+	define('INFO_NO_FME_CLOUD_INSTANCES', '|ERROR|PHP| Aucune instance FME Server sur FME Cloud n\'est active.');
+	define('INFO_LICENCE_STATUS_VERIFICATION_ERROR', '|ERROR|PHP| Erreur dans la vérification du statut de la licence FME.');
+	define('INFO_FME_CLOUD_INSTANCE_NOT_FOUND', '|ERROR|PHP| L\'instance FME Server spécifiée sur FME Cloud n\'existe pas.');
+	define('INFO_FME_SERVER_JOB_IN_PROGRESS', '|INFORM|PHP| La demande est en cours de traitement par Fme Server.');
+	define('INFO_FME_SERVER_JOB_STATUS', '|INFORM|PHP| Statut de la demande asynchrone sur Fme Server : ');
+	define('INFO_FME_SERVER_JOB_ID', '|INFORM|PHP| Job id pour la demande asynchrone sur Fme Server : ');
+	define('INFO_FME_SERVER_ASYNCHRONOUS_JOB_IN_PROGRESS', '|INFORM|PHP| La demande asynchrone est en cours de traitement par Fme Server.');
+	define('INFO_LAUNCHING_FME_CLOUD_INSTANCE', '|INFORM|PHP| L\'instance FME Server sur FME Cloud est en cours de démarrage.');
+	define('INFO_FME_CLOUD_INSTANCE_STATUS', '|INFORM|PHP| Statut de l\'instance FME Server sur FME Cloud : ');
+	define('INFO_FME_CLOUD_INSTANCE_RUNNING', '|INFORM|PHP| L\'instance FME Server sur FME Cloud est opérationnelle');
+	define('INFO_FME_SERVER_EXPIRED_LICENCE', '|INFORM|PHP| La licence de Fme Server a expiré.');
+	define('INFO_ORDER_PID_UPDATE_ERROR', '|ERROR|PHP| Impossible de mettre à jour le pid de la demande. ');
+	define('INFO_FME_SERVER_ASYNCHRONOUS_JOB_REMOVED_FROM_LIST', '|INFORM|PHP| Le traitement a été retirée de la liste des traitements asynchrones en cours');
+	define('INFO_RUNNING_JOBS_ERROR', '|ERROR|PHP| Impossible de récupérer la liste des demandes en attente et en cours.');
 ?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/subscription.php b/gtf.engine/gtf.engines/subscription.php
index 68d5006129c8a22b1ff2e319691b5804e4d65db0..a6caaae0c62bf4c2f22d34a87e9f93f7e36ffca3 100755
--- a/gtf.engine/gtf.engines/subscription.php
+++ b/gtf.engine/gtf.engines/subscription.php
@@ -41,7 +41,7 @@ require_once 'string.inc';
   }
  */
 //Pas besoin de mot de passe pour le robot
-$oBd = new Vm($properties["login"], '', $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
+$oBd = new Vm($properties["login_scheduler"], $properties['password_scheduler'], $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
 if ($oBd->erreurRencontree) {
     writeToLog(INFO_BASE_CONNECTION_ERROR . $properties["database"], $properties["subscription_log_file"]);
 } else {
@@ -199,7 +199,7 @@ if ($oBd->erreurRencontree) {
                         //deplacement vers le dossier upload en fonction du type
                         $bCopie = false;
                         $bIsFile = false;
-                        $sUnique = UniqFileName();
+                        $sUnique = getUniqRandomId();
                         if (is_dir($sFolder . '/' . $Entry)) {
                             $bIsFile = false;
                             $bCopie = rename($sFolder . "/" . $Entry, $properties["upload_dir"] . "/" . $sUnique);