<?php

/*
 * @brief Fonctions php diverses
 *
 * @author Fabien Marty <fabien.marty@veremes.com>
 * @author Yoann Perollet <yoann.perollet@veremes.com>
 * @author Armand Bahi <armand.bahi@veremes.com>
 * @author Anthony Borghi <anthony.borghi@veremes.com>
 */
/*
 * Variable globale stockant le nom de dossier lib.
 */
$sFolderLib = "vmlib";

/**
 *This method remove all the backslashes of the element in an array.
 *@file vmlib/phpUtil.inc
 *@return $aString An array without the backlashes.
 */
function stripslashes_deep($aString) {
    $aString = is_array($aString) ?
            array_map('stripslashes_deep', $aString) :
            stripslashes($aString);

    return $aString;
}

/**
 *This method allow to upload a file on a server.
 *@file vmlib/phpUtil.inc
 *@param $sNomObjet Name of the object.
 *@param $sFileType Type of file needed.
 *@param $sServerPath New path of the file.
 *@param $sMaxSize Maximal size of the file.
 *@param $aFileValues File structure generated by extractFileStruct.
 *@return $sErrorMsg The error message or the final file path on success.
 */
 function uploadFile($sNomObjet, $sFileType, $sServerPath, $sMaxSize, $aFileValues) {
     global $properties, $sFolderLib;
     loadLang($sFolderLib, $properties["language"], $sFolderLib . "/");

     $aExtension = array(
         "image" => array('gif', 'jpg', 'jpeg', 'png'),
         "image-pdf" => array('gif', 'jpg', 'jpeg', 'png', 'pdf'),
         "document" => array('pdf', 'gif', 'jpg', 'jpeg', 'png', 'txt'),
         "pdf" => array('pdf'),
         "zip" => array('zip', 'gex'),
         "fmw" => array('fmw')
     );
     $aForbiddenExtension = explode('|', str_replace("*.", "", $properties['forbidden_extension']));
     $sTmpFile = "";
     $sErrorMsg = "";
     // si pas de aValues il y a eu une erreur pendant l'upload dans tmp du PUT
     if (!empty($aFileValues)){
         $sTmpFile = $aFileValues['tmp_name'];

         // Si l'utilisateur n'a indiqué aucun fichier à uploader, il ne se passe rien
         if ($sTmpFile == '') {
             if ($aFileValues['name'] != "") {
                 switch ($aFileValues['error']) {
                     case "1" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_UPLOAD_MAX_FILE_SIZE;
                         break;
                     case "2" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MAX_FILE_SIZE;
                         break;
                     case "3" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PARTIAL_DOWNLOAD;
                         break;
                     case "4" :
                         $sErrorMsg = ERROR_NO_FILE_DOWNLOADED;
                         break;
                     case "6" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MISSING_TEMP_FOLDER;
                         break;
                     case "7" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_WRITING_DISK;
                         break;
                     case "8" :
                         $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PHP_EXT_SEND;
                         break;
                 }
                 writeToErrorLog($sErrorMsg);
             }
             return $sErrorMsg;
         }

         $aTemp = explode("/", $sServerPath);

         $sFileName = end($aTemp);
         $sFileExtension = extension($sFileName);

         if (!in_array($sFileExtension, $aForbiddenExtension)) {
             //Teste si le fichier correspont au format voulu.
             $bAllowUpload = false;
             $sFormat = "";

             if (in_array($sFileType, array_keys($aExtension))){
                 if (in_array($sFileExtension, $aExtension[$sFileType])) {
                     $bAllowUpload = true;
                 } else {
                     foreach ($aExtensionPicture as $sValue) {
                         $sFormat .= " " . $sValue;
                     }
                     writeToErrorLog(ERROR_FILE . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType);
                     $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
                 }
             } else {
                 $bAllowUpload = true;
             }

             //Teste si le fichier n'est pas de trop grande taille.
             if ($aFileValues['size'] > $sMaxSize || $aFileValues['error'] == 1) {
                 $bAllowUpload = false;
                 if ($aFileValues['size'] > $sMaxSize)
                     $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . OF_LABEL_PHPUTIL . $aFileValues['size'] . ERROR_EXCEED_MAX_SIZE . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
                 if ($aFileValues['error'] > $sMaxSize)
                     $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_EXCEED_MAX_SIZE_PHP . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
             }

             // si c'est une image avec les infos de taille final on resample
             if($sFileType === "image" && (isset($aFileValues["width"]) && isset($aFileValues["height"]))){
               $sTmpFile = pictureResampler($sTmpFile, $aFileValues["width"], $aFileValues["height"], 0, 0, 0, 0, $sFileExtension);
               if(!$sTmpFile){
                 $bAllowUpload = false;
                 writeToErrorLog(ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . ', while resampling picture, ' . $sServerPath);
                 $sErrorMsg = ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . '.';
               }
             }

             //Lance l'upload.
             if ($bAllowUpload) {
               if ($properties['fileS3Uploader']){
                 require_once ("aws_sdk/aws-autoloader.php");

                 $s3 = new Aws\S3\S3Client(array(
                     'version'=>'latest',
                     'region'=> $properties['fileS3UploaderRegion'],
                     'profile'=> $properties['fileS3UploaderProfil'],
                     'debug' => false
                 ));

                 $sBucket = $properties['fileS3UploaderBucket'];
                 $sPrefix = "";

                 if (strpos($sBucket, "/") > -1){
                     $aBucket = explode("/", $sBucket );
                     $sBucket = $aBucket[0];
                     $sPrefix = implode("/", array_slice($aBucket, 1));
                 }

                 $sServerPath = str_replace($properties["vas_home"], $sPrefix , $sServerPath);
                 
                 // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
                 if (strpos($sServerPath, '/') === 0)
                    $sServerPath = substr($sServerPath, 1);

                 $aResult = $s3->putObject(array(
                   'Bucket' => $sBucket,
                   'Key'    => $sServerPath,
                   'Body'   => file_get_contents($sTmpFile)
                 ));

               } else if (!copy($sTmpFile, $sServerPath)) {
                     writeToErrorLog(ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . ', ' . $sTmpFile . ', ' . $sServerPath);
                     $sErrorMsg = ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . '.';
               }
                 unlink($sTmpFile);
                 $sErrorMsg = $sServerPath;
                 //chmod($sServerPath,755);
             }
         } else {
             writeToErrorLog(ERROR_FILE . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType);
             $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
         }
     } else {
         writeToErrorLog(ERROR_FILE . "File" . ERROR_DOWNLOAD_SERVER);
         $sErrorMsg = FILE_LABEL_PHPUTIL . "File" . ERROR_DOWNLOAD_SERVER . '.';
     }

     return $sErrorMsg;
 }

 /**
  *This method convert $_FILE struct or the aValues File to a File Struct usable by uploadFile.
  *@file vmlib/phpUtil.inc
  *@param $sField Name of the field.
  *@param $aValues $aValues to copy file in tmp.
  *@return $aFileStruct FileStuct or null if an error block the write in tmp.
  */
  function extractFileStruct ($sField, $aValues = null){
      global $properties;
      $aFileStruc = array();
      if (!isset($aValues[$sField . "_name"])){
          // Extract From Post $File Struct
          $aFileStruc = array(
              "name" => $_FILES[$sField]['name'],
              "tmp_name" => $_FILES[$sField]['tmp_name'],
              "error" => $_FILES[$sField]['error'],
              "size" => $_FILES[$sField]['size']
          );
      } else {
          // Extraction de $aValues, on le met dans tmp pour préparer la copie dans upload file
          $sTmpFile = $properties['extract_dir'] . "/" . getUniqRandomId();
          $oFile = fopen($sTmpFile, 'w+');
          if (!$oFile){
              writeToErrorLog("Can't open file in " . $properties['extract_dir']);
              return null;
          }else{
              fwrite($oFile, $aValues[$sField . "_file"]);
              fclose($oFile);
              $aFileStruc = array(
                  "name" => $aValues[$sField . "_name"],
                  "tmp_name" => $sTmpFile,
                  "error" => "0",
                  "size" => filesize($sTmpFile)
              );
          }
      }

      if(isset($aValues[$sField . "_width"]) && isset($aValues[$sField . "_height"])){
        $aFileStruc["width"] = $aValues[$sField . "_width"];
        $aFileStruc["height"] = $aValues[$sField . "_height"];
      }

      return $aFileStruc;
  }
 /**
  *This method upload a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@param $aValues Vitis $aValues.
  *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
  *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
  *@return $sErrorMsg The error message.
  */
 function uploadInWsDataDir ($sModule, $sObject, $mId, $sField, $aValues, $iMaxSize = -1, $sFileTypeCtrl = "all"){
     global $properties;

     // on controle les attributs pour éviter les mauvais placements
     if (strpos($sModule, '/') > -1){
         writeToErrorLog("Module can't contain path : " . $sModule);
         return "Module can't contain path : "  . $sModule;
     }

     if (strpos($sObject, "/") > -1){
         writeToErrorLog("Object can't contain path : " . $sObject);
         return "Object can't contain path : "  . $sObject;
     }

     if (strpos($mId, "/") > -1){
         writeToErrorLog("Id can't contain path : " . $mId);
         return "Id can't contain path : "  . $mId;
     }

     if (strpos($sField, "/") > -1){
         writeToErrorLog("Field can't contain path : " . $sField);
         return "Field can't contain path : "  . $sField;
     }
     // on génére la Structure fichier
     $aFileStruct = extractFileStruct ($sField, $aValues);
     // on génére la destination
     $sDestDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
     if(!empty($sField)){
       $sDestDir .= "/" . $sField;
     }
     $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];

     // on controle la destination pour éviter les mauvais placements
     if (strpos($sDestPath, "/\.\./") > -1){
         writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
         return "This function doesn't accept relative reference : " . $sDestPath;
     }
     // si taille max vaut -1 alors taille max = taille fichier + 1
     if ($iMaxSize == -1){
         $iMaxSize = $aFileStruct["size"] + 1;
     }
     // création du fichier si besoin
     if (!is_dir($sDestDir)){
         if(!mkdir($sDestDir, 0777, true)){
             writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
             return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
         }
     }
     // Upload du fichier
     return uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
 }
 /**
  *This method upload a file in Public.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sField field name (generally DB column name).
  *@param $aValues Vitis $aValues.
  *@param $sRandomUniqId random folder to write the file.(set to auto to let the function create the folder)
  *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
  *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
  *@return $sErrorMsg The error message.
  */
 function uploadInPublicDir($sModule, $sField, $aValues, $sRandomUniqId = "auto", $iMaxSize = -1, $sFileTypeCtrl = "all"){
   global $properties;

   // on controle les attributs pour éviter les mauvais placements
   if (strpos($sModule, '/') > -1){
       writeToErrorLog("Module can't contain path : " . $sModule);
       return "Module can't contain path : "  . $sModule;
   }
   if (strpos($sField, "/") > -1){
       writeToErrorLog("Field can't contain path : " . $sField);
       return "Field can't contain path : "  . $sField;
   }
   // on génére la Structure fichier
   $aFileStruct = extractFileStruct ($sField, $aValues);
   // on génére le dossier unique si besoin
   if($sRandomUniqId == "auto"){
     $sRandomUniqId = getUniqRandomId();
   }
   // on génére la destination
   $sDestDir = $properties['dir_export'] . "/" . $sModule . "/" . $sRandomUniqId;
   $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];

   // on controle la destination pour éviter les mauvais placements
   if (strpos($sDestPath, "/\.\./") > -1){
       writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
       return "This function doesn't accept relative reference : " . $sDestPath;
   }
   // si taille max vaut -1 alors taille max = taille fichier + 1
   if ($iMaxSize == -1){
       $iMaxSize = $aFileStruct["size"] + 1;
   }

   // création du fichier si besoin
   if (!is_dir($sDestDir)){
       if(!mkdir($sDestDir, 0777, true)){
           writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
           return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
       }
   }
   // Upload du fichier
   return uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
 }
 /**
  *This method upload a file in Upload.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sField field name (generally DB column name).
  *@param $aValues Vitis $aValues.
  *@param $sRandomUniqId random folder to write the file.(set to auto to let the function create the folder)
  *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
  *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
  *@return $sErrorMsg The error message.
  */
 function uploadInUploadDir($sModule, $sField, $aValues, $sRandomUniqId = "auto", $iMaxSize = -1, $sFileTypeCtrl = "all"){
   global $properties;

   // on controle les attributs pour éviter les mauvais placements
   if (strpos($sModule, '/') > -1){
       writeToErrorLog("Module can't contain path : " . $sModule);
       return "Module can't contain path : "  . $sModule;
   }
   if (strpos($sField, "/") > -1){
       writeToErrorLog("Field can't contain path : " . $sField);
       return "Field can't contain path : "  . $sField;
   }
   // on génére la Structure fichier
   $aFileStruct = extractFileStruct ($sField, $aValues);
   // on génére le dossier unique si besoin
   if($sRandomUniqId == "auto"){
     $sRandomUniqId = getUniqRandomId();
   }
   // on génére la destination
   $sDestDir = $properties['upload_dir'] . "/" . $sModule . "/" . $sRandomUniqId;
   $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];

   // on controle la destination pour éviter les mauvais placements
   if (strpos($sDestPath, "/\.\./") > -1){
       writeToErrorLog("This function doesn't accept relative reference : " . $sDestPath);
       return "This function doesn't accept relative reference : " . $sDestPath;
   }
   // si taille max vaut -1 alors taille max = taille fichier + 1
   if ($iMaxSize == -1){
       $iMaxSize = $aFileStruct["size"] + 1;
   }

   // création du fichier si besoin
   if (!is_dir($sDestDir)){
       if(!mkdir($sDestDir, 0777, true)){
           writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDestDir);
           return 'ERROR_CREATING_DIRECTORY ' . $sDestDir;
       }
   }
   // Upload du fichier
   return uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
 }
 /**
  *This method upload a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@return $aArray Tree structure from S3 or ws_data.
  */
 function getDirectoryInfosFromWsDataDir ($sModule, $sObject, $mId, $sField){
   global $properties;
   $sScanDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;

   if (!empty($sField)){
     $sScanDir .= "/" . $sField;
   }

   if ($properties['fileS3Uploader']){
     return array(getS3FolderInfos($sScanDir));
   }else{
     return array(getFolderInfos($sScanDir));
   }
 }
 /**
  *This method upload a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@return $aArray Tree structure from S3 or ws_data.
  */
 function deleteFileFromWsDataDirTree ($sModule, $sObject, $mId, $sField, $sFilePath){
   global $properties;
   require_once ("aws_sdk/aws-autoloader.php");
   $sFilePath = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId . "/" . $sField . "/" . $sFilePath;

   if ($properties['fileS3Uploader']){
     // traitement du bucket et de ses sous-dossiers
     $sBucket = $properties['fileS3UploaderBucket'];
     $sPrefix = "";

     if (strpos($sBucket, "/") > -1){
         $aBucket = explode("/", $sBucket );
         $sBucket = $aBucket[0];
         $sPrefix = implode("/", array_slice($aBucket, 1));
     }
     // Création du client S3
     $s3 = new Aws\S3\S3Client(array(
         'version'=>'latest',
         'region'=> $properties['fileS3UploaderRegion'],
         'profile'=> $properties['fileS3UploaderProfil'],
         'debug' => false
     ));

     try{

       $aResult = $s3->deleteObject(array(
         'Bucket' => $sBucket,
         'Key' => $sPrefix . str_replace($properties['ws_data_dir'], "/ws_data", $sFilePath)
       ));

     }catch(Aws\S3\Exception\S3Exception $e){
         writeToErrorLog($e->getMessage());
     }
   }else{
     unlink($sFilePath);
   }
 }
 /**
  *This method upload a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@return $aArray Tree structure from S3 or ws_data.
  */
 function postFileInWsDataDirTree ($sModule, $sObject, $mId, $sField, $aValues, $sAttrName){
   global $properties;
   require_once ("aws_sdk/aws-autoloader.php");
   $sFilePath = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId . "/";

   if(!empty($sField)){
     $sFilePath .= $sField . "/";
   }

   $aFileStruct = extractFileStruct ($sAttrName, $aValues);

   if ($properties['fileS3Uploader']){
     // traitement du bucket et de ses sous-dossiers
     $sBucket = $properties['fileS3UploaderBucket'];
     $sPrefix = "";

     if (strpos($sBucket, "/") > -1){
         $aBucket = explode("/", $sBucket );
         $sBucket = $aBucket[0];
         $sPrefix = implode("/", array_slice($aBucket, 1));
     }
     // Création du client S3
     $s3 = new Aws\S3\S3Client(array(
         'version'=>'latest',
         'region'=> $properties['fileS3UploaderRegion'],
         'profile'=> $properties['fileS3UploaderProfil'],
         'debug' => false
     ));

     try{

       $aResult = $s3->putObject(array(
         'Bucket' => $sBucket,
         'Key' => $sPrefix . str_replace($properties['ws_data_dir'], "/ws_data", $sFilePath) . $aFileStruct["name"],
         'Body' => file_get_contents($aFileStruct["tmp_name"])
       ));

       unlink($aFileStruct["tmp_name"]);

     }catch(Aws\S3\Exception\S3Exception $e){
         writeToErrorLog($e->getMessage());
     }
   }else{
     copy($aFileStruc["tmp_name"], $sFilePath . $aFileStruct["name"]);
   }
 }
 /**
  *This method scan a path to get metrics of a file/directory.
  *@file vmlib/phpUtil.inc
  *@param $sFilePath path to scan.
  *@return $aArray file structure from ws_data.
  */
 function getFileInfos ($sFilePath){
     global $properties;
     $iFileSize = filesize($sFilePath);

     $sFileSize = $iFileSize . " octets";
     if($iFileSize > 1024){
         if($iFileSize > 1024*1024){
             if($iFileSize > 1024*1024*1024){
                 $sFileSize = "-";
             } else {
                 $sFileSize = (ceil($iFileSize/(1024*1024))) . "Mo";
             }
         }else{
             $sFileSize = (ceil($iFileSize/1024)) . "Ko";
         }
     }

     $aFileName = explode("/", $sFilePath);
     $date = new DateTime();
     $sDataUrl = $properties['web_server_name'] . "/rest/vitis/file_downloader?key=[KEY]&eTag=[ETAG]&d=" . $date->getTimestamp();

     $sFileUrl = str_replace("[KEY]", str_replace($properties['ws_data_dir'], "ws_data" , $sFilePath), $sDataUrl);
     $sFileUrl = str_replace("[ETAG]", sha1(file_get_contents($sFilePath), false), $sFileUrl);

     return array("filename"=>$aFileName[count($aFileName) - 1], "size"=>$sFileSize, "lastModification"=> date ("d/m/Y H:i:s", filemtime($sFilePath)), "href" => $sFileUrl);
 }

 /**
  *This method scan a path to get metrics of an object (S3).
  *@file vmlib/phpUtil.inc
  *@param $sDirectoryPath path/prefix to scan.
  *@return $aArray file structure from S3.
  */
 function getS3FolderInfos ($sDirectoryPath){
     global $properties;
     require_once ("aws_sdk/aws-autoloader.php");
     //$oS3 = new AmazonS3($this->aProperties["awsAccessKey"], $this->aProperties["awsSecretKey"], $this->aProperties["s3Region"]);
     //$oS3Scan = $oS3->scanDir($properties["bucketName"], $sDirectoryPath, true);

     // traitement du bucket et de ses sous-dossiers
     $sBucket = $properties['fileS3UploaderBucket'];
     $sPrefix = "";

     if (strpos($sBucket, "/") > -1){
         $aBucket = explode("/", $sBucket );
         $sBucket = $aBucket[0];
         $sPrefix = implode("/", array_slice($aBucket, 1));
     }
     // Création du client S3
     $s3 = new Aws\S3\S3Client(array(
         'version'=>'latest',
         'region'=> $properties['fileS3UploaderRegion'],
         'profile'=> $properties['fileS3UploaderProfil'],
         'debug' => false
     ));

     $sListPrefix = str_replace($properties['ws_data_dir'], $sPrefix . "/ws_data" , $sDirectoryPath);

     try{

       $aList = $s3->listObjectsV2(array(
         'Bucket' => $sBucket,
         'Prefix' => $sListPrefix
       ));

       $date = new DateTime();
       $sDataUrl = $properties['web_server_name'] . "/rest/vitis/file_downloader?key=[KEY]&eTag=[ETAG]&d=" . $date->getTimestamp();
       $aPath = explode("/", $sDirectoryPath);
       $aTree = array(
               "filename"=> end($aPath),
               "lastModification" => "none",
               "size"=> "0 Octet",
               "content" => array()
       );
       if ($aList["KeyCount"] > 0){
         foreach ($aList["Contents"] as $aObject){
           $sObjectPath = str_replace($sListPrefix, "", $aObject["Key"]);
           $aObjectPath = explode("/", $sObjectPath);

           $sFileUrl = str_replace("[KEY]", $aObject["Key"], $sDataUrl);
           $sFileUrl = str_replace("[ETAG]", str_replace('"', '', $aObject["ETag"]), $sFileUrl);

           $iFileSize = $aObject["Size"];
           $sFileSize = $iFileSize . " octets";
           if($iFileSize > 1024){
               if($iFileSize > 1024*1024){
                   if($iFileSize > 1024*1024*1024){
                       $sFileSize = "-";
                   } else {
                       $sFileSize = (ceil($iFileSize/(1024*1024))) . "Mo";
                   }
               }else{
                   $sFileSize = (ceil($iFileSize/1024)) . "Ko";
               }
           }

           $sDate = $aObject["LastModified"]->__toString();
           $aTree = s3TreeBuilder($aTree, $sObjectPath, array(
               "filename"=> end($aObjectPath),
               "lastModification" =>  date ("d/m/Y H:i:s", strtotime($sDate)),
               "size" => $sFileSize,
               "href" => $sFileUrl
           ));
         }
       }

       return $aTree;

     }catch(Aws\S3\Exception\S3Exception $e){
         writeToErrorLog($e->getMessage());
     }
 }
 /**
  *This method scan an object key to generate a tree struct (S3).
  *@file vmlib/phpUtil.inc
  *@param $aTree an existing tree.
  *@param $sPath Path to scan.
  *@param $FileStructure object metrics structure.
  *@return $aArray file structure from S3.
  */
 function s3TreeBuilder ($aTree, $sPath, $FileStructure){
   $aTreeTmp = &$aTree["content"];
   $aPath = explode("/", $sPath);
   foreach ($aPath as $sFragment){
     if(!empty($sFragment)){
       if($sFragment !== $FileStructure["filename"]){
         $key = array_search($sFragment, array_column($aTreeTmp, 'filename'));

         if ($key !== false){
           $aTreeTmp = &$aTreeTmp[$key]["content"];
         } else {
           $aFolder = array(
             "filename"=> $sFragment,
             "lastModification" => "none",
             "size"=> "0 Octet",
             "content" => array()
           );

           array_push($aTreeTmp, $aFolder);
           $key = array_search($sFragment, array_column($aTreeTmp, 'filename'));
           $aTreeTmp = &$aTreeTmp[$key]["content"];
         }
       }else {
         array_push($aTreeTmp, $FileStructure);
       }
     }
   }
   return $aTree;
 }
 /**
  *This method scan a path to get metrics of a directory.
  *@file vmlib/phpUtil.inc
  *@param $sDirectoryPath path to scan.
  *@return $aArray file structure from ws_data.
  */
 function getFolderInfos ($sDirectoryPath){

     if(is_dir($sDirectoryPath)){
         $aContentDir = scandir($sDirectoryPath);
         $aTree = getFileInfos($sDirectoryPath);
         $aDir = array();
         for ($i =0 ; $i < count($aContentDir); $i++){
             if($aContentDir[$i] !== "." && $aContentDir[$i] !== ".."){
                 array_push($aDir, getFolderInfos($sDirectoryPath . "/" . $aContentDir[$i]));
             }
         }

         $aTree["content"] = $aDir;
         unset($aTree["href"]);
         return $aTree;
     } else {
         return getFileInfos($sDirectoryPath);
     }
 }

