From ebebc8d189857fb8601c6910d05a69f8e1c2ae3b Mon Sep 17 00:00:00 2001
From: ArmandBahi <armand.bahi@veremes.com>
Date: Mon, 15 Oct 2018 09:22:32 +0200
Subject: [PATCH] add gtf engines

---
 gtf.engine/engine/README.txt                  |  11 +
 gtf.engine/engine/compil-linux.bat            |  21 +
 gtf.engine/engine/compil.bat                  |  34 +
 gtf.engine/engine/engine.c                    | 545 ++++++++++++
 gtf.engine/engine/engine.h                    |  11 +
 gtf.engine/engine/php.ini                     | 162 ++++
 gtf.engine/engine/sha1.c                      | 371 +++++++++
 gtf.engine/engine/sha1.h                      |  54 ++
 gtf.engine/gtf.engines/Changelog.txt          |   1 +
 gtf.engine/gtf.engines/Traitement.class.inc   | 781 +++++++++++++++++
 gtf.engine/gtf.engines/constants.inc          |  10 +
 gtf.engine/gtf.engines/engine                 | Bin 0 -> 32888 bytes
 gtf.engine/gtf.engines/engine.exe             | Bin 0 -> 75276 bytes
 gtf.engine/gtf.engines/engine.php             | 787 ++++++++++++++++++
 gtf.engine/gtf.engines/engine.sql.inc         |  17 +
 .../gtf.engines/lang_engines/en-lang.inc      |   7 +
 .../gtf.engines/lang_engines/fr-lang.inc      |   8 +
 gtf.engine/gtf.engines/php_engine_conf.inc    |   4 +
 gtf.engine/gtf.engines/properties_engine.inc  |  19 +
 gtf.engine/gtf.engines/regex2.dll             | Bin 0 -> 79360 bytes
 gtf.engine/gtf.engines/string.inc             |  59 ++
 gtf.engine/gtf.engines/subscription.bat       |   5 +
 gtf.engine/gtf.engines/subscription.php       | 359 ++++++++
 gtf.engine/gtf.engines/subscription.sql.inc   |   8 +
 gtf.engine/gtf.engines/tcl/Traitement.tcl     |  64 ++
 gtf.engine/gtf.engines/tcl/commande.tcl       |   0
 gtf.engine/gtf.engines/tcl/tclUtil.tcl        |  50 ++
 .../gtf.messages/class/Action.class.inc       |  74 ++
 .../gtf.messages/class/BoAction.class.inc     |  43 +
 .../gtf.messages/class/EmailAction.class.inc  |  40 +
 .../gtf.messages/class/Message.class.inc      | 155 ++++
 .../gtf.messages/class/Message.class.sql.inc  |   4 +
 gtf.engine/gtf.messages/processMessages.bat   |   5 +
 gtf.engine/gtf.messages/processMessages.php   | 173 ++++
 gtf.engine/gtf.messages/processMessages.sh    |   5 +
 .../gtf.messages/processMessages.sql.inc      |   4 +
 36 files changed, 3891 insertions(+)
 create mode 100755 gtf.engine/engine/README.txt
 create mode 100755 gtf.engine/engine/compil-linux.bat
 create mode 100755 gtf.engine/engine/compil.bat
 create mode 100755 gtf.engine/engine/engine.c
 create mode 100755 gtf.engine/engine/engine.h
 create mode 100755 gtf.engine/engine/php.ini
 create mode 100755 gtf.engine/engine/sha1.c
 create mode 100755 gtf.engine/engine/sha1.h
 create mode 100755 gtf.engine/gtf.engines/Changelog.txt
 create mode 100755 gtf.engine/gtf.engines/Traitement.class.inc
 create mode 100755 gtf.engine/gtf.engines/constants.inc
 create mode 100755 gtf.engine/gtf.engines/engine
 create mode 100755 gtf.engine/gtf.engines/engine.exe
 create mode 100755 gtf.engine/gtf.engines/engine.php
 create mode 100755 gtf.engine/gtf.engines/engine.sql.inc
 create mode 100755 gtf.engine/gtf.engines/lang_engines/en-lang.inc
 create mode 100755 gtf.engine/gtf.engines/lang_engines/fr-lang.inc
 create mode 100755 gtf.engine/gtf.engines/php_engine_conf.inc
 create mode 100755 gtf.engine/gtf.engines/properties_engine.inc
 create mode 100755 gtf.engine/gtf.engines/regex2.dll
 create mode 100755 gtf.engine/gtf.engines/string.inc
 create mode 100755 gtf.engine/gtf.engines/subscription.bat
 create mode 100755 gtf.engine/gtf.engines/subscription.php
 create mode 100755 gtf.engine/gtf.engines/subscription.sql.inc
 create mode 100755 gtf.engine/gtf.engines/tcl/Traitement.tcl
 create mode 100755 gtf.engine/gtf.engines/tcl/commande.tcl
 create mode 100755 gtf.engine/gtf.engines/tcl/tclUtil.tcl
 create mode 100755 gtf.engine/gtf.messages/class/Action.class.inc
 create mode 100755 gtf.engine/gtf.messages/class/BoAction.class.inc
 create mode 100755 gtf.engine/gtf.messages/class/EmailAction.class.inc
 create mode 100755 gtf.engine/gtf.messages/class/Message.class.inc
 create mode 100755 gtf.engine/gtf.messages/class/Message.class.sql.inc
 create mode 100755 gtf.engine/gtf.messages/processMessages.bat
 create mode 100755 gtf.engine/gtf.messages/processMessages.php
 create mode 100755 gtf.engine/gtf.messages/processMessages.sh
 create mode 100755 gtf.engine/gtf.messages/processMessages.sql.inc