/**
 *This method return the extension of a file.
 *@file vmlib/phpUtil.inc
 *@param $sString Full name of a file.
 *@return Retourne une chaine.
 */
function extension($sString) {
    $aTemp = explode(".", $sString);
    $sString = strtolower($aTemp[count($aTemp) - 1]);

    return $sString;
}

/**
 *This method return the name of a file from its full path.
 *@file vmlib/phpUtil.inc
 *@param $sFullFileName Full path of a file.
 *@return $aTemp2 The file name.
 */
function getFileName($sFullFileName) {
    $aTemp = explode("/", $sFullFileName);
    $aTemp2 = explode("\\", $aTemp[(count($aTemp) - 1)]);

    return $aTemp2[(count($aTemp2) - 1)];
}

/**
 *Creates a compressed zip file
 *@file vmlib/phpUtil.inc
 *@param string $sFolder
 *@param string $sDestination
 *@param string $sPassword
 *@return boolean
 */
function createZip($sFolder, $sDestination, $sExtensionToExclude = '', $sPassword = '', $bDeleteFiles = false) {
    if (!empty($sExtensionToExclude)) {
        $aExtensionToExclude = explode('|', $sExtensionToExclude);
    } else {
        $aExtensionToExclude = array();
    }
    $sFolder = rtrim($sFolder, "/");

    $zip = new ZipArchive();

    if ($zip->open($sDestination, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
        die("An error occurred creating your ZIP file.");
    }

    $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($sFolder), RecursiveIteratorIterator::LEAVES_ONLY
    );
    $aCompressedFiles = array();
    foreach ($files as $name => $file) {
        if (!$file->isDir()) {
            $filePath = $file->getRealPath();

            // Récupération de l'extension
            $oFileInfo = new SplFileInfo($filePath);
            $sExtension = $oFileInfo->getExtension();

            $relativePath = substr($filePath, strlen($sFolder) + 1);
            if (in_array($sExtension, $aExtensionToExclude)) {
                continue;
            }
            if ($zip->addFile($filePath, $relativePath))
                $aCompressedFiles[] = $filePath;
            // Mot de passe.
            if (!empty($sPassword))
                $zip->setEncryptionName($oFileInfo->getFilename(), ZipArchive::EM_AES_256, $sPassword);
        }
    }

    if ($zip->close()) {
        // Suppression des fichiers compressés.
        if ($bDeleteFiles) {
            foreach ($aCompressedFiles as $sFilePath) {
                if (file_exists($sFilePath))
                    unlink($sFilePath);
            }
        }
    }
    return file_exists($sDestination);
}

/**
 *Unzip a compressed zip file
 *@file vmlib/phpUtil.inc
 *@param string $sZipFile
 *@param string $sDestination
 */
function unZip($sZipFile, $sDestination) {
    $zip = new ZipArchive;
    $res = $zip->open($sZipFile);
    if ($res === TRUE) {
        // extract it to the path we determined above
        $zip->extractTo($sDestination);
        $zip->close();
        return file_exists($sDestination);
    } else {
        return false;
    }
}

/**
 *@file vmlib/phpUtil.inc
 *@brief Teste un code pour savoir si il correspond à une fréquence.
 * Ce code est d'un jour (de 1 à 31), d'un mois (de 1 à 12) et d'un type de jour de la semaine (de 1 à 7).
 * Ces éléments doivent être définis ainsi : * défini tout le temps et / défini une répétition.
 *@param $sCode Code of the frequency.
 *@return $sReturn Return nothing if the code is good else return an error message.
 */
function TesteCode($sCode) {
    $bIsCorrecte = true;
    $sErrorMessage = "";
    $aCode = explode(" ", $sCode);
    if (count($aCode) == 3) {
        $aCode = Array('jour' => $aCode[0], 'mois' => $aCode[1], 'jour_semaine' => $aCode[2]);

        //Teste sur le jour
        if ($aCode['jour'] != "*") {
            if (($aCode['mois'] == "*" || is_numeric($aCode['mois'])) && $aCode['jour_semaine'] == "*") {
                if (is_numeric($aCode['jour'])) {
                    if ($aCode['jour'] >= 32 && $aCode['jour'] <= 0) {
                        $sErrorMessage = ERROR_DAY_CODE . $aCode['jour'] . ERROR_CODE_NOT_VALID . ERROR_NOT_INF . "1" . ERROR_NOT_SUP . '31.';
                        $bIsCorrecte = false;
                    }
                } else {
                    if (substr($aCode['jour'], 0, 2) != '*/' || !is_numeric(substr($aCode['jour'], 2, 2))) {
                        $sErrorMessage = ERROR_DAY_CODE . $aCode['jour'] . ERROR_CODE_NOT_VALID;
                        $bIsCorrecte = false;
                    } else {
                        if (substr($aCode['jour'], 2, 1) >= 31 && substr($aCode['jour'], 2, 2) <= 0) {
                            $sErrorMessage = ERROR_DAY_CODE . $aCode['jour'] . ERROR_CODE_NOT_VALID . ERROR_NOT_INF . '1' . ERROR_NOT_SUP . '30.';
                            $bIsCorrecte = false;
                        }
                    }
                }
            } else {
                $sErrorMessage = ERROR_DAY_WEEK;
                $bIsCorrecte = false;
            }
        }

        //Teste sur le mois
        if ($aCode['mois'] != "*" && $bIsCorrecte == true) {
            if (($aCode['jour'] == "*" || is_numeric($aCode['jour']) ) && $aCode['jour_semaine'] == "*") {
                if (is_numeric($aCode['mois'])) {
                    if ($aCode['mois'] >= 13 && $aCode['mois'] <= 0) {
                        $sErrorMessage = ERROR_MONTH_CODE . $aCode['mois'] . ERROR_CODE_NOT_VALID . ERROR_NOT_INF . '1' . ERROR_NOT_SUP . '12.';
                        $bIsCorrecte = false;
                    }
                } else {
                    if (substr($aCode['mois'], 0, 2) != '*/' || !is_numeric(substr($aCode['mois'], 2, 2))) {
                        $sErrorMessage = ERROR_MONTH_CODE . $aCode['mois'] . ERROR_CODE_NOT_VALID;
                        $bIsCorrecte = false;
                    } else {
                        if (substr($aCode['mois'], 2, 1) >= 13 && substr($aCode['mois'], 2, 2) <= 0) {
                            $sErrorMessage = ERROR_MONTH_CODE . $aCode['mois'] . ERROR_CODE_NOT_VALID . ERROR_CODE_NOT_VALID . ERROR_NOT_INF . '1' . ERROR_NOT_SUP . '12.';
                            $bIsCorrecte = false;
                        }
                    }
                }
            } else {
                $sErrorMessage = ERROR_DAY_WEEK;
                $bIsCorrecte = false;
            }
        }

        //Teste sur le jour de la semaine
        if ($aCode['jour_semaine'] != "*" && $bIsCorrecte == true) {
            if ($aCode['jour'] == "*" && $aCode['mois'] == "*") {
                if (is_numeric($aCode['jour_semaine'])) {
                    $sErrorMessage = ERROR_WEEK_CODE . $aCode['jour_semaine'] . ERROR_CODE_NOT_VALID . ERROR_NUMBER_PHPUTIL;
                    $bIsCorrecte = false;
                } else {
                    if (substr($aCode['jour_semaine'], 0, 2) != '*/' || !is_numeric(substr($aCode['jour_semaine'], 2, 2))) {
                        $sErrorMessage = ERROR_WEEK_CODE . $aCode['jour_semaine'] . ERROR_CODE_NOT_VALID;
                        $bIsCorrecte = false;
                    } else {
                        if (substr($aCode['jour_semaine'], 2, 2) >= 13 && substr($aCode['jour_semaine'], 2, 2) <= 0) {
                            $sErrorMessage = ERROR_WEEK_CODE . $aCode['jour_semaine'] . ERROR_CODE_NOT_VALID . ERROR_CODE_NOT_VALID . ERROR_NOT_INF . '1' . ERROR_NOT_SUP . '12.';
                            $bIsCorrecte = false;
                        }
                    }
                }
            } else {
                $sErrorMessage = ERROR_DAY_WEEK;
                $bIsCorrecte = false;
            }
        }
    } else {
        $sErrorMessage = ERROR_CODE_3_VALUES;
        $bIsCorrecte = false;
    }

    $sReturn = $sErrorMessage;

    return $sReturn;
}