diff --git a/gtf.engine/engine/README.txt b/gtf.engine/engine/README.txt
new file mode 100755
index 00000000..96459bda
--- /dev/null
+++ b/gtf.engine/engine/README.txt
@@ -0,0 +1,11 @@
+Compilateur
+
+	Le compilateur utilis� est MinGW version 5.1.6
+	Il est disponible sur PICPOUL --> Partage --> Logiciel --> MinGW --> mingw-get-inst-20111118.exe
+	Une fois install�, copier le dossier openssl du dossier MinGW vers <MinGW>/include
+
+
+Compilation
+
+	Pour compiler, il suffit de double-cliquer sur compil.bat
+	La compilation r�cup�re le num�ro de r�vision SVN l'�crit dans le fichier Changelog.txt, compile l'application puis copie les fichiers dans le dossier gtf.engine
diff --git a/gtf.engine/engine/compil-linux.bat b/gtf.engine/engine/compil-linux.bat
new file mode 100755
index 00000000..d395b209
--- /dev/null
+++ b/gtf.engine/engine/compil-linux.bat
@@ -0,0 +1,21 @@
+@ECHO OFF
+SET letter=%~d0
+SET currentPath=%~p0
+CALL :ChangeSlashes currentPath
+CALL :LoCase letter
+
+REM Compilation
+bash -c "cd  /mnt/%letter%%currentPath% && gcc -g engine.c sha1.h sha1.c -o engine -LC:\MingW\lib\ -lregex"
+REM copie vers le dossier gtf.engine
+COPY "engine" "../gtf.engines/engine"
+pause
+
+GOTO:EOF
+
+:LoCase
+:: Subroutine to convert a variable VALUE to all lower case.
+:: The argument for this subroutine is the variable NAME.
+FOR %%i IN (":=" "A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i" "J=j" "K=k" "L=l" "M=m" "N=n" "O=o" "P=p" "Q=q" "R=r" "S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z") DO CALL SET "%1=%%%1:%%~i%%"
+
+:ChangeSlashes
+FOR %%i IN ("\=/") DO CALL SET "%1=%%%1:%%~i%%"
diff --git a/gtf.engine/engine/compil.bat b/gtf.engine/engine/compil.bat
new file mode 100755
index 00000000..cee98ded
--- /dev/null
+++ b/gtf.engine/engine/compil.bat
@@ -0,0 +1,34 @@
+@Echo OFF
+%~d0
+cd %~dp0
+REM Recuperation du numero de version
+for /f "delims=" %%i in ('svnversion "../engine"') do Set versionComp=%%i
+REM Initialisation de la variable de recuperation de version
+set versionComp = 2473:2481M
+REM Verification de la structure de num de version renvoye pas SVN
+echo %versionComp% | find ":"
+REM Si le num de version contient : version complexe sinon version simple
+if errorlevel 1 (call :simpleversion) else (call :complexeversion)
+
+
+:simpleversion
+REM Recuperation du num de version simple
+for /f "delims=" %%i in ('echo %versionComp:~0,4%') do Set version=%%i
+goto compil
+
+:complexeversion
+REM Recuperation du num de version simple
+for /f "delims=" %%i in ('echo %versionComp:~5,4%') do Set version=%%i
+goto compil
+
+:compil
+REM Suppression du fichier Changelog
+IF EXIST Changelog.txt DEL Changelog.txt
+REM Ecriture du num de version
+echo %version% > Changelog.txt
+REM Compilation en incluant la librairie psapi
+gcc -g engine.c sha1.h sha1.c -o engine.exe -l"psapi" -LC:\MingW\lib\ -lregex
+REM copie vers le dossier gtf.engine
+COPY "engine.exe" "../gtf.engines/engine.exe"
+COPY "Changelog.txt" "../gtf.engines/Changelog.txt"
+pause
\ No newline at end of file
diff --git a/gtf.engine/engine/engine.c b/gtf.engine/engine/engine.c
new file mode 100755
index 00000000..5dd2e7c7
--- /dev/null
+++ b/gtf.engine/engine/engine.c
@@ -0,0 +1,545 @@
+#ifdef __unix__
+	#define OS_Windows 0
+	#define MAX_PATH 4096
+	#include <locale.h>
+	typedef unsigned long DWORD;
+	const char * separator = "/";
+#else
+	#define OS_Windows 1
+	#include <windows.h>
+	#include <Winbase.h>
+	#include <tchar.h>
+	#include <psapi.h>
+	const char * separator = "\\";
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h> 
+#include <stdlib.h>
+#include <sys/types.h>  
+#include <unistd.h> 
+#include "sha1.h"
+#include <time.h>
+#include "regex.h"
+#include "engine.h"
+
+#define TAILLE_MAX 1000
+
+int num_pid = 0, debug = 0;
+char *current_directory;
+// const char * separator = "/";
+
+int main(int argc, char *argv[]){
+	int valid = 0;;
+	unsigned int i;
+	if (argc > 1){
+		for (i = 0; i < strlen(argv[1]); ++i){
+			if (!isdigit(argv[1][i]))
+			{
+				valid = 1;
+				break;
+			}
+		}
+		if (valid ==0){
+			if (argc > 2){
+				if (strcmp(argv[2],"d") == 0){
+					debug = 1;
+				}
+			}
+		}else{
+			printf("Syntaxe : engine.exe [moteur_number] [d]\n");
+			printf("d : Debug mode\n");
+
+			exit(1);
+		}
+	}else{
+		printf("Syntaxe : engine.exe [motor_number] [d]\n");
+		printf("d : Debug mode\n");
+
+		exit(1);
+	}
+	//declaration des variables
+	int exist_pid_file = 0;
+	
+	// Nom du fichier pid
+	char* pid_file = malloc(strlen("pid_.txt") + strlen(argv[1]) + 1);
+	sprintf(pid_file, "pid_%s.txt", argv[1]);
+	int result = 0;
+	printf("1\n");
+	//R�cup�ration du r�pertoire courant du fichier courant
+	#ifdef __unix__
+		char *cwd_buffer = malloc(sizeof(char) * MAX_PATH);
+		current_directory = getcwd(cwd_buffer, MAX_PATH);
+	#else
+		char current_path[MAX_PATH];
+		GetModuleFileName( NULL, current_path, MAX_PATH );
+		current_directory = RemplacerFragment((char *)current_path, "\\engine.exe", "");
+	#endif
+	writeToDebugLog("R�pertoire courant : ", current_directory);
+	//remplacement du nom de l exe par le nom du fichier pid
+	char* pid_file_path = malloc(strlen(current_directory) + strlen("/") + strlen(pid_file) + 1);
+	sprintf(pid_file_path, "%s%s%s", current_directory, separator, pid_file);
+
+	writeToDebugLog("fichier PID : ", pid_file_path);
+	//test de l'existence des fichiers
+    exist_pid_file = findPidFile(pid_file_path);
+	
+	char tmp[5];
+	sprintf(tmp, "%i", exist_pid_file);
+	writeToDebugLog("existence Fichier pid (0, n existe pas) : ", tmp);
+	char *motor_number = argv[1];
+	//si fichier inexistant
+	if (exist_pid_file == 0){
+		writeToDebugLog("Execution", " robot non existence fichier pid.");
+		result = execRobot(pid_file_path, motor_number);
+	} else {
+		//si fichier vide
+		if (num_pid == 0){
+			writeToDebugLog("Execution", " robot fichier pid vide.");
+			result = execRobot(pid_file_path, motor_number);
+		} else {
+			sprintf(tmp, "%i", num_pid);
+			writeToDebugLog("num PID : ", tmp);
+			int process = 0;
+			process = verifyProcess(num_pid);
+			if (process == 0){
+				writeToDebugLog("Execution", " robot processus fini.");
+				result = execRobot(pid_file_path, motor_number);
+			}
+		} 
+	}
+	return result;
+}
+
+//fonction de recherche d'un numero de pid
+int findPidFile(char *pid_file_path){
+	//declaration des variables
+	char line[512];
+	int nb_lines = 0;
+	FILE *fic;
+	//ouverture du fichier
+	fic = fopen(pid_file_path, "r"); // ouvrir en lecture
+	
+	//si le programme n a pas trouve de fichier
+	if(fic == NULL){
+		return 0;
+	}
+	//si le programme a trouvee un fichier
+	else{
+		//lecture du fichier
+		while(fgets(line, 512, fic) != NULL){
+			//recuperation du pid
+			num_pid = atoi(line);
+			//passage a la ligne suivante
+			nb_lines++;
+		}
+		//fermeture du fichier
+		fclose(fic); 
+		return 1;
+	}
+}
+
+//Fonction de remplacement de chaine de caractere par une autre : n'existe pas par defaut en c.
+char *RemplacerFragment(char *source, char *vieux, char *nouveau){
+	//Recuperation des parametres
+	char *original = source;
+	char temp[256];
+	int ancienne_long = strlen (vieux);
+	int i, j, k, place = -1;
+	 
+	//recherche de la position de l'occurence tant que la fonction n a pas trouvee
+	for (i = 0; source[i] && (place == -1); ++i){
+		for (j = i, k = 0; source[j] == vieux[k]; j++, k++){
+			if (!vieux[k+1]){
+				place = i;
+			}
+		}
+	}
+	//remplacement de lancienne chaine par la nouvelle
+	if (place != -1){
+		//recuperation de la chaine jusqu a l'emplacement de la chaine a remplacer
+		for (j=0; j < place; j++){
+			temp[j] = source[j];
+		}
+		//remplacement de l ancienne valeur par la nouvelle
+		for (i=0; nouveau[i]; i++, j++){
+			temp[j] = nouveau[i];
+		}
+		//reucperation de la fin de la chaine de caracteres
+		for (k = place + ancienne_long; source[k]; k++, j++){
+			temp[j] = source[k];
+		}
+		temp[j] = 0;
+		for (i=0; (source[i] = temp[i]); i++){
+		}
+	}
+	return original;
+} 
+
+int execRobot(char *pid_file_path, char *motor_number){
+	writeToDebugLog("path pid : ", pid_file_path);
+	getWritePid(pid_file_path);
+	char var_env_engine[MAX_PATH];
+	char var_env_php[MAX_PATH];
+	
+	strcpy(var_env_engine, "GTF_ENGINE_HOME=");
+	strcat(var_env_engine, current_directory);
+	
+	strcpy(var_env_php, "PHP_HOME=");
+	strcat(var_env_php, current_directory);
+	strcat(var_env_php, "/php");
+	
+	writeToDebugLog("", var_env_php);
+	writeToDebugLog("", var_env_engine);
+	putenv(var_env_engine);
+	putenv(var_env_php);
+	putenv("PYTHONPATH=");
+	// Changement de la locale pour traiter les nombres
+	setlocale(LC_NUMERIC, "en_US.UTF8");
+	
+	char *argument = verifyLicense(motor_number);
+	writeToDebugLog("value verification : ", argument);
+	char function_robot[512];
+	if (OS_Windows == 0) {
+		sprintf(function_robot, "\"%s%sphp%sbin%sphp\" \"%s%sengine.php\" %s %s", current_directory, separator, separator, separator, current_directory, separator, motor_number, argument);	
+	} else {
+		sprintf(function_robot, "\"\"%s%sphp%sphp.exe\" \"%s%sengine.php\" %s %s\"", current_directory, separator, separator, current_directory, separator, motor_number, argument);		
+	}
+	writeToDebugLog("function : ", function_robot);
+	system(function_robot);
+
+	remove(pid_file_path);
+	return 0;
+}
+
+void getWritePid(char *pid_file_path){
+	FILE *fic;
+	//ouverture du fichier
+	fic = fopen(pid_file_path, "w"); //"w"  : mode texte en �criture (cr�ation)
+	//recuperation du pid
+	pid_t pid = getpid();
+	fprintf(fic, "%i", pid);
+	fclose(fic);
+}
+
+
+int verifyProcess(int num_pid){
+	int running = 0;
+	int i = 0;
+	int j = 0;
+	char *szProcessName;
+	char *szProcessNameWithSpaces;
+	#ifdef __unix__
+		if (getpgid(num_pid) >= 0){
+			FILE *fic;
+			char* process_path = malloc(strlen("/proc//comm") + 6);
+			sprintf(process_path, "/proc/%i/comm", num_pid);
+			//ouverture du fichier
+			fic = fopen(process_path, "r"); // ouvrir en lecture
+	
+			//si le programme n a pas trouve de fichier
+			if(fic != NULL){
+				//lecture du fichier
+				char line[512];
+				int nb_lines = 0;
+				while(fgets(line, 512, fic) != NULL){
+					//recuperation du nom du pid
+					szProcessNameWithSpaces = line;
+					//passage a la ligne suivante
+					nb_lines++;
+				}
+				//trim 
+				while(i < strlen(szProcessNameWithSpaces)){
+					if (&szProcessNameWithSpaces[i] != " " || &szProcessNameWithSpaces[i] != "\n"){
+						i++;
+					} else {
+						szProcessName[j] = szProcessNameWithSpaces[i];
+						i++;
+						j++;
+					}
+				}
+				//fermeture du fichier
+				fclose(fic);
+				writeToDebugLog("Pid name: ",  szProcessName);
+				writeToDebugLog("Exe file : engine", "");
+				if (strcmp(szProcessName, "engine") == 0){
+					running = 1;
+				}
+			}
+		}
+	#elif defined(_WIN32)
+		HANDLE hProcess=OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION,FALSE, num_pid);
+		if(hProcess){
+			HMODULE hMod;
+			DWORD unused;
+			if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &unused)){
+				GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(char));
+				writeToDebugLog("Pid name: ",  szProcessName);
+				writeToDebugLog("Exe file : engine.exe", "");
+				if (strcmp(szProcessName, "engine.exe") == 0){
+					running = 1;
+				}
+			}
+		}
+	#endif
+	return running;
+}
+
+char *verifyLicense(char *motor_number){
+	char *returnValue = "";
+	char expireDate[TAILLE_MAX] = "";
+	char motorNumber[TAILLE_MAX] = "";
+
+	char* licence_path = malloc(strlen(current_directory) + strlen("licenseslicense.txt") + 3);
+	sprintf(licence_path, "%s%slicenses%slicense.txt", current_directory, separator, separator);
+
+	FILE* fichier = NULL;
+	writeToDebugLog("Fichier License : ",licence_path);
+	fichier = fopen(licence_path, "r");
+	if (fichier != NULL){
+		char chaine[TAILLE_MAX] = "";
+		char testChaine[TAILLE_MAX] = "";
+		// char *chaine = "";
+		char *key;
+		char *temp;
+		char toKey[TAILLE_MAX] = "";
+		int z = 0;
+		while (fgets(chaine, TAILLE_MAX, fichier) != NULL){ // On lit le fichier tant qu'on ne re�oit pas d'erreur (NULL)
+			if (chaine[0]!= '#'){
+				RemplacerFragment(chaine, "\r", "");
+				copie(chaine, testChaine);
+				if (strncmp( verifyRegexp(testChaine, "^Expiry date: (Permanent|[0-9]{6,8})"), "error", 1000)  != 0){
+					RemplacerFragment(testChaine, "Expiry date: ", "");
+					copie(testChaine, expireDate);
+				}
+				if (strncmp( verifyRegexp(testChaine, "^Engines: ([0-9]+)"), "error", 1000)  != 0){
+					RemplacerFragment(testChaine, "Engines: ", "");
+					copie(testChaine, motorNumber);
+				}
+				if (chaine[0]!= 'K'){
+					if (z == 0){
+						z = z+1;
+					}else{
+						strcat(toKey, "\n");
+					}
+					temp = RemplacerFragment(chaine, "\n", "");
+					strcat(toKey, temp);
+				}else{
+					if (chaine[1]!= 'e'){
+						if (z == 0){
+							z = z+1;
+						}else{
+							strcat(toKey, "\n");
+						}
+						temp = RemplacerFragment(chaine, "\n", "");
+						strcat(toKey, temp);
+					}else{
+						if (chaine[2]!= 'y'){
+							if (z == 0){
+								z = z+1;
+							}else{
+								strcat(toKey, "\n");
+							}
+							temp = RemplacerFragment(chaine, "\n", "");
+							strcat(toKey, temp);
+						}else{
+							key=RemplacerFragment(chaine, "Key: ", "");
+						}
+					}
+				}
+			}
+		}
+		writeToDebugLog("Expire Date: ",expireDate);
+		writeToDebugLog("Motor Number: ",motorNumber);
+		writeToDebugLog("clef: ", key);
+		writeToDebugLog("Toclef: ", toKey);
+		SHA1Context sha;
+		int i;
+		SHA1Reset(&sha);
+		for(i = 1; i <= 1000; i++) {
+			SHA1Input(&sha, toKey, strlen(toKey));
+		}
+		if (!SHA1Result(&sha)){
+			 writeToErrorLog("Erreur licence : ", "Impossible de hasher la clef");
+			 returnValue = "E001";
+		}else{
+			char clefTemp[5][TAILLE_MAX];
+			char *clef, *clefTest;
+			for(i = 0; i < 5; i++){
+				sprintf(clefTemp[i], "%X ", sha.Message_Digest[i]);
+			}
+			int j=0;
+			for(j = 0; j < 5; j++){
+				clefTest= clefTemp[j];
+				 if (j == 0){
+					clef = clefTest;
+				}else{
+					strcat(clef, clefTest);
+				}
+			}
+			writeToDebugLog("clef calcul�e: ", clef);
+			int result = strncmp(clef, key, 1000);
+			if (result == 0){
+				writeToDebugLog("Comparaison Clefs: ", "Egales");
+				time_t current_time;
+				current_time = time(NULL);
+				struct tm *nowtm;
+				int yy, mm, dd;
+				yy = makeInt(expireDate +  0, 4) -1900;
+				mm = makeInt(expireDate +  4, 2)-1;
+				dd = makeInt(expireDate +  6, 2);
+				nowtm = localtime(&current_time);
+				writeToDebugLog("Comparaison Date Nombre moteur: ",motorNumber);
+				writeToDebugLog("Comparaison Date num�ro moteur: ",motor_number);
+				if (strncmp(expireDate, "permanent", 1000) ==0){
+					writeToDebugLog("Comparaison Date : ", "OK");
+					if (atoi(motor_number) <= atoi(motorNumber)){
+						writeToDebugLog("Comparaison Moteur : ", "Ok");
+						returnValue = "0";
+					}else{
+						writeToDebugLog("Comparaison Moteur : ", "Num�ro de moteur trop grand");
+						returnValue = "E003";
+					}
+				}else{
+					if (yy < nowtm->tm_year){
+						writeToDebugLog("Comparaison Date : ", "Ann�e courante sup�rieure");
+						writeToErrorLog("Erreur licence : ", "Ann�e courante sup�rieure");
+						returnValue = "E002";
+					}else{
+						if (mm < nowtm->tm_mon){
+							writeToDebugLog("Comparaison Date : ", "Mois courant sup�rieur");
+							returnValue = "E002";
+						}else{
+							if (dd < nowtm->tm_mday){
+								writeToDebugLog("Comparaison Date : ", "Jour courant sup�rieur");
+								returnValue = "E002";
+							}else{
+								writeToDebugLog("Comparaison Date : ", "OK");
+								if (atoi(motor_number) <= atoi(motorNumber)){
+									writeToDebugLog("Comparaison Moteur : ", "Ok");
+									returnValue = "0";
+								}else{
+									writeToDebugLog("Comparaison Moteur : ", "Num�ro de moteur trop grand");
+									writeToErrorLog("Erreur licence : ", "Num�ro de moteur trop grand");
+									returnValue = "E003";
+								}
+							}
+						}
+					}
+				}
+				
+			}else{
+				returnValue = "E001";
+				writeToDebugLog("Comparaison Clefs : ", "Diff�rentes");
+				writeToErrorLog("Erreur licence : ", "Clefs diff�rentes");
+			}
+		} 
+		fclose(fichier);
+	}else{
+		// On affiche un message d'erreur si on veut
+		writeToErrorLog("Erreur licence : ", "Ouverture du fichier impossible");
+		returnValue = "E001";
+	}
+	
+	return returnValue;
+}
+
+void writeToDebugLog(char *titre, char *error){
+	if (debug == 1){
+		FILE *fic;
+		//ouverture du fichier
+		char* debug_file_path = malloc(strlen(current_directory) + strlen("engine.log") + 2);
+		sprintf(debug_file_path, "%s%sengine.log", current_directory, separator);
+		fic = fopen(debug_file_path, "a"); //"w"  : mode texte en �criture (cr�ation)
+		char resultat[MAX_PATH];
+		strcpy(resultat, titre);
+		strcat(resultat, error);
+		strcat(resultat, "\n");
+		//recuperation du pid
+		fprintf(fic, "%s", resultat);
+		fclose(fic); 
+	}
+}
+
+void writeToErrorLog(char *titre, char *error){
+	FILE *fic;
+	//ouverture du fichier
+	char* error_file_path = malloc(strlen(current_directory) + strlen("engine_error.log") + 2);
+	sprintf(error_file_path, "%s%sengine_error.log", current_directory, separator);
+	fic = fopen(error_file_path, "a"); //"w"  : mode texte en �criture (cr�ation)
+	char resultat[MAX_PATH];
+	strcpy(resultat, titre);
+	strcat(resultat, error);
+	strcat(resultat, "\n");
+	//recuperation du pid
+	fprintf(fic, "%s", resultat);
+	fclose(fic);
+}
+
+char *verifyRegexp (char *str_request, char *str_regex){
+	char *returnValue = "error";
+	int err;
+	regex_t preg;
+	err = regcomp (&preg, str_regex, REG_EXTENDED);
+	if (err == 0){
+		int match;
+		size_t nmatch = 0;
+		regmatch_t *pmatch = NULL;
+		nmatch = preg.re_nsub;
+		pmatch = malloc (sizeof (*pmatch) * nmatch);
+		if (pmatch){
+			match = regexec (&preg, str_request, nmatch, pmatch, 0);
+			regfree (&preg);
+			if (match == 0){
+				char *site = NULL;
+				int start = pmatch[0].rm_so;
+				int end = pmatch[0].rm_eo;
+				size_t size = end - start;
+				site = malloc (sizeof (*site) * (size + 1));
+				if (site){
+				   strncpy (site, &str_request[start], size);
+				   site[size] = '\0';
+				   returnValue = site;
+				   free (site);
+				}
+			}else if (match == REG_NOMATCH){
+				returnValue = "error";
+			}else{
+				char *text;
+				size_t size;
+				size = regerror (err, &preg, NULL, 0);
+				text = malloc (sizeof (*text) * size);
+				if (text){
+				   regerror (err, &preg, text, size);
+				   returnValue = text;
+				   free (text);
+				}else{
+				   returnValue = "error";
+				}
+			}
+		}else{
+			 returnValue = "error";
+		}	
+	}else{
+		returnValue = "error";
+	}
+	
+	return returnValue;
+}
+
+void copie(char srce[] , char dest[]) { 
+  register int i;     /* un indice est necessaire */
+  for( i=0 ; (dest[i] = srce[i]) != 0 ; i++) 
+     ;
+}
+
+int makeInt(const char *p, int size){
+    const char *endp;
+    int intval = 0;
+    endp = p + size;
+    while (p < endp){
+        intval = intval * 10 + *p - '0';
+        p++;
+    }
+    return intval;
+}
diff --git a/gtf.engine/engine/engine.h b/gtf.engine/engine/engine.h
new file mode 100755
index 00000000..88fa8fbd
--- /dev/null
+++ b/gtf.engine/engine/engine.h
@@ -0,0 +1,11 @@
+int execRobot(char *pid_file_path, char *motor_number);
+void getWritePid(char *pid_file_path);
+int verifyProcess(int num_pid);
+int findPidFile(char *pid_file_path);
+void copie(char srce[] , char dest[]);
+void writeToDebugLog(char *titre, char *error);
+void writeToErrorLog(char *titre, char *error);
+char *RemplacerFragment(char *source, char *vieux, char *nouveau);
+char *verifyRegexp(char *str_request, char *str_regex);
+char *verifyLicense(char *motor_number);
+int makeInt(const char *,int);
\ No newline at end of file
diff --git a/gtf.engine/engine/php.ini b/gtf.engine/engine/php.ini
new file mode 100755
index 00000000..982525bc
--- /dev/null
+++ b/gtf.engine/engine/php.ini
@@ -0,0 +1,162 @@
+[PHP]
+engine = On
+short_open_tag = Off
+asp_tags = Off
+precision = 14
+output_buffering = 4096
+zlib.output_compression = Off
+implicit_flush = Off
+unserialize_callback_func =
+serialize_precision = 17
+disable_functions =
+disable_classes =
+zend.enable_gc = On
+expose_php = On
+max_execution_time = 30
+max_input_time = 60
+memory_limit = 128M
+error_reporting = E_ALL & ~E_NOTICE 
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+log_errors_max_len = 1024
+ignore_repeated_errors = Off
+ignore_repeated_source = Off
+report_memleaks = On
+track_errors = Off
+html_errors = On
+error_log = php.log
+variables_order = "GPCS"
+request_order = "GP"
+register_argc_argv = Off
+auto_globals_jit = On
+post_max_size = 8M
+auto_prepend_file =
+auto_append_file =
+default_mimetype = "text/html"
+include_path = ".;"
+doc_root =
+user_dir =
+ extension_dir = "ext"
+enable_dl = Off
+file_uploads = On
+upload_max_filesize = 2M
+max_file_uploads = 20
+allow_url_fopen = On
+allow_url_include = Off
+default_socket_timeout = 60
+extension=php_curl.dll
+extension=php_gd2.dll
+extension=php_ldap.dll
+extension=php_mbstring.dll
+extension=php_openssl.dll
+extension=php_pdo_pgsql.dll
+extension=php_xsl.dll
+[CLI Server]
+cli_server.color = On
+[Date]
+date.timezone = "EUROPE/Paris"
+[Pdo_mysql]
+pdo_mysql.cache_size = 2000
+pdo_mysql.default_socket=
+[mail function]
+SMTP = localhost
+smtp_port = 25
+mail.add_x_header = On
+[SQL]
+sql.safe_mode = Off
+[ODBC]
+odbc.allow_persistent = On
+odbc.check_persistent = On
+odbc.max_persistent = -1
+odbc.max_links = -1
+odbc.defaultlrl = 4096
+odbc.defaultbinmode = 1
+[Interbase]
+ibase.allow_persistent = 1
+ibase.max_persistent = -1
+ibase.max_links = -1
+ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
+ibase.dateformat = "%Y-%m-%d"
+ibase.timeformat = "%H:%M:%S"
+[MySQL]
+mysql.allow_local_infile = On
+mysql.allow_persistent = On
+mysql.cache_size = 2000
+mysql.max_persistent = -1
+mysql.max_links = -1
+mysql.default_port =
+mysql.default_socket =
+mysql.default_host =
+mysql.default_user =
+mysql.default_password =
+mysql.connect_timeout = 60
+mysql.trace_mode = Off
+[MySQLi]
+mysqli.max_persistent = -1
+mysqli.allow_persistent = On
+mysqli.max_links = -1
+mysqli.cache_size = 2000
+mysqli.default_port = 3306
+mysqli.default_socket =
+mysqli.default_host =
+mysqli.default_user =
+mysqli.default_pw =
+mysqli.reconnect = Off
+[mysqlnd]
+mysqlnd.collect_statistics = On
+mysqlnd.collect_memory_statistics = Off
+[PostgreSQL]
+pgsql.allow_persistent = On
+pgsql.auto_reset_persistent = Off
+pgsql.max_persistent = -1
+pgsql.max_links = -1
+pgsql.ignore_notice = 0
+pgsql.log_notice = 0
+[Sybase-CT]
+sybct.allow_persistent = On
+sybct.max_persistent = -1
+sybct.max_links = -1
+sybct.min_server_severity = 10
+sybct.min_client_severity = 10
+[bcmath]
+bcmath.scale = 0
+[Session]
+session.save_handler = files
+session.use_strict_mode = 0
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.name = PHPSESSID
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_path = /
+session.cookie_domain =
+session.cookie_httponly =
+session.serialize_handler = php
+session.gc_probability = 1
+session.gc_divisor = 1000
+session.gc_maxlifetime = 1440
+session.referer_check =
+session.cache_limiter = nocache
+session.cache_expire = 180
+session.use_trans_sid = 0
+session.hash_function = 0
+session.hash_bits_per_character = 5
+url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
+[MSSQL]
+mssql.allow_persistent = On
+mssql.max_persistent = -1
+mssql.max_links = -1
+mssql.min_error_severity = 10
+mssql.min_message_severity = 10
+mssql.compatibility_mode = Off
+mssql.secure_connection = Off
+[Tidy]
+tidy.clean_output = Off
+[soap]
+soap.wsdl_cache_enabled=1
+soap.wsdl_cache_dir="/tmp"
+soap.wsdl_cache_ttl=86400
+soap.wsdl_cache_limit = 5
+[ldap]
+ldap.max_links = -1
diff --git a/gtf.engine/engine/sha1.c b/gtf.engine/engine/sha1.c
new file mode 100755
index 00000000..d87c7f48
--- /dev/null
+++ b/gtf.engine/engine/sha1.c
@@ -0,0 +1,371 @@
+/*
+ *  sha1.c
+ *
+ *  Copyright (C) 1998, 2009
+ *  Paul E. Jones <paulej@packetizer.com>
+ *  All Rights Reserved
+ *
+ *****************************************************************************
+ *  $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
+ *****************************************************************************
+ *
+ *  Description:
+ *      This file implements the Secure Hashing Standard as defined
+ *      in FIPS PUB 180-1 published April 17, 1995.
+ *
+ *      The Secure Hashing Standard, which uses the Secure Hashing
+ *      Algorithm (SHA), produces a 160-bit message digest for a
+ *      given data stream.  In theory, it is highly improbable that
+ *      two messages will produce the same message digest.  Therefore,
+ *      this algorithm can serve as a means of providing a "fingerprint"
+ *      for a message.
+ *
+ *  Portability Issues:
+ *      SHA-1 is defined in terms of 32-bit "words".  This code was
+ *      written with the expectation that the processor has at least
+ *      a 32-bit machine word size.  If the machine word size is larger,
+ *      the code should still function properly.  One caveat to that
+ *      is that the input functions taking characters and character
+ *      arrays assume that only 8 bits of information are stored in each
+ *      character.
+ *
+ *  Caveats:
+ *      SHA-1 is designed to work with messages less than 2^64 bits
+ *      long. Although SHA-1 allows a message digest to be generated for
+ *      messages of any number of bits less than 2^64, this
+ *      implementation only works with messages with a length that is a
+ *      multiple of the size of an 8-bit character.
+ *
+ */
+
+#include "sha1.h"
+
+/*
+ *  Define the circular shift macro
+ */
+#define SHA1CircularShift(bits,word) \
+                ((((word) << (bits)) & 0xFFFFFFFF) | \
+                ((word) >> (32-(bits))))
+
+/* Function prototypes */
+void SHA1ProcessMessageBlock(SHA1Context *);
+void SHA1PadMessage(SHA1Context *);
+
+/*  
+ *  SHA1Reset
+ *
+ *  Description:
+ *      This function will initialize the SHA1Context in preparation
+ *      for computing a new message digest.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to reset.
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1Reset(SHA1Context *context)
+{
+    context->Length_Low             = 0;
+    context->Length_High            = 0;
+    context->Message_Block_Index    = 0;
+
+    context->Message_Digest[0]      = 0x67452301;
+    context->Message_Digest[1]      = 0xEFCDAB89;
+    context->Message_Digest[2]      = 0x98BADCFE;
+    context->Message_Digest[3]      = 0x10325476;
+    context->Message_Digest[4]      = 0xC3D2E1F0;
+
+    context->Computed   = 0;
+    context->Corrupted  = 0;
+}
+
+/*  
+ *  SHA1Result
+ *
+ *  Description:
+ *      This function will return the 160-bit message digest into the
+ *      Message_Digest array within the SHA1Context provided
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to use to calculate the SHA-1 hash.
+ *
+ *  Returns:
+ *      1 if successful, 0 if it failed.
+ *
+ *  Comments:
+ *
+ */
+int SHA1Result(SHA1Context *context)
+{
+
+    if (context->Corrupted)
+    {
+        return 0;
+    }
+
+    if (!context->Computed)
+    {
+        SHA1PadMessage(context);
+        context->Computed = 1;
+    }
+
+    return 1;
+}
+
+/*  
+ *  SHA1Input
+ *
+ *  Description:
+ *      This function accepts an array of octets as the next portion of
+ *      the message.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The SHA-1 context to update
+ *      message_array: [in]
+ *          An array of characters representing the next portion of the
+ *          message.
+ *      length: [in]
+ *          The length of the message in message_array
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1Input(     SHA1Context         *context,
+                    const unsigned char *message_array,
+                    unsigned            length)
+{
+    if (!length)
+    {
+        return;
+    }
+
+    if (context->Computed || context->Corrupted)
+    {
+        context->Corrupted = 1;
+        return;
+    }
+
+    while(length-- && !context->Corrupted)
+    {
+        context->Message_Block[context->Message_Block_Index++] =
+                                                (*message_array & 0xFF);
+
+        context->Length_Low += 8;
+        /* Force it to 32 bits */
+        context->Length_Low &= 0xFFFFFFFF;
+        if (context->Length_Low == 0)
+        {
+            context->Length_High++;
+            /* Force it to 32 bits */
+            context->Length_High &= 0xFFFFFFFF;
+            if (context->Length_High == 0)
+            {
+                /* Message is too long */
+                context->Corrupted = 1;
+            }
+        }
+
+        if (context->Message_Block_Index == 64)
+        {
+            SHA1ProcessMessageBlock(context);
+        }
+
+        message_array++;
+    }
+}
+
+/*  
+ *  SHA1ProcessMessageBlock
+ *
+ *  Description:
+ *      This function will process the next 512 bits of the message
+ *      stored in the Message_Block array.
+ *
+ *  Parameters:
+ *      None.
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *      Many of the variable names in the SHAContext, especially the
+ *      single character names, were used because those were the names
+ *      used in the publication.
+ *         
+ *
+ */
+void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+    const unsigned K[] =            /* Constants defined in SHA-1   */      
+    {
+        0x5A827999,
+        0x6ED9EBA1,
+        0x8F1BBCDC,
+        0xCA62C1D6
+    };
+    int         t;                  /* Loop counter                 */
+    unsigned    temp;               /* Temporary word value         */
+    unsigned    W[80];              /* Word sequence                */
+    unsigned    A, B, C, D, E;      /* Word buffers                 */
+
+    /*
+     *  Initialize the first 16 words in the array W
+     */
+    for(t = 0; t < 16; t++)
+    {
+        W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
+        W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
+    }
+
+    for(t = 16; t < 80; t++)
+    {
+       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+    }
+
+    A = context->Message_Digest[0];
+    B = context->Message_Digest[1];
+    C = context->Message_Digest[2];
+    D = context->Message_Digest[3];
+    E = context->Message_Digest[4];
+
+    for(t = 0; t < 20; t++)
+    {
+        temp =  SHA1CircularShift(5,A) +
+                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 20; t < 40; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 40; t < 60; t++)
+    {
+        temp = SHA1CircularShift(5,A) +
+               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 60; t < 80; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+        temp &= 0xFFFFFFFF;
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    context->Message_Digest[0] =
+                        (context->Message_Digest[0] + A) & 0xFFFFFFFF;
+    context->Message_Digest[1] =
+                        (context->Message_Digest[1] + B) & 0xFFFFFFFF;
+    context->Message_Digest[2] =
+                        (context->Message_Digest[2] + C) & 0xFFFFFFFF;
+    context->Message_Digest[3] =
+                        (context->Message_Digest[3] + D) & 0xFFFFFFFF;
+    context->Message_Digest[4] =
+                        (context->Message_Digest[4] + E) & 0xFFFFFFFF;
+
+    context->Message_Block_Index = 0;
+}
+
+/*  
+ *  SHA1PadMessage
+ *
+ *  Description:
+ *      According to the standard, the message must be padded to an even
+ *      512 bits.  The first padding bit must be a '1'.  The last 64
+ *      bits represent the length of the original message.  All bits in
+ *      between should be 0.  This function will pad the message
+ *      according to those rules by filling the Message_Block array
+ *      accordingly.  It will also call SHA1ProcessMessageBlock()
+ *      appropriately.  When it returns, it can be assumed that the
+ *      message digest has been computed.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to pad
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+ *
+ */
+void SHA1PadMessage(SHA1Context *context)
+{
+    /*
+     *  Check to see if the current message block is too small to hold
+     *  the initial padding bits and length.  If so, we will pad the
+     *  block, process it, and then continue padding into a second
+     *  block.
+     */
+    if (context->Message_Block_Index > 55)
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 64)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+
+        SHA1ProcessMessageBlock(context);
+
+        while(context->Message_Block_Index < 56)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+    else
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 56)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+
+    /*
+     *  Store the message length as the last 8 octets
+     */
+    context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
+    context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
+    context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
+    context->Message_Block[59] = (context->Length_High) & 0xFF;
+    context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
+    context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
+    context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
+    context->Message_Block[63] = (context->Length_Low) & 0xFF;
+
+    SHA1ProcessMessageBlock(context);
+}
diff --git a/gtf.engine/engine/sha1.h b/gtf.engine/engine/sha1.h
new file mode 100755
index 00000000..1ca4b104
--- /dev/null
+++ b/gtf.engine/engine/sha1.h
@@ -0,0 +1,54 @@
+/*
+ *  sha1.h
+ *
+ *  Copyright (C) 1998, 2009
+ *  Paul E. Jones <paulej@packetizer.com>
+ *  All Rights Reserved
+ *
+ *****************************************************************************
+ *  $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
+ *****************************************************************************
+ *
+ *  Description:
+ *      This class implements the Secure Hashing Standard as defined
+ *      in FIPS PUB 180-1 published April 17, 1995.
+ *
+ *      Many of the variable names in the SHA1Context, especially the
+ *      single character names, were used because those were the names
+ *      used in the publication.
+ *
+ *      Please read the file sha1.c for more information.
+ *
+ */
+
+#ifndef _SHA1_H_
+#define _SHA1_H_
+
+/* 
+ *  This structure will hold context information for the hashing
+ *  operation
+ */
+typedef struct SHA1Context
+{
+    unsigned Message_Digest[5]; /* Message Digest (output)          */
+
+    unsigned Length_Low;        /* Message length in bits           */
+    unsigned Length_High;       /* Message length in bits           */
+
+    unsigned char Message_Block[64]; /* 512-bit message blocks      */
+    int Message_Block_Index;    /* Index into message block array   */
+
+    int Computed;               /* Is the digest computed?          */
+    int Corrupted;              /* Is the message digest corruped?  */
+} SHA1Context;
+
+/*
+ *  Function Prototypes
+ */
+void SHA1Reset(SHA1Context *);
+int SHA1Result(SHA1Context *);
+void SHA1Input( SHA1Context *,
+                const unsigned char *,
+                unsigned);
+
+#endif
diff --git a/gtf.engine/gtf.engines/Changelog.txt b/gtf.engine/gtf.engines/Changelog.txt
new file mode 100755
index 00000000..34a7e1fc
--- /dev/null
+++ b/gtf.engine/gtf.engines/Changelog.txt
@@ -0,0 +1 @@
+2194 
diff --git a/gtf.engine/gtf.engines/Traitement.class.inc b/gtf.engine/gtf.engines/Traitement.class.inc
new file mode 100755
index 00000000..1a5c2f39
--- /dev/null
+++ b/gtf.engine/gtf.engines/Traitement.class.inc
@@ -0,0 +1,781 @@
+<?php
+
+/**
+ * \file Traitement.class.inc
+ * \brief Traitement.class.inc \n \n Ce fichier contient la classe php Traitement.
+ *
+ * Cette classe virtuelle permet de générer les éléments nécessaires à la création d'un rapport ou
+ * à l'éxécution d'un traitement FME.
+ *
+ * Cette classe permet de générer des fichiers textes, csv ou d'images pour la création de rapport.
+ * Elle permet aussi de lancer la création d'un rapport ou l'éxécution d'un traitement FME.
+ *
+ * \author Fabien Marty <fabien.marty@veremes.com>
+ * \update Matthieu Ambrosy <matthieu.ambrosy@veremes.com>
+ */
+require_once ("vmlib/phpUtil.inc");
+require_once ("vmlib/logUtil.inc");
+require_once ("vmlib/stringUtil.inc");
+require_once ("gtf_lib/GtfFmwParser.class.inc");
+require_once 'string.inc';
+
+class Traitement {
+
+    //Variable stockant l'url du log FME
+    var $sLogFme = "";
+
+    /**
+     * Identifiant de la demande.
+     */
+    var $iDemandeId;
+
+    /**
+     * Fichier de log.
+     */
+    var $sRobotLogFile;
+
+    /**
+     * Objet de la classe Bd. Connexion à la base de données
+     */
+    var $oBd;
+
+    /**
+     * Boolean spécifiant si le traitement est en erreur ou pas.
+     */
+    var $bErreur = false;
+
+    /**
+     * Boolean spécifiant si FME a subit un crash.
+     */
+    var $bFmeCrash = false;
+
+    /**
+     * Message d'erreur.
+     */
+    var $sMessageErreur;
+
+    /**
+     * Tableau des paramètres
+     */
+    var $aParametre;
+
+    /**
+     * Chaine contenant les parametres
+     */
+    var $sParams;
+
+    /**
+     * Emplacement du fichier projet FMW
+     */
+    var $sFmwFileName;
+
+    /**
+     * Tableau des propriétés provenant du fichier properties_robot.inc
+     */
+    var $aProperties;
+
+    /**
+     * Tableau des extensions associées à une source de données GUI
+     */
+    var $aExtension;
+    var $sDestination;
+    var $sSource;
+    var $sSourceTemp = "";
+
+    /**
+     * Cette méthode permet d'initialiser les variables.
+     * \param $oBd Connexion à la base de données.
+     * \param $iDemandeId Identifiant de la demande.
+     * \param $sRobotLogFile Fichier de log.
+     */
+    function __construct($oBd, $iDemandeId, $sRobotLogFile, $sParams, $aProperties, $sFmwFileName) {
+        $this->oBd = $oBd;
+        $this->iDemandeId = $iDemandeId;
+        $this->sRobotLogFile = $sRobotLogFile;
+        $this->sFmwFileName = $sFmwFileName;
+        $this->aParametre = $this->dbParamsAsArray($sParams);
+        $this->sParams = $sParams;
+        $this->aProperties = $aProperties;
+        // table de correspondance entre GTF et le FMW utiliser dans les fonction d'encodage 
+        $this->aReplaceGTF = array("\r\n", " ", "(", ")", "$", "&", "@", "°", "'", ",", "\"", "{", "}", "[", "]", ";", "/", "\\", "é", "à");
+        $this->aReplaceFME = array("<lf>", "<space>", "<openparen>", "<closeparen>", "<dollar>", "<amp>", "<at>", "<u00b0>", "<apos>", "<comma>", "<quote>", "<opencurly>", "<closecurly>", "<openbracket>", "<closebracket>", "<semicolon>", "<solidus>", "<backslash>", "<u00e9>", "<u00e0>");
+
+        writeToLog(str_replace('[this->sFmwFileName]', $this->sFmwFileName, str_replace('[sParams]', $sParams, INFO_RESOURCES)), $this->sRobotLogFile);
+    }
+
+    /*
+     * Initialisation du traitement.
+     * \param $oBd Connexion à la base de données.
+     * \param $iDemandeId Identifiant de la demande.
+     * \param $sLogFile Fichier de log.
+     * \param $sParams Liste des paramètres saisis par l'utilisateur à la création de la demande.
+     * \param $aProperties Tableau des properties associés à l'application
+     * \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.
+     * \return un tableau contenant les paramètres.
+     */
+    function dbParamsAsArray($sAllParams) {
+        $aAllParams = Array();
+        $aLigne = explode("|", $sAllParams);
+        //$aLigne = stringExplode($sAllParams, "|", "\"", "\"");
+        foreach ($aLigne as $sValeur) {
+            $aValeurs = explode("=", $sValeur, 2);
+            if ($aValeurs[1] == "") {
+                writeToLog(INFO_NULL_ELEMENT . $aValeurs[0] . ".", $this->sRobotLogFile);
+            }
+            if (!empty($aValeurs[2])) {
+                $sTemp = $aValeurs[1] . "=" . $aValeurs[2];
+                $aValeurs[1] = $sTemp;
+            }
+            $aAllParams[$aValeurs[0]] = $aValeurs[1];
+            writeToLog(str_replace('[aValeurs[0]]', $aValeurs[0], INFO_DB_PARAM) . $aValeurs[1], $this->sRobotLogFile);
+        }
+        return $aAllParams;
+    }
+
+    /**
+     * Cette méthode permet d'éxécuter une ligne de commande et de stocker les paramètres dans un fichier
+     * \param $sCommand Ligne de commande à éxécuter.
+     */
+    function execute($sCommand, $sFMELogFile) {
+        $sExeName = "FME";
+        if (!$this->bErreur) {
+            set_time_limit(0);
+            //$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);
+            //writeToLog(INFO_INFORM.$sExeName."| ".$sResultCommande, $this->sRobotLogFile);
+            // $sResultCommande = exec('"'.$this->aProperties["fme_path"].'" APPLY_SETTINGS "Python/Python Interpreter" "C:/apps/FME-2015.1-b15477-32/fmepython27/python27.dll"', $aResult, $iResult);
+            // writeToLog(INFO_INFORM.$sExeName."| APPLY_SETTINGS \"Python/Python Interpreter\" \"C:/apps/FME-2015.1-b15477-32/fmepython27\"", $this->sRobotLogFile);
+            // writeToLog(INFO_INFORM.$sExeName."| ".$sResultCommande, $this->sRobotLogFile);
+            $sResultCommande = exec($sCommand, $aResult, $iResult);
+            if ($sResultCommande == "") {
+                $aResultCommande[0] = true;
+            } else {
+                $aResultCommande = explode("|", $sResultCommande);
+            }
+            //Récupération d'une erreur.
+			if ($iResult !=0){
+            //if ($iResult || ($aResultCommande[0] != 0)) {
+                $this->bErreur = true;
+                if (sizeOf($aResultCommande) == 1)
+                    $this->bFmeCrash = false;
+            }
+            //Écriture dans le log
+            if ($this->bErreur) {
+                if (!empty($aResultCommande[1])) {
+                    if ($this->aProperties["convert_utf8"]) {
+                        $aResultCommande[1] = utf8_decode($aResultCommande[1]);
+                    }
+                    $this->sMessageErreur = "Erreur lors de l exécution de la commande." . $aResultCommande[1] . ".";
+                } 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;
+				}
+                foreach ($aResult as $sValeur) {
+                    writeToLog(INFO_ERROR . "   " . "| " . $sValeur, $this->sRobotLogFile);
+					if ($bExistFMELogFile === false){
+						$monfichier = fopen($sFMELogFile, 'a');
+						fputs($monfichier, $sValeur. "\n");
+						fclose($monfichier);
+					}
+                }
+                writeToLog(INFO_COMMAND_ERROR . $sCommand . ".", $this->sRobotLogFile);
+            } else {
+                foreach ($aResult as $sValeur) {
+                    if (mb_detect_encoding($sValeur, "UTF-8, ISO-8859-1") != "UTF-8") {
+                        $sValeur = iconv("ISO-8859-1", "UTF-8", $sValeur);
+                    }
+                    writeToLog(INFO_INFORM . $sExeName . "| " . $sValeur, $this->sRobotLogFile);
+                }
+                writeToLog(INFO_SUCCESSFUL_TREATMENT, $this->sRobotLogFile);
+            }
+        }
+    }
+
+    /**
+     * Cette méthode permet de 7zipper des fichiers.
+     * \param $sZipDir Emplacement des fichiers à zipper.
+     * \param $sZipUrl URL du fichier zip.
+     * \param $sZipFileName Nom du fichier zip à compresser.
+     * \return L'url du fichier zip.
+     */
+    function zipFile($sZipDir, $sZipFileDir, $sZipUrl, $sZipFileName) {
+        writeToLog(str_replace('[sZipDir]', $sZipDir, INFO_FILE_COMPRESSION), $this->sRobotLogFile);
+        if (createZip($sZipDir, $sZipFileDir . '/' . $sZipFileName . '.zip', 'log')) {
+            $sZipFile = $sZipUrl . "/" . $sZipFileName . ".zip";
+            writeToLog(INFO_COMPRESSED_FILES . $sZipFile . ".", $this->sRobotLogFile);
+        } else {
+            $this->bErreur = true;
+            $sZipFile = "";
+            writeToLog(INFO_TREATMENT_FAILURE, $this->sRobotLogFile);
+            writeToLog(str_replace('[sZipFileDir]', $sZipFileDir, str_replace('[sZipDir]', $sZipDir, INFO_FILES_COMPRESSION_FAILURE)) . $sZipFileName, $this->sRobotLogFile);
+            $this->sMessageErreur = "Le traitement n\'a produit aucun résultat. Consultez son log.";
+        }
+        return $sZipFile;
+    }
+
+    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
+        $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;
+
+        // If faut gérer l'ensemble des zip (.zip, .7z, .rar, bzip2, gzip, tar, wim, xz)
+        if (mb_eregi("(.ZIP)$", strtoupper($sParam), $aOccurence)) {
+            // Décompression du fichier zip.
+            $sDir = $this->unZipFile($sParam);
+        } else { // Le fichier uploadé n'est pas un fichier zippé
+            $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;
+    }
+
+    /**
+     * Cette méthode permet de dézipper un fichier.
+     * \param $sZipFile Le fichier zip à décompresser.
+     * \return L'emplacement des fichiers qui ont été extraits.
+     */
+    function unZipFile($sZipFile) {
+        if (!$this->bErreur) {
+            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() . "/";
+            $this->sSourceTemp = $sExtractDir;
+            if (unZip($sZipFile, $sExtractDir)) {
+                writeToLog(INFO_FILE_COMPRESSION_DIRECTORY . $sExtractDir . ".", $this->sRobotLogFile);
+            } else {
+                $this->bErreur = true;
+                writeToLog(INFO_TREATMENT_FAILURE, $this->sRobotLogFile);
+                writeToLog(str_replace('[sZipFile]', $sZipFile, INFO_FILE_COMPRESSION_FAILURE) . $sExtractDir . ".", $this->sRobotLogFile);
+                $this->sMessageErreur = "Impossible de dézipper le fichier. Consultez le log du robot.";
+                $sExtractDir = "";
+            }
+            return $sExtractDir;
+        }
+    }
+
+    /*
+     * Fonction qui se charge de la mise à jour du paramètre "source" s'il existe
+     * $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
+     */
+
+    function updateSourceParam($oGui, $oGtfFmwParser, $sDirSource, $bUsePattern) {
+        $sdelimiterFichier = '"""';
+        $sdelimiterParam = '"';
+        $sSourceMacro = $sdelimiterFichier;
+		$aSourceMacro = array();
+        $i = 0;
+
+        if (is_dir($sDirSource)) {
+            $this->aExtension = $oGui->getExtensionArrayNoLower($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;
+            } else {
+				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) {
+								if ($i != 0)
+									$sSourceMacro.= "<space>";
+								writeToLog(INFO_VALID_DATA_SOURCE_FILE_EXTENSION . $sExtension, $this->sRobotLogFile);
+								$sSourceMacro.= $sdelimiterParam . $sDirSource . '/**/' . $sExtension . $sdelimiterParam;
+								$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) {
+						if ($sSourceMacro != $sdelimiterFichier){
+							$sSourceMacro.= "<space>";
+						}
+						$sSourceMacro.= $sdelimiterParam . $source . $sdelimiterParam;
+					}
+                }
+            }
+        }else {
+            $sSourceMacro.= $sdelimiterParam . $sDirSource . $sdelimiterParam;
+        }
+        $sSourceMacro .= $sdelimiterFichier;
+        $this->aParametre[$oGui->sDefault_Macro] = $sSourceMacro;
+		
+        return $sSourceMacro;
+    }
+
+    // Compte le nombre de fichier
+    // $sDirSource : Répertoire de base
+    // $sExtension : Filtre
+    function countFilesExtension($sDirSource, $sExtension) {
+        $num = 0;
+        if (!is_dir($sDirSource)) {
+            $path_parts = pathinfo($sDirSource);
+            if (is_file($sDirSource) && $path_parts['extension'] == $sExtension)
+                return 1;
+            else
+                return false;
+        }
+        foreach (scandir($sDirSource) AS $entry) {
+            if (!in_array($entry, array('..', '.')))
+                $num += $this->countFilesExtension($sDirSource . "/" . $entry, $sExtension);
+        }
+        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
+     * $oGui : Objet GUI de la source
+     * $sDirSource : Chaine de caractère contenant le chemin d'accés à la source de données
+     */
+
+    function updateDestParam($oGui, $oGtfFmwParser, $sNewDir, $sDest) {
+        $this->aExtension = $oGui->getExtensionArray($oGui->sFiltreDest);
+        if ($sDest == "" && $oGui->sType != "DIRNAME") {
+            $sDest = $sNewDir;
+        }
+        $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;
+            writeToLog(INFO_OUTPUT_DATA_DIRECTORY . $this->aParametre[$oGui->sDefault_Macro], $this->sRobotLogFile);
+        }
+        if ($oGui->sType == "FILENAME") {
+            if (count($aDest) > 1) { // Dans GTF, la valeur du champ [nom de fichier en sortie] comporte une extension. Ex : result.xls (le fichier résultat sera de l'excel et sera nommé result.
+                $sResult = $sDest;
+            } else {
+                $sResult = str_replace("*", $sDest, $this->aExtension[0]);
+            }
+            $this->aParametre[$oGui->sDefault_Macro].= $this->aProperties["dir_export"] . "/gtf/" . $sNewDir . '/' . $sResult;
+            $this->sDestination = $sResult;
+
+            writeToLog(INFO_OUTPUT_DATA_FILE . $this->aParametre[$oGui->sDefault_Macro], $this->sRobotLogFile);
+        }
+        else if ($oGui->sType == "FILENAME_EXISTING")
+            $this->aParametre[$oGui->sDefault_Macro] = $sDest;
+        return $this->aParametre[$oGtfFmwParser->sDestMacro];
+    }
+
+    /*     * *************************************************************************************** */
+    /*                                          Codage                                        */
+
+    function unichr($u) {
+        return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
+    }
+
+    function ordutf8($string, &$offset) {
+        $code = ord(substr($string, $offset, 1));
+        if ($code >= 128) {        //otherwise 0xxxxxxx
+            if ($code < 224)
+                $bytesnumber = 2;                //110xxxxx
+            else if ($code < 240)
+                $bytesnumber = 3;        //1110xxxx
+            else if ($code < 248)
+                $bytesnumber = 4;    //11110xxx
+            $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0);
+            for ($i = 2; $i <= $bytesnumber; $i++) {
+                $offset ++;
+                $code2 = ord(substr($string, $offset, 1)) - 128;        //10xxxxxx
+                $codetemp = $codetemp * 64 + $code2;
+            }
+            $code = $codetemp;
+        }
+        $offset += 1;
+        if ($offset >= strlen($string))
+            $offset = -1;
+        return $code;
+    }
+
+    function encoderFME($sStr) {
+        //table de correcpondance des symboles UTF-8 avec les codes FME/GTF
+        // ATTENTION : laisser < > en premier sinon replace remplace les balises par d'autre balise
+        $aReplaceGTFToFMW = array("<" => "<lt>", ">" => "<gt>");
+        $sReplaced = $sStr;
+
+        //on gere les chevrons simultanèment pour ne pas gener l'encodage après
+        if (strpos($sReplaced, "<") !== false && strpos($sReplaced, ">") !== false) {
+            $sReplaced = strtr($sReplaced, $aReplaceGTFToFMW);
+        }
+
+        //on remplace tous les encodage par leurs symboles
+        for ($i = 0; $i < count($this->aReplaceGTF); $i++) {
+            if (strpos($sReplaced, $this->aReplaceGTF[$i]) !== false) {
+                $sReplaced = str_replace($this->aReplaceGTF[$i], $this->aReplaceFME[$i], $sReplaced);
+            }
+        }
+
+        // on encode les balises UTF-8 		
+
+        $offset = 0;
+        $iPos = 0;
+
+        while ($offset >= 0) {
+            $iCode = $this->ordutf8($sReplaced, $offset);
+            if ($iCode > 127) {
+                $cLetter = dechex($iCode);
+                while (strlen($sLetter) < 4) {
+                    $cLetter = "0" . $cLetter;
+                }
+                $sReplaced = str_replace($sReplaced[$iPos], "<u" . $cLetter . ">", $sReplaced);
+            }
+            $iPos += 1;
+        }
+
+        return $sReplaced;
+    }
+
+    function decoderFME($sStr) {
+        //table de correcpondance des symboles UTF-8 avec les codes FME/GTF
+        // ATTENTION : laisser < > en premier sinon replace remplace les balises par d'autre balise
+        $aReplaceFMWToGTF = array("<lt>" => "<", "<gt>" => ">");
+        $sReplaced = $sStr;
+
+        //on gere les chevrons simultanèment pour ne pas gener l'encodage après
+        if (strpos($sReplaced, "<lt>") !== false && strpos($sReplaced, "<gt>") !== false) {
+            $sReplaced = strtr($sReplaced, $aReplaceFMWToGTF);
+        }
+        //on remplace tous les encodage par leurs symboles
+        for ($i = 0; $i < count($this->aReplaceGTF); $i++) {
+            if (strpos($sReplaced, $this->aReplaceFME[$i]) !== false) {
+                $sReplaced = str_replace($this->aReplaceFME[$i], $this->aReplaceGTF[$i], $sReplaced);
+            }
+        }
+
+        // on decode les balises UTF-8 		
+        $matches = array();
+
+        preg_match_all("/<u[0-9a-fA-F]{4}>/", $sStr, $matches);
+
+        for ($i = 0; $i < count($matches[0]); $i++) {
+            $iCode = hexdec(substr($matches[0][$i], 2, 4));
+            $cChr = $this->unichr($iCode);
+            $sReplaced = str_replace($matches[0][$i], $cChr, $sReplaced);
+        }
+        return $sReplaced;
+    }
+
+    function isDecode($sStr) {
+        for ($i = 0; $i < count($this->aReplaceFME); $i++) {
+            if (strpos($sStr, $this->aReplaceFME[$i]) !== false && strpos($sStr, $this->aReplaceGTF[$i]) === false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function isEncode($sStr) {
+        for ($i = 0; $i < count($this->aReplaceFME); $i++) {
+            if (strpos($sStr, $this->aReplaceFME[$i]) === false && strpos($sStr, $this->aReplaceGTF[$i]) !== false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*     * *************************************************************************************** */
+
+    /*
+     *  Fonction qui permet de concaténer tous les paramètres nécessaire pour l'appel du TCL
+     *  et qui retourne $sChaine, la chaine des paramètres à passer au TCL
+     *  $oGtfFmwParser : Objet GtfFmwParser contenant les GUI
+     */
+
+    function getTclParams($oGtfFmwParser, $sNewDir) {
+        $aTGui = array();
+        $sChaine = "";
+		$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>") {
+                    $sDirSource = $this->unZipSource($this->aParametre[$oGui->sDefault_Macro]);
+                    $this->updateSourceParam($oGui, $oGtfFmwParser, $sDirSource, $bUsePattern);
+                }
+            }
+            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;
+                }
+                // Echappement des doubles quotes pour FME.
+                $sGTFOutput = str_replace('"', '\"', $sGTFOutput);
+                //
+                $sChaine .= " --" . $oGui->sDefault_Macro . " \"" . $sGTFOutput . "\"";
+            }
+        }
+
+        // $sChaine = substr($sChaine, 0, -1)."\"";
+        //$sChaine = substr($sChaine, 0, -1);
+        return $sChaine;
+    }
+
+    function listDir($sDossier, $iDemandeId) {
+        $ouverture = @opendir($sDossier);
+        if (!$ouverture)
+            return false;
+        while ($sFichier = readdir($ouverture)) {
+            if ($sFichier == '.' || $sFichier == '..')
+                continue;
+            if (is_dir($sDossier . $sFichier)) {
+                closedir($ouverture);
+                return true;
+            } else {
+                $path_parts = pathinfo($sDossier . $sFichier);
+                if ($sFichier != "fme_" . $iDemandeId . ".log") {
+                    closedir($ouverture);
+                    return true;
+                }
+            }
+        }
+        closedir($ouverture);
+        return False;
+    }
+
+    /*
+     * 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);
+        $NbFile = 0;
+        while ($sFichier = readdir($ouverture)) {
+            if ($sFichier == '.' || $sFichier == '..')
+                continue;
+            if (is_dir($sDossier . $sFichier)) {
+                $NbFile = $NbFile + 2;
+            } else {
+                $path_parts = pathinfo($sDossier . $sFichier);
+                if ($sFichier != "fme_" . $iDemandeId . ".log") {
+                    $NbFile = $NbFile + 1;
+                }
+            }
+        }
+        closedir($ouverture);
+        $ouverture = @opendir($sDossier);
+        if ($NbFile != 1) {
+            return "";
+        } else {
+            $pattern = '/^' . str_replace("*", ".+", str_replace(".", "\\.", $this->aProperties['not_compressed_extension'])) . '$/';
+            while ($sFichier = readdir($ouverture)) {
+                if ($sFichier == '.' || $sFichier == '..')
+                    continue;
+                if ($sFichier != "fme_" . $iDemandeId . ".log") {
+                    if (preg_match($pattern, $sFichier)) {
+                        return $sNewDir . "/" . $sFichier;
+                    } else {
+                        return "";
+                    }
+                }
+            }
+        }
+        closedir($ouverture);
+    }
+
+    /*
+     * fonction qui lance la génération de la ligne de commande, l'éxécution de la demande et la mise en forme du résultat
+     * \return Retourne les fichiers résultant zippés
+     */
+
+    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;
+
+        //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);
+        if ($sTclParams != "")
+            $sCommandLine .= $sTclParams;
+
+		$aTGui = array();
+        $sChaine = "";
+		  // Ajout des paramètres GTF_ s'ils sont associés à un paramètre publié du traitement
+        foreach ($oGtfFmwParser->aGuiObject as $aGui) {
+			switch($aGui->sDefault_Macro) {
+				 case 'GTF_ORDER_ID':
+					$sCommandLine .= " --GTF_ORDER_ID \"" . $this->iDemandeId . "\"";
+					break;
+				 case 'GTF_SHARED_DIR':
+					$sCommandLine .= " --GTF_SHARED_DIR \"" . $this->aProperties["shared_dir"] . "\"";
+					break;
+				 case 'GTF_CONNECTION_STRING':
+					if ($aGui->sType == "PASSWORD"){
+						 $sCommandLine .= "  --GTF_CONNECTION_STRING \"" . $this->aProperties["server"] . "," . $this->aProperties["port"] . "," . $this->aProperties["database"] . "," . $this->aProperties["login_scheduler"] . "," . $this->aProperties["password_scheduler"] . "\"";
+					}
+					 break;
+				 case 'GTF_REST_URL':
+					 $sCommandLine .= "  --GTF_REST_URL \"" . $this->aProperties["web_server_name"] . "/" . $this->aProperties["services_alias"] . "/\"";
+					 break;
+				 //case 'GTF_FORCE_PATTERN':
+			}
+           
+        }
+        /*
+         * 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";
+        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";
+        $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");
+        writeToLog(INFO_TREATMENT_COMMAND_LINE . $sCommandLine, $this->sRobotLogFile);
+        if (file_exists($sDestDir . "/fme_" . $this->iDemandeId . ".log") == 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 = "";
+        }
+        return $sZipFile;
+    }
+
+}
+
+?>
diff --git a/gtf.engine/gtf.engines/constants.inc b/gtf.engine/gtf.engines/constants.inc
new file mode 100755
index 00000000..d4d3d5ab
--- /dev/null
+++ b/gtf.engine/gtf.engines/constants.inc
@@ -0,0 +1,10 @@
+<?php
+// Définition des constantes
+if (!defined("CR")) {
+	define ("CR",chr(13));
+	define ("LF",chr(10));
+	define ("HT",chr(9));
+}
+define ("VM_FALSE",0);
+define ("VM_TRUE",1);
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/engine b/gtf.engine/gtf.engines/engine
new file mode 100755
index 0000000000000000000000000000000000000000..53b01477108bf7e5f77ce52eb5b0c48c458e2dd6
GIT binary patch
literal 32888
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

literal 0
HcmV?d00001

diff --git a/gtf.engine/gtf.engines/engine.exe b/gtf.engine/gtf.engines/engine.exe
new file mode 100755
index 0000000000000000000000000000000000000000..299a2bc1ca56950134511a6694772126a6f3c03c
GIT binary patch
literal 75276
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
Zxaa`_8bM41^%TH9#F77@NgO)20RSHYV^{zH

literal 0
HcmV?d00001

diff --git a/gtf.engine/gtf.engines/engine.php b/gtf.engine/gtf.engines/engine.php
new file mode 100755
index 00000000..70a33d33
--- /dev/null
+++ b/gtf.engine/gtf.engines/engine.php
@@ -0,0 +1,787 @@
+<?php
+
+/**
+ * \file engine.php
+ * \brief engine.php \n \n Ce fichier contient un programme php.
+ *
+ * Ce programme permet de traiter des demandes de traitements.
+ *
+ * \author Fabien Marty <fabien.marty@veremes.com>
+ */
+$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
+
+require_once ("php_engine_conf.inc");
+require_once ("vmlib/BD.class.inc");
+require_once ("vmlib/logUtil.inc");
+require_once("vmlib/dbUtil.inc");
+require_once ("gtf_lib/phpUtility.inc");
+require_once("vmlib/phpUtil.inc");
+
+require_once ("properties_engine.inc");
+require_once ("engine.sql.inc");
+//require_once ("PEAR/Mail.php");
+require_once("Ldap.class.inc");
+
+require_once("vmlib/Email.class.inc");
+require_once("gtf_lib/gtf_object/Order.class.inc");
+require_once("vmlib/error.inc");
+require_once 'string.inc';
+
+loadLang("engines", $properties["language"]);
+if ($ErrorLicense == "0") {
+    //writeToLog('|INFO |PHP| dump prop '. var_export($properties,true),$properties["engine_log_file"]);
+
+    $sDateDebut = new DateTime(date("Y-m-d H:i:s"));
+    $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_scheduler'], $properties['password_scheduler'], $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"]);
+    if ($oBd->erreurRencontree) {
+        writeToLog(INFO_BASE_CONNECTION_ERROR . $properties["database"], $properties["engine_log_file"]);
+    } else {
+        writeToLog(INFO_BASE_CONNECTION . $properties["database"], $properties["engine_log_file"]);
+
+        //Recherche du Moteur V2 (ExecuteWithParams)
+        //Selection du chemin fme
+        $aParams = array();
+        $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
+        $aParams['gtf_engine_id'] = array('value' => $properties['id_gtf_engine'], 'type' => 'number');
+        $oPDOResult = $oBd->executeWithParams($aSql['pgsql']['select_fme_path'], $aParams);
+
+        if ($aRecord = $oBd->ligneSuivante($oPDOResult)) {
+            $properties["fme_path"] = $aRecord['fme_path'];
+        } else {
+            $properties["fme_path"] = '';
+        }
+        putenv("FME_PATH=" . $properties["fme_path"]);
+        putenv("GTF_HOME=" . $properties["workspace_dir"] . "/");
+
+        /*
+        // Traitement des demandes en fonction du moteur
+        $iNbTraitement = 0;
+        $aUserToRefresh = Array();
+        //$sSql = $aSql[$properties["sgbd"]]["boucle_1"];
+        if (TesteHeureCreuse($properties["heure_creuse_min"], $properties["heure_creuse_max"])) { // On est en heure creuse (0 correspond à "Heure Creuse")
+            $iPlageHorraire = 0;
+            $sSql = $aSql[$properties["sgbd"]]["boucle_1"];
+        } else { // On est PAS en heure creuse
+            $iPlageHorraire = 0;
+            $sSql = $aSql[$properties["sgbd"]]["boucle_2"];
+        }
+        $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+        $sSql = str_replace("[iPriorityId]", $iPlageHorraire, $sSql);
+        $sSql = str_replace("[iIdGtfEngine]", $properties["id_gtf_engine"], $sSql);
+        if ($properties["nbr_order_max"] < 1)
+            $properties["nbr_order_max"] = 1;
+        $sSql = str_replace("[iNnbrOrderMax]", $properties["nbr_order_max"], $sSql);
+        $sEnErreur = 2;
+        $oPDOResult = $oBd->execute($sSql);
+        //*/
+        
+        ///*
+        // Traitement des demandes en fonction du moteur7
+        // Gestion des heures creuses
+        $iNbTraitement = 0;
+        $aUserToRefresh = Array();
+        $aParams = array();
+
+        $iPlageHorraire = 0;
+        
+        $aParams['sSchemaGtf'] = array('value' => $properties['schema_gtf'], 'type' => 'schema_name');
+        $aParams['iPriorityId'] = array('value' => $iPlageHorraire, 'type' => 'number');
+        $aParams['iIdGtfEngine'] = array('value' => $properties["id_gtf_engine"], 'type' => 'number');
+        if ($properties["nbr_order_max"] < 1)
+            $properties["nbr_order_max"] = 1;
+        $aParams['iNnbrOrderMax'] = array('value' => $properties["nbr_order_max"], 'type' => 'number');
+
+        $sEnErreur = 2;
+        
+        if (TesteHeureCreuse($properties["heure_creuse_min"], $properties["heure_creuse_max"])) { // On est en heure creuse (0 correspond à "Heure Creuse")
+            $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["boucle_1"], $aParams);
+        } else { // On est PAS en heure creuse
+            $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["boucle_2"], $aParams);
+        }
+        
+        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']
+                            )
+                        )
+                    ));
+                }
+                $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
+                // 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;
+                    } else {
+                        $bAutorisationDemande = false;
+                        while ($aTraitementsAutorise = $oBd->ligneSuivante($oPDOResult2)) {
+
+                            if ($aTraitementsAutorise['workspace_id'] == $aDemande['workspace_id']) {
+                                $bAutorisationDemande = true;
+                            }
+                        }
+                    }
+                    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
+                        $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.
+                        $aLicence = getFmeLicence($properties['fme_path']);
+                        $bLicenceIsValid = $aLicence['valid'];
+                        $aLicence['valid'] = 1;
+                        if ($aLicence['valid'] == 1) {
+                            $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"]);
+                                            } 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) {
+
+                                        /*
+                                          $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"]);
+                                            } else {
+                                                writeToLog(str_replace("[properties['transit_dir']]", $properties['transit_dir'], INFO_DIRECTORY_NOT_FOUND_ENGINE), $properties["engine_log_file"]);
+                                                $iStatut = $sEnErreur;
+                                            }
+                                        }
+                                    }
+                                }
+                                $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;
+                            }
+                            unset($oTraitement);
+                        } else {
+                            $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"]);
+                            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 = "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;
+
+                        if (file_exists($sLogFme)) {
+                            $sLienLogFme = $sLogFme;
+                        } else {
+                            $sLienLogFme = 'Non disponible';
+                        }
+                    }
+                }
+                $oPDOResult2 = $oBd->fermeResultat();
+
+                //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"]);
+                    }
+                    // Fin - OG 27/03/2013 for table job
+                    $oPDOResult2 = $oBd->fermeResultat();
+                }
+                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);
+                    //*/
+
+                    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();
+                }
+                $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);
+                }
+
+                $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"]);
+                    }
+                    // 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);
+                      // */
+
+                    ///*
+                    // Mise a jour de la demande si resultat null
+                    $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']
+                                )
+                            )
+                        ));
+                    }
+                    $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.
+                    $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['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) {
+                        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'];
+
+                        /*
+                          // Nom des moteurs GTF et FME
+                          $sSql = $aSql[$properties["sgbd"]]["get_gtf_engine_name"];
+                          $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+                          $sSql = str_replace('[gtf_engine_id]', $aDemande['gtf_engine_id'], $sSql);
+                          $oPDOResult2 = $oBd->execute($sSql);
+                          // */
+                        ///*
+                        // Nom des moteurs GTF et FME
+                        $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);
+                        //*/
+
+
+                        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();
+                    //}
+                    $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	
+        }
+        if ($iNbTraitement >= 1) {
+            //Crée ou modifie le fichier de maj de l'application pour l'utilisateur.
+            writeToLog(INFO_END_ORDER_PROCESSING, $properties["engine_log_file"]);
+        }
+        $oPDOResult = $oBd->fermeResultat();
+    }
+} else {
+    writeToErrorLog(constant($ErrorLicense));
+}
+
+//Teste si le traitement est autorisé si la demande est en heure creuse.
+//retourne true si le traitement est autorisé, retourne false si le traitement n'est pas autorisé.
+function TesteHeureCreuse($sHeureMin, $sHeureMax) {
+    $sHeure = date('H');
+    $sMinute = date('i');
+    $aHeureMin = explode(":", $sHeureMin);
+    $aHeureMax = explode(":", $sHeureMax);
+    $bMax = false;
+    $bMin = false;
+    //Test de l'heure minimale.
+    if ($sHeure > $aHeureMin[0]) {
+        $bMin = true;
+    } else {
+        if ($sHeure == $aHeureMin[0] && $sMinute >= $aHeureMin[1]) {
+            $bMin = true;
+        }
+    }
+    //Test de l'heure maximale. 
+    if ($sHeure < $aHeureMax[0]) {
+        $bMax = true;
+    } else {
+        if (($aHeureMax[0] < $aHeureMin[0]) && ($sHeure < 24)) {
+            $bMax = true;
+        }
+        if ($sHeure == $aHeureMax[0] && $sMinute <= $aHeureMax[1]) {
+            $bMax = true;
+        }
+    }
+    if ($bMin && $bMax) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+?>
diff --git a/gtf.engine/gtf.engines/engine.sql.inc b/gtf.engine/gtf.engines/engine.sql.inc
new file mode 100755
index 00000000..3a36a236
--- /dev/null
+++ b/gtf.engine/gtf.engines/engine.sql.inc
@@ -0,0 +1,17 @@
+<?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']['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]";
+$aSql['pgsql']['select_user']='SELECT * FROM [sSchemaFramework].user WHERE "user_id"=[iUserId]';
+$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']['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])';
+?>
diff --git a/gtf.engine/gtf.engines/lang_engines/en-lang.inc b/gtf.engine/gtf.engines/lang_engines/en-lang.inc
new file mode 100755
index 00000000..be577b8a
--- /dev/null
+++ b/gtf.engine/gtf.engines/lang_engines/en-lang.inc
@@ -0,0 +1,7 @@
+<?php
+
+//Error Licence
+define('E001', "Orders unprocessed: Invalid lincense file");
+define('E002', "Orders unprocessed: Expired license file");
+define('E003', "Orders unprocessed: Number of the GTF engine upper than available engines");
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/lang_engines/fr-lang.inc b/gtf.engine/gtf.engines/lang_engines/fr-lang.inc
new file mode 100755
index 00000000..7d5d5046
--- /dev/null
+++ b/gtf.engine/gtf.engines/lang_engines/fr-lang.inc
@@ -0,0 +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");
+
+?>
\ 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
new file mode 100755
index 00000000..6985372b
--- /dev/null
+++ b/gtf.engine/gtf.engines/php_engine_conf.inc
@@ -0,0 +1,4 @@
+<?php
+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/properties_engine.inc b/gtf.engine/gtf.engines/properties_engine.inc
new file mode 100755
index 00000000..faf47c8d
--- /dev/null
+++ b/gtf.engine/gtf.engines/properties_engine.inc
@@ -0,0 +1,19 @@
+<?php
+require_once ("properties.inc");
+$properties["robot_root_dir"] = str_replace("\\","/",dirname($_SERVER["PHP_SELF"])); // Chemin du répertoire courant : gtf.engines
+if ($properties["id_gtf_engine"] != '') {
+	$subdir = '/engine_'.$properties["id_gtf_engine"];
+} else {
+	$subdir = '/subscription';
+}
+
+$properties["engine_log_home"] = $properties['vas_home']."/log/engines/".date($properties['log_period']).$subdir;
+$properties["debug_log_file"] = $properties["engine_log_home"]."/debug.log";
+$properties["engine_log_file"] = $properties["engine_log_home"]."/engine.log";
+$properties["notify_log_file"] = $properties["engine_log_home"]."/notify.log";
+$properties["sql_log_file"] = $properties["engine_log_home"]."/sql.log";
+$properties["subscription_log_file"] = $properties["engine_log_home"]."/subscription.log";
+$properties["error_log_file"] = $properties['vas_home']."/log/engines"."/error.log";
+
+$properties['web_server_name'] = 'https://dev.veremes.net';
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/regex2.dll b/gtf.engine/gtf.engines/regex2.dll
new file mode 100755
index 0000000000000000000000000000000000000000..f84a847a0de92fc59fa2ff8494ff700e62b87326
GIT binary patch
literal 79360
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
XFtagtFn2NcF!wPBrSwrexI+K{pWT)4