/**
 * 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;
}

/*
 * function html2rgb
 * \brief  Ce code convertit les couleurs HTML (codées en hexa), en RGB .
 * \param $color chaine correspondant à la couleur
 * \return un tableau correspondant à la couleur en rgb
 */

function html2rgb($color) {
    // gestion du #...
    if (substr($color, 0, 1) == "#")
        $color = substr($color, 1, 6);
    $aTableau[0] = hexdec(substr($color, 0, 2));
    $aTableau[1] = hexdec(substr($color, 2, 2));
    $aTableau[2] = hexdec(substr($color, 4, 2));
    return $aTableau;
}

/*
 * function rgb2html
 * \brief  La réciproque exacte de la fonction html2rgb.
 * \param $aTableau tableau correspondant à la couleur en rgb
 * \return un chaine correspondant à la couleur
 */

function rgb2html($aTableau) {
    for ($i = 0; $i <= 2; $i++) {
        $aTableau[$i] = bornes($aTableau[$i], 0, 255);
    }
    // Le str_pad permet de remplir avec des 0
    // parce que sinon rgb2html(Array(0,255,255)) retournerai #0ffff<=manque un 0 !
    return "#" . str_pad(dechex(($aTableau[0] << 16) | ($aTableau[1] << 8) | $aTableau[2]), 6, "0", STR_PAD_LEFT);
}

/*
 * function rgb2html
 * \brief Une petite fonction utile pour borner les nombres entre 0 et 255.
 */

function bornes($nb, $min, $max) {
    if ($nb < $min)
        $nb = $min; // $nb est borné bas
    if ($nb > $max)
        $nb = $max; // $nb est Borné haut
    return $nb;
}

/*
 * function verifyFolder
 * \brief vérifie l'existance d'un répertoire
 * \param $sFolder : chemin du répertoire
 * \return $bFolderExist : booleen , true si le répertoire existe sinon false
 */

function verifyFolder($sFolder) {
    @$bFolderExist = dir($sFolder);
    return (@$bFolderExist);
}

/**
 * Cette fonction permet de supprimer un dossier sur le serveur.
 * \param $sDossier Dossier à supprimer.
 * return un booleen.
 */
function clearDir($sDossier) {
    $ouverture = @opendir($sDossier);
    if (!$ouverture)
        return;
    while ($sFichier = readdir($ouverture)) {

        if ($sFichier == '.' || $sFichier == '..')
            continue;
        if (is_dir($sDossier . "/" . $sFichier)) {
            $bCleared = clearDir($sDossier . "/" . $sFichier);
            if (!$bCleared)
                return false;
        }
        else {
            $bCleared = @unlink($sDossier . "/" . $sFichier);
            if (!$bCleared)
                return false;
        }
    }
    closedir($ouverture);
    $bCleared = @rmdir($sDossier);
    if (!$bCleared)
        return false;
    return true;
}

/*
 * function loadLang
 * charge le fichier de lang
 */

function loadLang($folderExt, $lang = "fr", $folderRoot = "", $encodage = "UTF-8") {
    if ($lang == "") {
        $lang = "fr";
    }
    if ($folderExt != "") {
        include_once($folderRoot . 'lang_' . $folderExt . '/' . $lang . '-lang.inc');
    } else {
        include_once($folderRoot . 'lang/' . $lang . '-lang.inc');
    }
}

/**
 * Cette fonction retourne le contenu d'un fichier dans une variable.
 * \param $sFilePath chaine Nom complet du fichier.
 * \return une chaine contenant le contenu du fichier, rien si le fichier n'existe pas.
 */