literal 0
HcmV?d00001

diff --git a/gtf.engine/gtf.engines/string.inc b/gtf.engine/gtf.engines/string.inc
new file mode 100755
index 00000000..24e8c0e4
--- /dev/null
+++ b/gtf.engine/gtf.engines/string.inc
@@ -0,0 +1,59 @@
+<?php
+// subscription.php
+	define('INFO_BASE_CONNECTION_ERROR', '|FATAL |PHP|Connexion impossible a la base ');
+	define('INFO_BASE_CONNECT', '|INFORM|PHP|Connect to ');
+	define('INFO_SUBSCRIPTION_PROCESSING', '|INFORM|PHP|Processing subscription order_id= ');
+	define('INFO_REQUEST_ERROR', '|FATAL |PHP| Erreur lors de l éxécution de la requête : ');
+	define('INFO_PHP_ERROR', '|ERROR|PHP| .');
+	define('INFO_ORDER_CREATED', '|INFORM|PHP|Order [iNouvelId] has been created.');
+	define('INFO_ORDER_CREATION_ERROR', '|ERROR|PHP|Problème lors de la création d\'un nouvel enregistrement dans la table "demande"');
+	define('INFO_CHECK_SQL_LOG', '|FATAL |PHP|Consultez le log sql.');
+	define('INFO_NO_USER_GRANT', '|FATAL |PHP|L utilisateur n a pas les droits nécessaires pour réaliser un traitement :');
+	define('INFO_CONTACT_ADMINISTRATOR', '|ERROR|PHP|Contactez l\'administrateur.');
+	define('INFO_CHECK_ORDER_FILES', '***************** Vérification des fichiers présents pour la demande [aDemande["order_id"]] *******************');
+	define('INFO_CHECK_DIRECTORY', '|INFORM|PHP|Check directory ');
+	define('INFO_MOVE_DIRECTORY', '|INFORM|PHP|Move directory from ');
+	define('INFO_MOVE_FILE', '|INFORM|PHP|Move file ');
+	define('INFO_DIRECTORY_NOT_FOUND_SUBSCRIPTION', "|ERROR|PHP| Le dossier [sFolder] n'existe pas. Contactez l'administrateur et vérifiez le dossier configuré dans l'interface de configuration de surveillance des dossier");
+	define('INFO_ORDER_PERIOD_NOT_FOUND', "|ERROR|PHP| La période d'abonnement n°[iPeriodeId] n'existe pas. Contactez l'administrateur et vérifiez la période d'abonnement ajoutée dans l'utilitaire pycron");
+	define('INFO_END_ORDER_PROCESSING', '***************** Fin du traitement des demandes *******************');
+	
+// Traitement.class.inc
+	define('INFO_RESOURCES', '|INFORM|PHP| Ressources : robot.php, Traitement.class.inc, Paramètres = [sParams], Fmw = [this->sFmwFileName]');
+	define('INFO_NULL_ELEMENT', '|WARN  |PHP| Un élément est null lors de la création de la demande : ');
+	define('INFO_DB_PARAM', 'Params : [aValeurs[0]] - Valeur : ');
+	define('INFO_ERROR', '|ERROR|');
+	define('INFO_COMMAND_ERROR', '|ERROR|PHP| Erreur lors de l exécution de la commande : ');
+	define('INFO_INFORM', '|INFORM|');
+	define('INFO_SUCCESSFUL_TREATMENT', '|INFORM|PHP| Traitement réussi.');
+	define('INFO_FILE_COMPRESSION', '|INFORM|PHP| Compression des fichiers du répertoire [sZipDir] en zip.');
+	define('INFO_TREATMENT_FAILURE', '|FATAL |PHP| Treatment failure.');
+	define('INFO_FILES_COMPRESSION_FAILURE', '|ERROR|PHP| Impossible de zipper les fichiers du répertoire [sZipDir] vers [sZipFileDir] dans fichier ');
+	define('INFO_COMPRESSED_FILES', '|INFORM|PHP| Compressed files : ');
+	define('INFO_DECOMPRESSING_FILE', '|INFORM|PHP| Décompression du fichier ');
+	define('INFO_FILE_COMPRESSION_FAILURE', '|ERROR|PHP| Impossible de dézipper le fichier [sZipFile] vers ');
+	define('INFO_FILE_COMPRESSION_DIRECTORY', '|INFORM|PHP| Fichiers décompressés vers ');
+	define('INFO_VALID_DATA_SOURCE_FILE_EXTENSION', '|INFORM|PHP| Extension valide pour le fichier de la source de données : ');
+	define('INFO_OUTPUT_DATA_DIRECTORY', '|INFORM|PHP| Répertoire de sortie des données : ');
+	define('INFO_OUTPUT_DATA_FILE', '|INFORM|PHP| Fichier de sortie des données : ');
+	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 ');
+	
+// engine.php
+	define('INFO_BASE_CONNECTION', '|INFORM|PHP| Connexion à la base de données ');
+	define('INFO_TOO_MANY_ORDER_ATTEMPT', "|INFORM|PHP| La demande [aDemande['order_id']] n'a pas été traitée suite à de trop nombreuses tentatives.");
+	define('INFO_ORDER_UPDATE_ERROR', '|ERROR|PHP| Impossible de mettre à jour la demande. ');
+	define('INFO_ORDER_UPDATE', '|INFORM|PHP| Mise à jour de la demande.');
+	define('INFO_ORDER_PROCESSING', "***************** Traitement de la demande [aDemande['order_id']] *******************");
+	define('INFO_DELETE_DIRECTORY', '|INFORM|PHP| Supression du dossier ');
+	define('INFO_GET_USER_INFO_ERROR', "|ERROR|PHP| Impossible de récupérer les informations sur l'utilisateur numéro ");
+	define('INFO_MOVING_FILE', '|INFORM|PHP| Déplacement du dossier [sSourceDirectory] vers le dossier ');
+	define('INFO_DIRECTORY_NOT_FOUND_ENGINE', "|ERROR|PHP| Le dossier [properties['transit_dir']] n'existe pas.");
+	define('INFO_INVALID_FME_LICENCE_FILE', '|FATAL |PHP| Invalid FME Licence file.');
+	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é ");
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/subscription.bat b/gtf.engine/gtf.engines/subscription.bat
new file mode 100755
index 00000000..f1830d76
--- /dev/null
+++ b/gtf.engine/gtf.engines/subscription.bat
@@ -0,0 +1,5 @@
+@echo off
+set GTF_ENGINE_HOME=%~dp0
+set PHP_HOME=%GTF_ENGINE_HOME%php
+rem %1 correspond au param�tre pass� par pycron
+"%PHP_HOME%\php.exe" "%GTF_ENGINE_HOME%\subscription.php" %1
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/subscription.php b/gtf.engine/gtf.engines/subscription.php
new file mode 100755
index 00000000..c12c25e3
--- /dev/null
+++ b/gtf.engine/gtf.engines/subscription.php
@@ -0,0 +1,359 @@
+<?php
+
+/**
+ * \file subscription.php
+ * \brief subscription.php \n \n Ce fichier contient un programme php.
+ *
+ * Ce programme permet de traiter les demandes d'abonnement de traitements.
+ *
+ * \author Laurent Panabieres <laurent.panabieres@veremes.com>
+ */
+//set_include_path(dirname($_SERVER["PHP_SELF"]).'/../gtf.client'.';'.dirname($_SERVER["PHP_SELF"]).'/php/lib');
+//ini_set ('writeToErrorLog', dirname($_SERVER["PHP_SELF"]).'/php/php.log');
+require_once ("php_engine_conf.inc");
+require_once ("gtf_lib/GtfFmwParser.class.inc");
+require_once ("vmlib/Vm.class.inc");
+require_once ("vmlib/phpUtil.inc");
+require_once("vmlib/dbUtil.inc");
+//require_once ("robot_properties.inc");
+//require_once ("engine_properties.inc");
+$properties["id_gtf_engine"] = "";
+require_once ("properties_engine.inc");
+require_once ("subscription.sql.inc");
+require_once ("vmlib/logUtil.inc");
+require_once("Ldap.class.inc");
+require_once 'vmlib/error.inc';
+require_once 'string.inc';
+
+//writeToLog('|INFO  |PHP| dump prop '. var_export($properties,true),$properties["subscription_log_file"]);
+
+/*
+  // Création du dossier journalier pour l'écriture du log
+  if (!is_dir($properties["engine_log_home"]. "/".date($properties["log_period"]))){
+  // Le dossier pour l'écritude du log n'existe pas, il est créé
+  if (!mkdir($properties["engine_log_home"]. "/".($properties["log_period"]), 0777, true)) {
+  writeToErrorLog(ERROR_0025.$properties["engine_log_home"]. "/".date($properties["log_period"]).'"');
+  }
+  }
+ */
+//Pas besoin de mot de passe pour le robot
+$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 {
+    writeToLog(INFO_BASE_CONNECT . $properties["database"], $properties["subscription_log_file"]);
+    // Traitement des demandes d'abonnement.
+    $iNbTraitement = 0;
+    // Récupération de l'identifiant de la période d'abonnement qui est lancé !
+    $iPeriodeId = $_SERVER['argv'][1];
+    
+    /*
+    $sSql = $aSql[$properties["sgbd"]]["verif_period_id"];
+    $sSql = str_replace("[iOrderPeriodId]", $iPeriodeId, $sSql);
+    $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+    $oPDOResult = $oBd->execute($sSql);
+    */
+    
+    // Récupération de l'identifiant de la période d'abonnement qui est lancé !
+    $aParams = array();
+    $aParams['iOrderPeriodId'] = array('value' => $iPeriodeId, 'type' => 'number');
+    $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+    $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["verif_period_id"], $aParams);
+
+    if ($oBd->ligneSuivante($oPDOResult) != "") {
+        
+        /*
+        $sSql = $aSql[$properties["sgbd"]]["abonnement"];
+        $sSql = str_replace("[iOrderPeriodId]", $iPeriodeId, $sSql);
+        $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+        $oPDOResult = $oBd->execute($sSql);
+         */
+        
+        // Recuperation des éléments de gestion des abonnements Gtf
+        $aParams = array();
+        $aParams['iOrderPeriodId'] = array('value' => $iPeriodeId, 'type' => 'number');
+        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+        $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["abonnement"], $aParams);
+        
+        while ($aDemande = $oBd->ligneSuivante($oPDOResult)) {
+            if (is_null($aDemande['order_date'])) {
+                $sDateTraitement = $aDemande['order_date'];
+            } else {
+                $sDateTraitement = $aDemande['execution_date'];
+            }
+            
+            /*
+            $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);
+            */
+            
+            // Récupération des information de connection de l'utilisateur et de ses droits
+            $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"]);
+            writeToLog(INFO_SUBSCRIPTION_PROCESSING . $aDemande["order_id"], $properties["subscription_log_file"]);
+            $iNbTraitement = $iNbTraitement + 1;
+            //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);
+            */
+            
+            // Verification des droits utilisateur sur la demande
+            $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["subscription_log_file"]);
+                writeToLog(INFO_PHP_ERROR, $properties["subscription_log_file"]);
+            } else {
+                if ($sGroupListId == "0") {
+                    $bAutorisationDemande = true;
+                } else {
+                    $bAutorisationDemande = false;
+                    while ($aTraitementsAutorise = $oBd->ligneSuivante($oPDOResult2)) {
+                        if ($aTraitementsAutorise['workspace_id'] == $aDemande['workspace_id']) {
+                            $bAutorisationDemande = true;
+                        }
+                    }
+                }
+                if ($bAutorisationDemande == true) {
+                    //Création d'une nouvelle demande.
+                    require_once("gtf_lib/gtf_object//Order.class.inc");
+                    $iNouvelId = $oBd->insert($properties["schema_gtf"], "order", Array("priority_id" => 1, "workspace_id" => $aDemande['workspace_id'], "order_status_id" => 1, "user_id" => $aDemande['user_id'], "period_id" => "", "order_date" => date("Y-m-d H:i:s"), "execution_date" => null, "wk_params" => $aDemande['wk_params'], "result_url" => "", "message" => "", "email_option_id" => $aDemande['email_option_id'], "gtf_engine_id" => $aDemande['gtf_engine_id'], "email_notifications" => $aDemande['email_notifications']), $properties["schema_gtf"] . ".seq_order", "order_id");
+                    $oOrder = new OrderLib($oBd, -1, $properties);
+                    $oOrder->getIdEngine($iNouvelId, "order", $aDemande['workspace_id']);
+                    $oOrder->update();
+                    if ($iNouvelId != "") {
+                        writeToLog(str_replace('[iNouvelId]', $iNouvelId, INFO_ORDER_CREATED), $properties["subscription_log_file"]);
+                        // L'abonnement crée une demande
+                        sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
+                            'action' => 'event',
+                            'service' => 'GtfEvents',
+                            'data' => array(
+                                'event' => 'subscription_creating_order',
+                                'order' => array(
+                                    'order_id' => $aDemande['order_id'],
+                                    'order_status_id' => $aDemande['order_status_id'],
+                                    'user_id' => $aDemande['user_id'],
+                                    'workspace_id' => $aDemande['workspace_id']
+                                )
+                            )
+                        ));
+                    } else {
+                        writeToLog(INFO_ORDER_CREATION_ERROR, $properties["subscription_log_file"]);
+                        writeToLog(INFO_CHECK_SQL_LOG, $properties["subscription_log_file"]);
+                    }
+                } else {
+                    writeToLog(INFO_NO_USER_GRANT . $aDemande['name'] . ' n\'as pas été définie.', $properties["subscription_log_file"]);
+                    writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["subscription_log_file"]);
+                    $iNouvelId = $oBd->update($properties["schema_gtf"], "order", Array("enabled" => FALSE), "order_id", $aDemande["order_id"], "");
+                }
+            }
+            $oPDOResult2 = $oBd->fermeResultat();
+        }
+        /*
+        $sSql = $aSql[$properties["sgbd"]]["dir_survey"];
+        $sSql = str_replace("[iOrderPeriodId]", $iPeriodeId, $sSql);
+        $sSql = str_replace("[sSchemaFramework]", $properties["schema_framework"], $sSql);
+        $sSql = str_replace("[sSchemaGtf]", $properties["schema_gtf"], $sSql);
+        writeToErrorLog($sSql);
+        $oPDOResult = $oBd->execute($sSql);
+        */
+        
+        $aParams = array();
+        $aParams['iOrderPeriodId'] = array('value' => $iPeriodeId, 'type' => 'number');
+        $aParams['sSchemaFramework'] = array('value' => $properties["schema_framework"], 'type' => 'schema_name');
+        $aParams['sSchemaGtf'] = array('value' => $properties["schema_gtf"], 'type' => 'schema_name');
+        $oPDOResult = $oBd->executeWithParams($aSql[$properties["sgbd"]]["dir_survey"], $aParams);
+        
+        while ($aDemande = $oBd->ligneSuivante($oPDOResult)) {
+            if (is_null($aDemande['order_date'])) {
+                $sDateTraitement = $aDemande['order_date'];
+            } else {
+                $sDateTraitement = $aDemande['execution_date'];
+            }
+            //writeToLog(str_replace('[aDemande["order_id"]]', $aDemande["order_id"], INFO_CHECK_ORDER_FILES), $properties["subscription_log_file"]); 
+            writeToLog(INFO_CHECK_DIRECTORY . $aDemande["condition"] . ' for survey order_id=' . $aDemande["order_id"], $properties["subscription_log_file"]);
+            //parcours du dossier de la condition de la demande
+            $sFolder = utf8_decode($aDemande["condition"]);
+            if (is_dir($sFolder)) {
+                $MyDirectory = opendir($sFolder);
+                while ($Entry = @readdir($MyDirectory)) {
+
+                    if ($Entry != '.' && $Entry != '..') {
+                        //deplacement vers le dossier upload en fonction du type
+                        $bCopie = false;
+                        $bIsFile = false;
+                        $sUnique = UniqFileName();
+                        if (is_dir($sFolder . '/' . $Entry)) {
+                            $bIsFile = false;
+                            $bCopie = rename($sFolder . "/" . $Entry, $properties["upload_dir"] . "/" . $sUnique);
+                            writeToLog(INFO_MOVE_DIRECTORY . $sFolder . "/" . $Entry . ' to ' . $properties["upload_dir"] . "/" . $sUnique, $properties["subscription_log_file"]);
+                        } else {
+                            $bIsFile = true;
+                            mkdir($properties["upload_dir"] . "/" . $sUnique);
+                            $bCopie = rename($sFolder . "/" . $Entry, $properties["upload_dir"] . "/" . $sUnique . "/" . $Entry);
+                            writeToLog(INFO_MOVE_FILE . $sFolder . "/" . $Entry . ' to ' . $properties["upload_dir"] . "/" . $sUnique . "/" . $Entry, $properties["subscription_log_file"]);
+                        }
+                        if ($bCopie) {
+                            //creation de la demande
+                            //Vérification si l'utilisateur a les droits pour faire une demande de ce traitement.
+                            /*
+                            $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);
+                            */
+                            
+                            // Récupération des infos utilisateurs
+                            $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"]);
+                            /*
+                            $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 des droits de l'utilisateurs pour la demande
+                            $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["subscription_log_file"]);
+                                writeToLog(INFO_PHP_ERROR, $properties["subscription_log_file"]);
+                            } else {
+                                if ($sGroupListId == "0") {
+                                    $bAutorisationDemande = true;
+                                } else {
+                                    $bAutorisationDemande = false;
+                                    while ($aTraitementsAutorise = $oBd->ligneSuivante($oPDOResult2)) {
+                                        if ($aTraitementsAutorise['workspace_id'] == $aDemande['workspace_id']) {
+                                            $bAutorisationDemande = true;
+                                        }
+                                    }
+                                }
+                                if ($bAutorisationDemande == true) {
+                                    //Création d'une nouvelle demande.
+                                    //writeToLog($properties["workspace_dir"],$properties["subscription_log_file"]);
+                                    $oGtfFmwParser = new GtfFmwParser($properties['vas_home'] . '/ws_data/gtf/workspace' . "/" . $aDemande['workspace_id'] . "/fme/" . $aDemande['fmw_file']);
+                                    $iNouvelId = "";
+
+                                    if ($bIsFile) {
+                                        $aDemande['wk_params'] = getParams($oGtfFmwParser, $sUnique . "/" . utf8_encode($Entry), $aDemande['wk_params']);
+                                    } else {
+                                        $aDemande['wk_params'] = getParams($oGtfFmwParser, $sUnique . "/", $aDemande['wk_params']);
+                                    }
+                                    require_once("gtf_lib/gtf_object/Order.class.inc");
+                                    $iNouvelId = $oBd->insert($properties["schema_gtf"], "order", Array("priority_id" => 1, "workspace_id" => $aDemande['workspace_id'], "order_status_id" => 1, "user_id" => $aDemande['user_id'], "period_id" => "", "order_date" => date("Y-m-d H:i:s"), "execution_date" => null, "wk_params" => $aDemande['wk_params'], "result_url" => "", "message" => "", "email_option_id" => $aDemande['email_option_id'], "gtf_engine_id" => $aDemande['gtf_engine_id'], "email_notifications" => $aDemande['email_notifications']), $properties["schema_gtf"] . ".seq_order", "order_id");
+                                    $oOrder = new OrderLib($oBd, -1, $properties);
+                                    $oOrder->getIdEngine($iNouvelId, "order", $aDemande['workspace_id']);
+                                    $oOrder->update();
+                                    if ($iNouvelId != "") {
+                                        writeToLog(str_replace('[iNouvelId]', $iNouvelId, INFO_ORDER_CREATED), $properties["subscription_log_file"]);
+                                        // La surveillance crée une demande
+                                        sendWebsocketMessage($properties['websocket_server'], $properties['websocket_port'], $properties['websocket_alias'], array(
+                                            'action' => 'event',
+                                            'service' => 'GtfEvents',
+                                            'data' => array(
+                                                'event' => 'survey_creating_order',
+                                                'order' => array(
+                                                    'order_id' => $aDemande['order_id'],
+                                                    'order_status_id' => $aDemande['order_status_id'],
+                                                    'user_id' => $aDemande['user_id'],
+                                                    'workspace_id' => $aDemande['workspace_id']
+                                                )
+                                            )
+                                        ));
+                                    } else {
+                                        writeToLog(INFO_ORDER_CREATION_ERROR, $properties["subscription_log_file"]);
+                                        writeToLog(INFO_CHECK_SQL_LOG, $properties["subscription_log_file"]);
+                                    }
+                                } else {
+                                    writeToLog(INFO_NO_USER_GRANT . $aDemande['name'] . ' n\'as pas été définie.', $properties["subscription_log_file"]);
+                                    writeToLog(INFO_CONTACT_ADMINISTRATOR, $properties["subscription_log_file"]);
+                                    $iNouvelId = $oBd->update($properties["schema_gtf"], "order", Array("enabled" => FALSE), "order_id", $aDemande["order_id"], "");
+                                }
+                            }
+                        }
+                    }
+                }
+            } else {
+                writeToLog(str_replace('[sFolder]', $sFolder, INFO_DIRECTORY_NOT_FOUND_SUBSCRIPTION), $properties["subscription_log_file"]);
+            }
+        }
+    } else {
+        writeToLog(str_replace('[iPeriodeId]', $iPeriodeId, INFO_ORDER_PERIOD_NOT_FOUND), $properties["subscription_log_file"]);
+    }
+
+    if ($iNbTraitement >= 1) {
+        //writeToLog(INFO_END_ORDER_PROCESSING, $properties["subscription_log_file"]);
+    }
+    $oPDOResult = $oBd->fermeResultat();
+}
+
+function getParams($oGtfFmwParser, $sNewSource, $sParams) {
+    $aTGui = array();
+    $sChaine = "";
+    $aParams = dbParamsAsArray($sParams);
+    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) {
+            writeToErrorLog($oGui->sDefault_Macro);
+            writeToErrorLog($sNewSource);
+            $aParams[$oGui->sDefault_Macro] = $sNewSource;
+        }
+    }
+    $aKeys = array_keys($aParams);
+
+    for ($i = 0; $i < count($aKeys); $i++) {
+        if ($sChaine == "") {
+            $sChaine = $aKeys[$i] . "=" . $aParams[$aKeys[$i]];
+        } else {
+            $sChaine .= "|" . $aKeys[$i] . "=" . $aParams[$aKeys[$i]];
+        }
+    }
+    //$sChaine = substr($sChaine, 0, -1)."\"";
+    return $sChaine;
+}
+
+function dbParamsAsArray($sAllParams) {
+    $aAllParams = Array();
+    //$aLigne = explode("|", $sAllParams);
+    $aLigne = stringExplode($sAllParams, "|", "\"", "\"");
+    foreach ($aLigne as $sValeur) {
+        $sValeur = str_replace("\"", "", $sValeur);
+        $aValeurs = explode("=", $sValeur);
+        if ($aValeurs[2] != "") {
+            $sTemp = $aValeurs[1] . "=" . $aValeurs[2];
+            $aValeurs[1] = $sTemp;
+        }
+        $aAllParams[$aValeurs[0]] = $aValeurs[1];
+    }
+    return $aAllParams;
+}
+
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/subscription.sql.inc b/gtf.engine/gtf.engines/subscription.sql.inc
new file mode 100755
index 00000000..46786f56
--- /dev/null
+++ b/gtf.engine/gtf.engines/subscription.sql.inc
@@ -0,0 +1,8 @@
+<?php
+//Requête pour subscription.php pgsql
+$aSql['pgsql']['verif_period_id']='SELECT period_id, name FROM [sSchemaGtf].period WHERE period_id = [iOrderPeriodId]';
+$aSql['pgsql']['abonnement']='SELECT "order".*, workspace.*, period.cron_expression FROM ([sSchemaGtf].order LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id) LEFT JOIN [sSchemaGtf].period ON period.period_id = "order".period_id WHERE order_status_id = 1 AND "order".period_id = [iOrderPeriodId] AND "order".period_id IS NOT NULL AND "order".survey_id IS NULL AND "order"."enabled" = TRUE ';
+$aSql['pgsql']['dir_survey']='SELECT "order".*, workspace.*, period.cron_expression, REPLACE(inbox.name, \'$user\', "user"."login") || \'/\' || "order".condition as condition FROM ([sSchemaGtf].order LEFT JOIN [sSchemaFramework].user on "order".user_id = "user"."user_id" LEFT JOIN [sSchemaGtf].inbox on "order".inbox_id = inbox.inbox_id LEFT JOIN [sSchemaGtf].workspace ON "order".workspace_id=workspace.workspace_id) LEFT JOIN [sSchemaGtf].period ON period.period_id = "order".period_id WHERE order_status_id = 1 AND "order".period_id = [iOrderPeriodId] AND "order".period_id IS NOT NULL AND "order".survey_id = 1 AND "order"."enabled" = TRUE';
+$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']["getLogin"]='SELECT "login" FROM [sSchemaFramework]."user" WHERE user_id = [iUserId]';
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.engines/tcl/Traitement.tcl b/gtf.engine/gtf.engines/tcl/Traitement.tcl
new file mode 100755
index 00000000..84defdd9
--- /dev/null
+++ b/gtf.engine/gtf.engines/tcl/Traitement.tcl
@@ -0,0 +1,64 @@
+# Récupération des variables d'environnement
+set sEnginesDir [file dirname $argv0]/..
+
+set sGtfDir $env(GTF_HOME)
+set sFmePath \{$env(FME_PATH)\}
+
+# Lecture de la librairie tclUtil
+source "$sEnginesDir/tcl/tclUtil.tcl"
+
+# Récupération des parametres sous forme de variables TCL
+set lLParams [stringToParam [lindex $argv 0] "|" "="]
+set lParametre [lindex $lLParams 0]
+set lValeur [lindex $lLParams 1]
+
+set sFmwFileName [lindex $lValeur 0]
+set sRobotLogName [lindex $lValeur 1] 
+set sFmeLogName [lindex $lValeur 2] 
+
+set i 0
+set sFmeParam ""
+foreach sParam $lParametre {
+  if {$sParam!="LOG_ROBOT" && $sParam!="LOG_FILENAME" && $sParam!="FMWFILENAME"} then {
+	set valeur [lindex $lValeur $i]
+	
+	# Vérification de l'emplacement de la balise <space>
+	set iSpacePlace [string first <space> $valeur]
+	# Si la balise existe, elle est remplacée par un espace (ça permet de gérer les cas ou la source (ex : de type access) peut contenir plusieurs extensions (mdb, accdb)
+	if {$iSpacePlace > 0} then {
+		set valeur [string map {<space> \ } $valeur]
+	}
+ 	set sFmeParam "$sFmeParam --$sParam \{$valeur\}"
+  }
+	incr i 
+}
+
+# Création de nouvelles variables
+set sScriptPath $sGtfDir/$sFmwFileName
+
+# Ecriture des parametres du traitement FME dans le log
+set sLigne "$sFmePath {$sScriptPath} $sFmeParam -LOG_FILENAME {$sFmeLogName}"
+
+# Variable qui va permettre d'écrire la commande TCL dans un fichier avec un nom unique
+set rand [expr int([expr rand() * 100000])]
+
+set sCommandeFile "$sEnginesDir/tcl/$rand.tcl"
+
+# Permet de récupérer un guillement (ajouté pour Edgar)
+set sLigne [string map {<quote> \"} $sLigne] 
+# Permet de récupérer un backslash (ajouté pour Edgar)
+set sLigne [string map {<backslashes> \\} $sLigne]
+
+set fCommande [open $sCommandeFile w+]
+# subst -nobackslashes $sLigne -- ligne inutile. Mis en commentaire le 20/06/12 par L.P.	
+puts $fCommande $sLigne
+close $fCommande
+
+if [ catch { source "$sCommandeFile" } sErreurFME] {
+	puts stdout "1|$sErreurFME" 
+} else {
+	puts stdout "0|Traitement réalisé avec succés"
+}
+
+file delete -force $sCommandeFile
+
diff --git a/gtf.engine/gtf.engines/tcl/commande.tcl b/gtf.engine/gtf.engines/tcl/commande.tcl
new file mode 100755
index 00000000..e69de29b
diff --git a/gtf.engine/gtf.engines/tcl/tclUtil.tcl b/gtf.engine/gtf.engines/tcl/tclUtil.tcl
new file mode 100755
index 00000000..873ec019
--- /dev/null
+++ b/gtf.engine/gtf.engines/tcl/tclUtil.tcl
@@ -0,0 +1,50 @@
+# + ---------------------------------------------------------------------- +
+# + tclUtil.tcl                                                            +
+# + Fonction TCL qui peuvent �tre r�utilis�es                              +
+# + Veremes - Fabien Marty - Mai 2007                                      +
+# + ---------------------------------------------------------------------- +
+
+
+##
+#D�coupe une chaine et renvoie les �l�ments d'une liste 
+#contenant une liste des param�tres et une liste des valeurs.
+##
+
+proc stringToParam {sString sDelimited1 sDelimited2} {
+	set lParams [split $sString $sDelimited1]
+	
+	foreach sParam $lParams {
+		set lResult [split $sParam =]
+		set sParametre [lindex $lResult 0]
+		set iLength [llength $lResult]
+	
+		if  { $iLength > 2 } {
+		set i 1
+		 while {$i < $iLength} {
+			set sTemp [lindex $lResult $i]
+			append sValeur $sTemp =
+		  set i [incr i]
+		 }
+
+		set sValue [string trimright $sValeur =]
+		} else {
+
+		set sValue [lindex $lResult 1]
+		}
+	lappend lListeParam $sParametre
+	lappend lListeValue $sValue
+	}	
+ return  [list $lListeParam $lListeValue]
+}
+
+##
+#�criture dans le log de la chaine pass�e en param�tre. 
+##
+
+proc writeToLog {sLogName sString sType} {
+	set oLogFile [open $sLogName "a"]
+	set sHeure [clock seconds]
+	set sHeureFormat [clock format $sHeure -format "%d/%m/%Y %H:%M:%S" -gmt false]
+	puts $oLogFile "$sHeureFormat	|$sType|TCL| $sString"
+	close $oLogFile
+}
\ No newline at end of file
diff --git a/gtf.engine/gtf.messages/class/Action.class.inc b/gtf.engine/gtf.messages/class/Action.class.inc
new file mode 100755
index 00000000..037a03a7
--- /dev/null
+++ b/gtf.engine/gtf.messages/class/Action.class.inc
@@ -0,0 +1,74 @@
+<?php
+require_once("vmlib/logUtil.inc");
+
+class Action {
+	protected $messageclass_action_id;
+	protected $aParams;
+	protected $oMessage;
+	protected $aProperties;
+	
+/***********************************************************
+  Récupère les paramètres de l'action d'un message
+	\$messageclass_action_id : id de l'actionclass
+	\$oMessage : objet du message
+	\$aParams :  paramètres de l'actionclass
+***********************************************************/
+	function __construct($messageclass_action_id, $oMessage, $aParams) {
+		$this->oMessage = $oMessage;
+		$this->messageclass_action_id = $messageclass_action_id;
+		$this->aProperties = $oMessage->aProperties;
+	// Application des paramètres
+		$this->setActionClassParameters($aParams);
+	}
+
+/*******************************************************
+*******************************************************/
+	function execute() {
+	}
+
+	function getError(){
+		writeToLog("You need to implement your action error controller", $properties["processMessage_log_file"], false);
+		writeToErrorLog("You need to implement your action error controller");
+		return true;
+	}
+
+/*******************************************************
+  
+  \$aParams : Tableau des paramètres définis en base
+*******************************************************/
+	function setActionClassParameters($aParams) {
+		if (!empty($aParams)) {
+			$this->aParams = array();
+			foreach($aParams as $sActionParam) {
+				list($sActionParamName, $sActionParamValue) = explode('=', $sActionParam);
+				eval('$this->aParams[\'' . $sActionParamName . '\'] = ' . $sActionParamValue . ';');
+			}
+			$this->aParams["token"] = $this->getToken($this->aProperties);
+		}
+	}
+
+	function getToken ($properties) {
+
+		if($properties['web_server_name'] === "[HTTP_HOST]"){
+			$properties['web_server_name'] = "https://localhost";
+		}
+		$sUrl = $properties['web_server_name'] . '/' . $properties['services_alias'] . '/vitis/privatetoken';
+		$postfields = array('user'=>$properties["login_bot"], 'password'=>$properties["pass_bot"]);
+
+		$oToken = json_decode($this->postCurlRequest ($sUrl, $postfields));
+		return $oToken->token;
+	}
+
+	function postCurlRequest ($sUrl, $postfields) {
+		$ch = curl_init($sUrl);
+		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+		curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json"));
+		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($ch, CURLOPT_POST, 1);
+		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+		curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
+		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+		return curl_exec($ch);
+	}
+}
+?>
diff --git a/gtf.engine/gtf.messages/class/BoAction.class.inc b/gtf.engine/gtf.messages/class/BoAction.class.inc
new file mode 100755
index 00000000..46eb9354
--- /dev/null
+++ b/gtf.engine/gtf.messages/class/BoAction.class.inc
@@ -0,0 +1,43 @@
+<?php
+require_once("vmlib/logUtil.inc");
+require_once("Action.class.inc");
+
+class BoAction Extends Action {
+	protected $oBusinessObject;
+	protected $bError;
+/**********************************************************
+  Class constructor
+	\$oBd : objet PDO
+	\$messageclass_action_id : id de l'actionclass
+	\$oMessage : Objet de la classe message
+	\$aParams :  paramètres de l'actionclass
+**********************************************************/
+	function __construct($oBd, $messageclass_action_id, $oMessage, $aParams, $properties) {
+		parent::__construct($messageclass_action_id, $oMessage, $aParams);
+		$iBoId = $oMessage->getBody($this->aParams['bo_id_attribute']);
+		if (!empty($iBoId)){
+			require_once($properties["vas_home"] ."/rest/ws/" . $this->aParams['module'] . "/" . $this->aParams['class'] . ".class.inc");
+			$aPath = array($this->aParams['module'], $this->aParams['class'], $iBoId);
+			$aValues = array($this->aParams['bo_id_attribute'] => $iBoId, "token" => $this->aParams['token']);
+
+			$this->oBusinessObject = new $this->aParams['class']($aPath, $aValues, $properties);
+			$this->oBusinessObject->oConnection->oBd = $oBd;
+			$this->bError = false;
+		} else {
+			$this->bError = true;
+		}
+	}
+
+/*******************************************************
+  Change le statut.
+*******************************************************/
+	function execute() {
+		$sTransitionMethod = $this->aParams['method'];
+		$this->oBusinessObject->$sTransitionMethod();
+	}
+
+	function getError() {
+		return $this->bError;
+	}
+}
+?>
diff --git a/gtf.engine/gtf.messages/class/EmailAction.class.inc b/gtf.engine/gtf.messages/class/EmailAction.class.inc
new file mode 100755
index 00000000..fa4d14cb
--- /dev/null
+++ b/gtf.engine/gtf.messages/class/EmailAction.class.inc
@@ -0,0 +1,40 @@
+<?php
+require_once("vmlib/logUtil.inc");
+require_once("vmlib/Email.class.inc");
+require_once("Action.class.inc");
+
+class EmailAction Extends Action {
+	protected $oEmail;
+	protected $bError;
+/**********************************************************
+  - Récupère les paramètres de l'action d'un message
+  - Crée un objet de la classe "Email".
+  - Applique les paramètres 
+	\$oBd : objet PDO
+	\$messageclass_action_id : id de l'actionclass
+	\$oMessage : Objet de la classe message
+	\$aParams :  paramètres de l'actionclass
+**********************************************************/
+	function __construct($oBd, $messageclass_action_id, $oMessage, $aParams) {
+		parent::__construct($messageclass_action_id, $oMessage, $aParams);
+		$aObjects['oMessage'] = $oMessage;
+		$iEmailTemplateId = $this->aParams['template_id'];
+		if (empty($iEmailTemplateId))
+			$iEmailTemplateId = $oMessage->aProperties['default_mail_model'];
+		$this->oEmail = new Email($oBd, $iEmailTemplateId, $oMessage->aProperties, $aObjects);
+		$this->bError = false;
+	}
+
+/*******************************************************
+  Envoi un email.
+*******************************************************/
+	function execute() {
+		if (!empty($this->oEmail->oEmailTemplate->name))
+			$this->oEmail->send();
+	}
+
+	function getError() {
+		return $this->bError;
+	}
+}
+?>
diff --git a/gtf.engine/gtf.messages/class/Message.class.inc b/gtf.engine/gtf.messages/class/Message.class.inc
new file mode 100755
index 00000000..59ad4a9e
--- /dev/null
+++ b/gtf.engine/gtf.messages/class/Message.class.inc
@@ -0,0 +1,155 @@
+<?php
+/**
+* \class Message
+* \file Message.class.inc
+*/
+
+require_once("vmlib/logUtil.inc");
+
+class Message {
+	protected $message_id;
+	public $messageclass;
+	protected $creation_date;
+	protected $status;
+	protected $body;
+	protected $bo_class_name;
+	protected $bo_class;
+	protected $bo_id;
+	protected $sender;
+	protected $oBo;
+	protected $oBd;
+	protected $aBodyValue;
+	public $aProperties;
+	protected $aSql;
+
+	/**
+	* Class constructor
+	* \param $oBd Connection object.
+	* \param $message_id Message id.
+	* \param $aProperties Array of properties.
+	*/
+	function __construct($oBd, $message_id , $aProperties) {
+		require("Message.class.sql.inc");
+		$this->aProperties = $aProperties;
+		$this->oBd = $oBd;
+		$this->aSql = $aSql;
+		$sSql = $this->aSql[$oBd->sgbd]['getMessage'];
+		//$sSql = str_replace('[message_id]',$message_id , $sSql);
+		//$sSql = str_replace('[schema]',$aProperties['schema_gtf'] , $sSql);
+		$aParams = array(
+			"message_id" => array("value"=> $message_id, "type"=> 'number'),
+			"schema" => array("value"=> $aProperties['schema_gtf'], "type"=> 'column_name')
+			);
+		$oResult = $oBd->executeWithParams($sSql, $aParams);
+		if($oBd->erreurRencontree)
+			$sErrorMsg = $oBd->getBDMessage();
+		else {
+			if ($oBd->nombreLigne ($oResult) > 0) {
+				$oRow = $oBd->objetSuivant ($oResult);
+				$this->message_id = $oRow->message_id;
+				$this->messageclass = $oRow->messageclass;
+				$this->creation_date = $oRow->creation_date;
+				$this->status = $oRow->status;
+				$this->body = $oRow->body;
+				//$this->bo_class_name = $oRow->bo_class_name;
+				//$this->bo_id = $oRow->bo_id;
+				$this->sender = $oRow->sender;
+			// Extrait les paramètres pour les actions de body
+				if (!empty($this->body)) {
+					preg_match_all('/(.)+:(.)+/', $this->body, $aActionParams);
+					if (!empty($aActionParams[0])) {
+						foreach ($aActionParams[0] as $sActionParam) {
+							list($sIndex, $sValue) = explode(':', $sActionParam);
+							$this->aBodyValue[trim($sIndex)] = trim($sValue);
+						}
+					}
+				}
+			}
+		}
+		if (isset($sErrorMsg)){
+			writeToLog("The message " . $message_id . "encountered this error : " . $sErrorMsg, $properties["processMessage_log_file"], false);
+		}
+	}
+
+	/*
+	* function setProcessed
+	* \brief Change the status of a message.
+	* \param $processed boolean.
+	*/
+	function setProcessed($processed) {
+		if ($processed === true)
+                $this->status = 3; // Traité
+            else
+                $this->status = 2; // En erreur
+        }
+
+	/*
+	* function process
+	* \brief Executes all actions of the message.
+	*/
+	function process() {
+	// Liste des actions du message	
+		$sSql = $this->aSql['pgsql']['getMessageActions'];
+		//$sSql = str_replace("[messageclass]", $this->messageclass, $sSql);
+		//$sSql = str_replace("[schema]", $this->aProperties['schema_gtf'], $sSql);
+		$aParams = array(
+			"messageclass" => array("value"=> $this->messageclass, "type"=> 'string'),
+			"schema" => array("value"=> $this->aProperties['schema_gtf'], "type"=> 'column_name')
+			);
+		$oActionResult = $this->oBd->executeWithParams($sSql, $aParams);
+		if(!$this->oBd->erreurRencontree) {
+			if ($this->oBd->nombreLigne($oActionResult) > 0) {
+				while ($oActionRow = $this->oBd->objetSuivant ($oActionResult)) {
+					if (file_exists(__DIR__ . '/' . $oActionRow->actionclass . '.class.inc')) {
+						require_once __DIR__ . '/' . $oActionRow->actionclass . '.class.inc';
+						if (!empty($oActionRow->parameters))
+							$aParams = explode('|', $oActionRow->parameters);
+						$oAction = new $oActionRow->actionclass($this->oBd, $oActionRow->messageclass_action_id, $this, $aParams, $this->aProperties);
+						if($oAction->getError() == false){
+							$oAction->execute();
+						} else {
+							writeToLog("ERROR : cannot create action with this body's parameters", $properties["processMessage_log_file"], false);
+							throw new Exception("ERROR : cannot create action with this body's parameters");
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	/*
+	* function getBody
+	* \param $key boolean.
+	* \return Returns the value of a parameter of action (or all the parameters and values).
+	*/
+	function getBody($key = null) {
+		if (is_null($key))
+			return $this->body;
+		else {
+			if (isset($this->aBodyValue[$key]))
+				return $this->aBodyValue[$key];
+			else
+				return null;
+		}
+	}
+
+	/*
+	* function update
+	* \brief Saves the settings of a message.
+	*/
+	function update() {
+	// Tous les paramètres sauf les tableaux et objets	
+		foreach (get_object_vars($this) as $sIndex => $value) {
+			if (!is_array($value) && !is_object($value)) {
+			// Le paramètre est une date ?	
+				/*if (strtotime($value) !== false)
+					$aValues[$sIndex] = "'$value'";
+				else*/
+					$aValues[$sIndex] = $value;
+			}
+		}
+		//error_log(print_r($this->oBd, true));
+		$this->oBd->update($this->aProperties['schema_gtf'], 'message', $aValues, 'message_id', $this->message_id, 'numeric');
+	}
+}
+?>
diff --git a/gtf.engine/gtf.messages/class/Message.class.sql.inc b/gtf.engine/gtf.messages/class/Message.class.sql.inc
new file mode 100755
index 00000000..47a0f8e9
--- /dev/null
+++ b/gtf.engine/gtf.messages/class/Message.class.sql.inc
@@ -0,0 +1,4 @@
+<?php
+	$aSql['pgsql']['getMessage'] = "SELECT * FROM [schema].message WHERE message_id = [message_id]";
+	$aSql['pgsql']['getMessageActions'] = "SELECT * FROM [schema].messageclass_action WHERE messageclass = [messageclass] ORDER BY index";
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.messages/processMessages.bat b/gtf.engine/gtf.messages/processMessages.bat
new file mode 100755
index 00000000..ae8efcb5
--- /dev/null
+++ b/gtf.engine/gtf.messages/processMessages.bat
@@ -0,0 +1,5 @@
+@echo off
+set GTF_MESSAGE_HOME=%~dp0
+set PHP_HOME=%GTF_MESSAGE_HOME%..\gtf.engines\php
+rem %1 correspond au paramètre passé par pycron
+"%PHP_HOME%\php.exe" "%GTF_MESSAGE_HOME%processMessages.php" %1
diff --git a/gtf.engine/gtf.messages/processMessages.php b/gtf.engine/gtf.messages/processMessages.php
new file mode 100755
index 00000000..bfa42008
--- /dev/null
+++ b/gtf.engine/gtf.messages/processMessages.php
@@ -0,0 +1,173 @@
+<?php
+	session_start();
+	
+	require_once dirname($_SERVER['PHP_SELF']).'/../gtf.engines/php_engine_conf.inc';
+	require_once dirname($_SERVER['PHP_SELF']).'/../gtf.engines/properties_engine.inc';
+	
+	require_once("vmlib/BD.class.inc");
+	require_once("vmlib/Vm.class.inc"); 
+	require_once("processMessages.sql.inc");
+	require_once("class/Message.class.inc");
+
+	$sPidFile = __DIR__ . "/PID_processMessages.pid";
+
+	$oNow = new DateTime();
+	$properties["processMessage_log_file"] = $properties['log_directories'] ['Application'] . "/processMessage/log_" . $oNow->format('Y-m-d') . ".log";
+
+	processIsRunnning ($sPidFile, $properties);
+	createPidFile($sPidFile, $properties);
+
+	//journalisation des logs pour le mailReader aussi 
+	// instanciation d'un objet pour accéder à la base compte u_vitis
+	$oBd = new BD ($properties['login_scheduler'], $properties['password_scheduler'], $properties["database"], $properties["server"], $properties["port"], $properties["sgbd"], $properties["page_encoding"]);
+
+	$iMessages = 0;
+	$iMessagesTraite = 0;
+
+	if ($oBd->erreurRencontree)
+		writeToLog('can\'t connect to database ' . $properties["database"] . " on " . $properties["server"] . ":" . $properties["port"] , $properties["processMessage_log_file"], false);
+	else {
+		// Traitement des messages en attente.
+		$sSql = $aSql['pgsql']['getWaitingMessages'];
+
+		$aParams = array(
+			"messageclass_type" => array("value"=> 'action', "type"=> 'string'),
+			"schema" => array("value"=> $properties['schema_gtf'], "type"=> 'column_name')
+			);
+
+		$oMessageResult=$oBd->executeWithParams($sSql, $aParams);
+		if(!$oBd->erreurRencontree) {
+			$iMessages = $oBd->nombreLigne($oMessageResult);
+			if ($iMessages > 0) {
+                // fonction à appeler à la fin du script.
+                register_shutdown_function('shutdownCallBack', $oBd, $properties);
+                // Traitement des messages en attente.
+                while ($oMessageRow = $oBd->objetSuivant ($oMessageResult)) {
+                    $iMessageId = $oMessageRow->message_id;
+                    $oMessage = new Message($oBd, $oMessageRow->message_id, $properties);
+                    $iOrderId = $oMessage->getBody("order_id");
+					if (!empty($iOrderId)){
+						$sSql = $aSql['pgsql']['getOrderStatus'];;
+						$sSql = str_replace("[ORDER_ID]", $iOrderId, $sSql);
+						$oOrderResult=$oBd->execute($sSql);
+						if(!$oBd->erreurRencontree) {
+							$oOrderRow = $oBd->objetSuivant ($oOrderResult);
+							if ($oOrderRow->order_status_id == 3 ){
+								$oMessage->process();
+								$oMessage->setProcessed(true);
+							    $oMessage->update();
+							    $iMessagesTraite ++;
+							}else{
+								writeToLog("message " . $iMessageId . " : can't be processing for the moment because the linked GTF order is not completed or it status is not 'valid'", $properties["processMessage_log_file"], false);
+							}
+						} else {
+							$oMessage->setProcessed(false);
+							$oMessage->update();
+							writeToLog("message " . $iMessageId . " : can't be processing because we can't find the linked GTF order", $properties["processMessage_log_file"], false);
+						}
+					} else {
+						$oMessage->process();
+						$oMessage->setProcessed(true);
+						$oMessage->update();
+						$iMessagesTraite ++;
+					}
+                }
+			}
+		}else{
+			writeToLog($oBd->getBDMessage(), $properties["processMessage_log_file"], false);
+		}
+	}
+
+	writeToLog("Iteration of the process completed : " . $iMessages . "(". $iMessagesTraite ." as OK)", $properties["processMessage_log_file"], false);
+
+	unlink($sPidFile);
+        
+	/*
+	* function shutDownCallBack
+	*   @oBd Database connection object.
+	*   @properties
+	*/
+        function shutDownCallBack($oBd, $properties) {
+            $aError = error_get_last();
+            // Erreur fatale pendant le traitement d'un message ?
+            if ($aError['type'] & E_ERROR > 0) {
+                writeToLog("[ERROR] [PHP] while processing the message " . $GLOBALS['iMessageId'] . "check the main log file", $properties["processMessage_log_file"], false);
+                // Change le statut du message : "en erreur".
+                $oMessage = new Message($oBd, $GLOBALS['iMessageId'], $properties);
+                $oMessage->setProcessed(false);
+                $oMessage->update();
+                // Re-exécute le script (au cas où il resterait des messages non traités).
+                if(DIRECTORY_SEPARATOR === "/"){
+                	// if linux
+                	exec(__DIR__ . '/processMessages.sh');
+                } else {
+                	// if windows
+                	exec(__DIR__ . '\processMessages.bat');
+                }
+            }
+        }
+
+        function processIsRunnning ($sPidFile, $properties){
+			if (file_exists ($sPidFile)){
+				// récupération du fichier .pid
+				$sPid = file_get_contents($sPidFile);
+				
+				$bProcessIsRunning = true;
+				$sOsName = PHP_OS;
+				// detection de l'os pour savoir comment controler le PID
+				if (strtoupper(substr($sOsName, 0, 3)) === 'WIN') {
+			    	$bProcessIsRunning = windowsPidCheck($sPid);
+				} else {
+				    $bProcessIsRunning = linuxPidCheck($sPid);
+				}
+
+				if($bProcessIsRunning === false){
+					//si le fichier PID est présent mais que le PID n'existe pas sur le serveur
+					// on supprime le fichier .pid et on lance le mailReader 
+					writeToLog("previous process exited without cleaning pidfile, removing", $properties["processMessage_log_file"], false);
+					unlink($sPidFile);
+				} else {
+					//si le process tourne déjà on ferme le process courant
+					writeToLog("found a running instance of processMessages.php, exiting.", $properties["processMessage_log_file"], false);
+					exit(0);
+				}
+			}
+			return true;
+		}
+
+		function windowsPidCheck ($iPid){
+			// fonction pour controller si un pid existe sous windows
+			$processes = explode( "\n", shell_exec('tasklist.exe /fi "PID eq ' . $iPid . '"'));
+
+			foreach( $processes as $process ) {
+
+			     if( ! empty($process) && (strpos("===", $process ) === 0) ){
+			          continue;
+			     }
+
+			     $matches = array();
+			     preg_match("/(.*?)\s+(\d+).*$/", $process, $matches);
+
+			     if(count($matches) > 0){
+			     	return true;
+			     }
+			}
+			return false;
+		}
+
+		function linuxPidCheck ($iPid){
+			// fonction pour controller si un pid existe sous linux
+			return file_exists("/proc/" . $iPid);
+		}
+
+		function createPidFile($sPidFile , $properties){
+		   	$file = fopen($sPidFile, 'w');
+		   	
+		   	if($file){ 
+		   		writeToLog("PID file creation with pid : " . getmypid(), $properties["processMessage_log_file"], false);
+		   		fwrite($file, getmypid());
+			}
+
+		   	fclose($file);
+		}
+?>
\ No newline at end of file
diff --git a/gtf.engine/gtf.messages/processMessages.sh b/gtf.engine/gtf.messages/processMessages.sh
new file mode 100755
index 00000000..89dadbfb
--- /dev/null
+++ b/gtf.engine/gtf.messages/processMessages.sh
@@ -0,0 +1,5 @@
+@echo off
+set GTF_MESSAGE_HOME=%~dp0
+set PHP_HOME=%GTF_MESSAGE_HOME%..\gtf.engines\php
+#rem %1 correspond au paramètre passé par pycron
+"../gtf.engines/php/bin/php" "./processMessages.php" %1
\ No newline at end of file
diff --git a/gtf.engine/gtf.messages/processMessages.sql.inc b/gtf.engine/gtf.messages/processMessages.sql.inc
new file mode 100755
index 00000000..6f481457
--- /dev/null
+++ b/gtf.engine/gtf.messages/processMessages.sql.inc
@@ -0,0 +1,4 @@
+<?php
+	$aSql['pgsql']['getWaitingMessages']='SELECT message.message_id FROM [schema].message,[schema].messageclass WHERE status=1 AND message.messageclass=messageclass.messageclass AND lower(messageclass_type)=lower([messageclass_type]) ORDER BY message_id;';
+	$aSql['pgsql']['getOrderStatus']='SELECT order_status_id FROM s_gtf.order WHERE order_id = [ORDER_ID] LIMIT 1';
+?>
\ No newline at end of file
-- 
GitLab