function getFileContent($sFilePath) {
    $sFileContent = "";
    if (file_exists($sFilePath)) {
        ob_start();
        include($sFilePath);
        $sFileContent = ob_get_contents();
        ob_end_clean();
    }
    return $sFileContent;
}

/**
 * ?
 */
function convert($value_in = false, $source_base = 10, $target_base = 32) {
    // We use these values for our conversions
    $values = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-', '_');
    $characters = array_flip($values);
    $string_out = '';
    // Easy answers
    if ($source_base == $target_base) {
        return $value_in;
    }
    $len = strlen($value_in);
    $sum = array();
    if ($source_base > $target_base) {
        for ($i = 0; $i < $len; $i++) {
            $char = substr($value_in, $len - $i - 1, 1);
            $sum[$i] = $characters[$char] * pow($source_base, $i);
        }
    } else {
        if ($source_base != 10) {
            $value = convert($value_in, $source_base, 10);
        } else {
            $value = $value_in;
        }
        $cnt = 0;
        while ($value > 0) {
            $times = $value / $target_base;
            $sum[] = mod($value, $target_base);
            $value = floor2($times); // get rid of our remainder
        }
        for ($i = count($sum); $i > 0; $i--) {
            $string_out .= $values[$sum[$i - 1]];
        }
        return $string_out;
    }
    if ($target_base == 10) {
        return array_sum($sum);
    }
    return implode($sum);
}

function mod($val, $mod) {
    return $val - floor2($val / $mod) * $mod;
}

function floor2($val) {
    $bits = explode('.', $val);
    return $bits[0];
}

/**
 * Send a websocket message
 * @param string $webSocketServer
 * @param string $webSocketPort
 * @param string $webSocketAlias
 * @param array $aPlayload array to convent JSON and send
 */
function sendWebsocketMessage($webSocketServer, $webSocketPort, $webSocketAlias, $aPlayload) {
    require_once 'vmlib/class.websocket_client.php';

    $client = new WebsocketClient;
    $client->connect($webSocketServer, $webSocketPort, '/' . $webSocketAlias);

    $sPayload = json_encode($aPlayload);

    // Check each 10ms if the server is yet connected and send the data via the websocket
    for ($index = 0; $index < 100; $index++) {
        if ($client->isConnected() === true) {
            $client->sendData($sPayload);
            break;
        } else {
            usleep(10000);
        }
    }

    usleep(5000);
}

/**
 * \class array2xml
 * \brief array2xml Class \n \n Cette classe totalement générique permet de générer du XML à partir d'un tableau PHP
 */
class array2xml extends DomDocument {

    private $xpath;
    private $sRoot;
    private $sNodeName;

    /**
     * Constructeur
     * \param $sRoot              Nom du premier noeud (string)
     * \param $sNodeName   The name numeric keys are called (string)
     */
    public function __construct($sRoot = 'root', $sNodeName = 'node') {
        parent::__construct();
        //$this->encoding = "ISO-8859-1";
        $this->encoding = "utf-8";
        $this->formatOutput = true;
        $this->sNodeName = $sNodeName;
        $this->sRoot = $this->appendChild($this->createElement($sRoot));
        $this->xpath = new DomXPath($this);
    }

    /*
     * Crée le XML à partir du tableau
     * \param   $aValueXml    Le tableau à convertir
     * \param  $sNode             Nom du noeud dans lequelle inlure les valeurs (string)
     */

    public function createNode($aValueXml, $sNode = null) {
        if (is_null($sNode)) {
            $sNode = $this->sRoot;
        }
        foreach ($aValueXml as $element => $value) {
            $element = is_numeric($element) ? $this->sNodeName : $element;
            $child = $this->createElement($element, (is_array($value) ? null : utf8_encode($value)));
            $sNode->appendChild($child);
            if (is_array($value)) {
                self::createNode($value, $child);
            }
        }
    }

    /*
     * Retourne le XML généré sous forme de chaine
     * return    le XML (string)
     */

    public function __toString() {
        return $this->saveXML();
    }

    /*
     * Perform an XPath query on the XML representation of the array
     * \param str $query - query to perform
     * return mixed
     */

    public function query($query) {
        return $this->xpath->evaluate($query);
    }

}

/**
 * Generate an unique id
 */
function vitisUniqId() {
    return uniqid(rand(10000, 99999));
}

/**
 * Generate an unique id
 * @param {integer} $iLength length og the random string before hash it
 * @return string random string generated by hashing a random string concatenated with current timestamp
 */
function getUniqRandomId($iLength = 64){
        $sCharacters = 'abcdefghijklmnopqrstuvwxyz0123456789';
        $sString = '';
        $iMax = strlen($sCharacters) - 1;

        for ($i = 0; $i < $iLength; $i++) {
            $sString .= $sCharacters[(mt_rand(0, $iMax*10) % $iMax)];
        }

        $sString .= time();

        return sha1($sString, false);
    }

/**
 * Copie un dossier ainsi que son contenu
 * @param {string} $src Source
 * @param {string} $dst Destination
 */
function copyDirectory($src,$dst) {
    $dir = opendir($src);
    @mkdir($dst);
    while(false !== ( $file = readdir($dir)) ) {
        if (( $file != '.' ) && ( $file != '..' )) {
            if ( is_dir($src . '/' . $file) ) {
                copyDirectory($src . '/' . $file,$dst . '/' . $file);
            }
            else {
                copy($src . '/' . $file,$dst . '/' . $file);
            }
        }
    }
    closedir($dir);
}

/**
 *This method will resample a picture. Preserve picture ratio.
 *@file vmlib/phpUtil.inc
 *@param $sFilePath Path to the picture on the server.
 *@param $iDstWidth Final Width.
 *@param $iDstHeight Final Height.
 *@param $iCropX Number of pixel to crop (horizontal).
 *@param $iCropY Number of pixel to crop (vertical).
 *@param $iOffsetX Number of pixel to begin the resampling (horizontal).
 *@param $iOffsetY Number of pixel to begin the resampling (vertical).
 *@param $sType Picture file extension if known.
 *@return $sPath Path of the resampled picture or false if error.
 */
function pictureResampler($sFilePath, $iDstWidth, $iDstHeight, $iCropX = 0, $iCropY = 0, $iOffsetX = 0, $iOffsetY = 0, $sType = null) {
    // récupération de l'extension pour ouverture du fichier
    if(empty($sType)){
      $sType = extension($sFilePath);
    }
    // Récupération du format de la source
    list($iCurrentWidth, $iCurrentHeight) = getimagesize($sFilePath);
    list($width, $height) = sizeCalculator($iCurrentWidth, $iCurrentHeight, $iDstWidth, $iDstHeight);
    // Ouverture de la ressource return false si format non réconnu
    switch ($sType) {
        case 'bmp':
            $img = imagecreatefromwbmp($sFilePath);
            break;
        case 'gif':
            $img = imagecreatefromgif($sFilePath);
            break;
        case 'jpg':
        case 'jpeg':
            $img = imagecreatefromjpeg($sFilePath);
            break;
        case 'png':
            $img = imagecreatefrompng($sFilePath);
            break;
        default :
            return false;
    }
    //Suppression du fichier sinon problème de réouverture après si jpg et doublon si autre format
    unlink($sFilePath);

    if ($img === false) {
        writeToErrorLog("ERROR : Vitis cannot open this file");
        return false;
    }
    // création de l'image de sortie
    $image_p = imagecreatetruecolor($width, $height);
    $white = imagecolorallocate($image_p, 255, 255, 255);
    imagefill($image_p, 0, 0, $white);
    // resizer
    if (!imagecopyresampled($image_p, $img, $iOffsetX, $iOffsetY, $iCropX, $iCropY, $width, $height, $iCurrentWidth, $iCurrentHeight)) {
        writeToErrorLog("ERROR : Vitis cannot resampling the picture");
        return false;
    }
    // transformation au format jpeg pour supprimer l'alpha et gagner en taille du fichier
    $dst = $sFilePath;
    if (strpos($sFilePath, ".") > -1){
      $aPath = explode(".", $sFilePath);
      $aPath[count($aPath) - 1] = "jpg";
      $dst = implode(".", $aPath);
    }

    // Enregistrement du jpeg
    if (!imagejpeg($image_p, $dst)) {
        writeToErrorLog("ERROR : Vitis failed to write this picture");
        return false;
    }
    // Libération espace mémoire
    imagedestroy($image_p);
    imagedestroy($img);
    // retour du nouveau nom de fichier
    return $dst;
}

/**
 *This method will process the final height/width for resampling a picture by preserve initial ratio.
 *@file vmlib/phpUtil.inc
 *@param $iCurrentWidth Width of the picture.
 *@param $iCurrentHeight Height of the picture.
 *@param $iTargetWidth Maximum final width of the picture.
 *@param $iTargetHeight Maximum final height of the picture.
 *@return $aSize couple width, height for resample the picture.
 */
function sizeCalculator($iCurrentWidth, $iCurrentHeight, $iTargetWidth, $iTargetHeight) {
    $iWidth = $iTargetWidth;
    $iHeight = $iTargetHeight;
    // si image plus grande on retourne les cibles
    if ($iCurrentWidth > $iTargetWidth && $iCurrentHeight > $iTargetHeight) {
        return array($iTargetWidth, $iTargetHeight);
    }
    // On détermine si on conserve la largeur ou la hauteur
    if ($iCurrentWidth > $iTargetWidth && $iCurrentHeight < $iTargetHeight) {
        $iHeight = $iCurrentHeight * $iTargetWidth / $iCurrentWidth;
        $iWidth = $iTargetWidth;
    } else if ($iCurrentWidth < $iTargetWidth && $iCurrentHeight > $iTargetHeight) {
        $iHeight = $iTargetHeight;
        $iWidth = $iCurrentWidth * $iTargetHeight / $iCurrentHeight;
    } else {
        // dans ce cas les les deux distance sont plus petite que le but on
        // calcul donc le delta pour déterminer quel coté est gardé
        $fDeltaWidth = $iCurrentWidth / $iTargetWidth;
        $fDeltaHeight = $iCurrentHeight / $iTargetHeight;
        if ($iDeltaWidth < $iDeltaHeight) {
            $iHeight = $iCurrentHeight;
            $iWidth = $iCurrentHeight * $iTargetWidth / $iTargetHeight;
        } else {
            $iWidth = $iCurrentWidth;
            $iHeight = $iCurrentWidth * $iTargetHeight / $iTargetWidth;
        }
    }

    return array($iWidth, $iHeight);
}


// end of class

/**
 * Get a date format
 * @param string $sUserDateFormat
 * @param string $sDateType
 * \return date pattern
 */
function getDatePattern($sUserDateFormat, $sDateType) {
    $Pattern= "";
    switch ($sDateType) {
        case "year" :
                $Pattern= "YYYY";
                break;
        case "month" :
                $Pattern= "MM";
                break;
        case "day" :
                $Pattern= "DD";
                break;
        case "yeartomonth" :
                $Pattern= "YYYY-DD";
                break;
        case "yeartoday" :
                $Pattern= substr($sUserDateFormat, 10);
                break;
        case "yeartominute" :
                $Pattern= str_replace("[FORMATDATE]", $sUserDateFormat, "[FORMATDATE] HH24:MI:SS");
                break;
        case "hourtosecond" :
                $Pattern= 'HH24:MI:SS';
                break;
        case "yeartosecond" :
                $Pattern= str_replace("[FORMATDATE]", $sUserDateFormat, "[FORMATDATE] HH24:MI:SS");
                break;
        case "yeartosecondtz" :
                $Pattern= str_replace("[FORMATDATE]", $sUserDateFormat, "[FORMATDATE] HH24:MI:SStz");
                break;
        case "yeartomillisecond" :
                $Pattern= str_replace("[FORMATDATE]", $sUserDateFormat, "[FORMATDATE] HH24:MI:SS.ms");
                break;
        case "yeartomillisecondtz" :
                $Pattern= str_replace("[FORMATDATE]", $sUserDateFormat, "[FORMATDATE] HH24:MI:SS.mstz");
                break;
    }
    return $Pattern;
}

  /**
  *This method copy a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@param $sFileName Name of the file to copy.
  *@param $sNewFileName Name of the new file.
  *@return $sErrorMsg The error message.
  */
function copyFileInWsDataDir ($sModule, $sObject, $mId, $sField = '', $sFileName, $sNewFileName) {
    global $properties;
    $sErrorMsg = '';
    $sDestDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
    if(!empty($sField))
        $sDestDir .= "/" . $sField;
    if ($properties['fileS3Uploader'] === true) {
        require_once ("aws_sdk/aws-autoloader.php");
        $s3 = new Aws\S3\S3Client(array(
            'version'=>'latest',
            'region'=> $properties['fileS3UploaderRegion'],
            'profile'=> $properties['fileS3UploaderProfil'],
            'debug' => false
        ));
        $sBucket = $properties['fileS3UploaderBucket'];
        $sPrefix = "";
        if (strpos($sBucket, "/") > -1){
            $aBucket = explode("/", $sBucket );
            $sBucket = $aBucket[0];
            $sPrefix = implode("/", array_slice($aBucket, 1));
        }
        $sServerPath = str_replace($properties["vas_home"], $sPrefix, $sDestDir);
        // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
        if (strpos($sServerPath, '/') === 0)
            $sServerPath = substr($sServerPath, 1);
        // Copie du fichier.
        try {
            $aResult = $s3->copyObject(array(
                'Bucket' => $sBucket,
                'Key' => $sServerPath . '/' . $sNewFileName,
                'CopySource' => $sBucket . '/' . $sServerPath . '/' . urlencode($sFileName)
            ));
        }
        catch(Aws\S3\Exception\S3Exception $e) {
            writeToErrorLog($e->getMessage());
        }
    }
    else {
        $sFilePath = $sDestDir . '/' . $sFileName;
        if (!copy($sFilePath, $sDestDir . '/' . $sNewFileName)) {
            writeToErrorLog(ERROR_COPYING_FILE . $sFileName . ON_SERVER_PHPUTIL . ', ' . $sFilePath . ', ' . $sServerPath);
            $sErrorMsg = ERROR_COPYING_FILE . $sFileName . ON_SERVER_PHPUTIL . '.';
        }
    }
    return $sErrorMsg;
}

 /**
  *This method delete a directory in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@param $sDirectoryName Name of the directory to delete.
  *@return $sErrorMsg The error message.
  */
function deleteDirectoryInWsDataDir($sModule, $sObject, $mId, $sField = '', $sDirectoryName = '') {
    global $properties;
    $sErrorMsg = '';
    $sDestDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
    if(!empty($sField))
        $sDestDir .= "/" . $sField;
    if ($properties['fileS3Uploader'] === true) {
        require_once ("aws_sdk/aws-autoloader.php");
        $s3 = new Aws\S3\S3Client(array(
            'version'=>'latest',
            'region'=> $properties['fileS3UploaderRegion'],
            'profile'=> $properties['fileS3UploaderProfil'],
            'debug' => false
        ));
        $sBucket = $properties['fileS3UploaderBucket'];
        $sPrefix = "";
        if (strpos($sBucket, "/") > -1){
            $aBucket = explode("/", $sBucket );
            $sBucket = $aBucket[0];
            $sPrefix = implode("/", array_slice($aBucket, 1));
        }
        $sServerPath = str_replace($properties["vas_home"], $sPrefix, $sDestDir);
        // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
        if (strpos($sServerPath, '/') === 0)
            $sServerPath = substr($sServerPath, 1);
        if (!empty($sDirectoryName))
            $sServerPath .=  '/' . $sDirectoryName;
        // Suppression du répertoire.
        try {
            $oAwsResult = $s3->listObjects(array(
                'Bucket' => $sBucket,
                'Prefix' => $sServerPath
            ));
            // Suppression de chaque fichier.
            $aKeys = $oAwsResult->get('Contents');
            if (is_array($aKeys)) {
                foreach($aKeys as $aKey) {
                    $aResult = $s3->deleteObject(array(
                        'Bucket' => $sBucket,
                        'Key' => $aKey['Key']
                    ));
                }
            }
        }
        catch(Aws\S3\Exception\S3Exception $e) {
            writeToErrorLog($e->getMessage());
        }
    }
    else {
        // Suppression du répertoire.
        $sDirectoryPath = $sDestDir . '/' . $sDirectoryName;
        if (is_dir($sDirectoryPath)) {
            if (!cleardir($sDirectoryPath)) {
                writeToErrorLog(ERROR_DELETING_DIRECTORY . $sDestDir);
                $sErrorMsg = ERROR_DELETING_DIRECTORY . $sDestDir;
            }
        }
    }
    return $sErrorMsg;
}

 /**
  *This method return the content of a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@param $sFileName Name of the file to read.
  *@return File content or false.
  */
function getFileContentInWsDataDir($sModule, $sObject, $mId, $sField = '', $sFileName) {
    global $properties;
    $sDestDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
    if(!empty($sField))
        $sDestDir .= "/" . $sField;
    if ($properties['fileS3Uploader'] === true) {
        require_once ("aws_sdk/aws-autoloader.php");
        $s3 = new Aws\S3\S3Client(array(
            'version'=>'latest',
            'region'=> $properties['fileS3UploaderRegion'],
            'profile'=> $properties['fileS3UploaderProfil'],
            'debug' => false
        ));
        $sBucket = $properties['fileS3UploaderBucket'];
        $sPrefix = "";
        if (strpos($sBucket, "/") > -1){
            $aBucket = explode("/", $sBucket );
            $sBucket = $aBucket[0];
            $sPrefix = implode("/", array_slice($aBucket, 1));
        }
        $sServerPath = str_replace($properties["vas_home"], $sPrefix, $sDestDir);
        // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
        if (strpos($sServerPath, '/') === 0)
            $sServerPath = substr($sServerPath, 1);
        if (!empty($sFileName))
            $sServerPath .=  '/' . $sFileName;
        // Lecture du fichier.
        try {
            $oAwsResult = $s3->getObject(array(
                'Bucket' => $sBucket,
                'Key' => $sServerPath
            ));
            return $oAwsResult->get('Body');
        }
        catch(Aws\S3\Exception\S3Exception $e) {
            writeToErrorLog($e->getMessage());
        }
    }
    else {
        // Chargment du contenu du fichier.
        $sFilePath = $sDestDir . '/' . $sFileName;
        if (file_exists($sFilePath)) {
            $sFileContent = file_get_contents($sFilePath);
            if ($sFileContent === false)
                writeToErrorLog(ERROR_READING_FILE_CONTENT . $sFilePath);
            return $sFileContent;
        }
        else {
            writeToErrorLog(ERROR_FILE_NOT_FOUND . $sFilePath);
            return false;
        }
    }
}

 /**
  *This method write data to a file in ws_data.
  *@file vmlib/phpUtil.inc
  *@param $sModule Name of the module.
  *@param $sObject Name of the object.
  *@param $mId Id of the current object.
  *@param $sField field name (generally DB column name).
  *@param $sFileName Name of the file to read.
  *@param $sFileContent Data to write to the file.
  *@return $sErrorMsg The error message.
  */
function putFileContentInWsDataDir($sModule, $sObject, $mId = '', $sField = '', $sFileName, $sFileContent) {
    global $properties;
    $sDestDir = $properties['ws_data_dir'] . "/" . $sModule . "/" . $sObject;
    if(!empty($mId))
        $sDestDir .= "/" . $mId;
    if(!empty($sField))
        $sDestDir .= "/" . $sField;
    if ($properties['fileS3Uploader'] === true) {
        require_once ("aws_sdk/aws-autoloader.php");
        $s3 = new Aws\S3\S3Client(array(
            'version'=>'latest',
            'region'=> $properties['fileS3UploaderRegion'],
            'profile'=> $properties['fileS3UploaderProfil'],
            'debug' => false
        ));
        $sBucket = $properties['fileS3UploaderBucket'];
        $sPrefix = "";
        if (strpos($sBucket, "/") > -1){
            $aBucket = explode("/", $sBucket );
            $sBucket = $aBucket[0];
            $sPrefix = implode("/", array_slice($aBucket, 1));
        }
        $sServerPath = str_replace($properties["vas_home"], $sPrefix, $sDestDir);
        // Suppression du slash de début de ligne (sinon création d'un répertoire vide sur S3).
        if (strpos($sServerPath, '/') === 0)
            $sServerPath = substr($sServerPath, 1);
        // Suppression du répertoire.
        try {
            $aResult = $s3->putObject(array(
                'Bucket' => $sBucket,
                'Key' => $sServerPath . '/' . $sFileName,
                'Body' => $sFileContent
            ));
        }
        catch(Aws\S3\Exception\S3Exception $e) {
            writeToErrorLog($e->getMessage());
        }
    }
    else {
        // Supprime le fichier si déja existant.
        $sFilePath = $sDestDir . '/' . $sFileName;
        if (file_exists($sFilePath)) {
            if (!unlink($sFilePath)) {
                writeToErrorLog(ERROR_DELETING_FILE . $sFilePath);
                return false;
            }
        }
        // Création du répertoire de destination si inexistant.
        if (!file_exists($sDestDir)) {
            if (!mkdir($sDestDir, 0777, true)) {
                writeToErrorLog('ERROR_CREATING_DIRECTORY ' . $sDirPath);
                return false;
            }
        }
        // Ecrit les données dans le fichier.
        if (file_put_contents($sFilePath, $sFileContent) === false) {
            writeToErrorLog(ERROR_WRITING_FILE_CONTENT . $sFilePath);
            return false;
        }
    }
}
?>
