From 80a981be0f721c86b277744aa5826272c5734b22 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Thu, 1 Mar 2018 17:52:59 +0100
Subject: [PATCH] FEAT #67 refactoring logs and history

---
 .../Controllers/ProcessConvertController.php  | 864 +++++++++---------
 .../ProcessThumbnailsController.php           | 688 +++++++-------
 rest/index.php                                |   4 +-
 .../history/controllers/HistoryController.php | 113 +--
 .../history/models/HistoryModelAbstract.php   | 159 +---
 src/core/controllers/LogsController.php       | 432 +++------
 6 files changed, 956 insertions(+), 1304 deletions(-)

diff --git a/modules/convert/Controllers/ProcessConvertController.php b/modules/convert/Controllers/ProcessConvertController.php
index 079a372314d..0aac650d696 100644
--- a/modules/convert/Controllers/ProcessConvertController.php
+++ b/modules/convert/Controllers/ProcessConvertController.php
@@ -1,432 +1,432 @@
-<?php
-
-/**
- * Copyright Maarch since 2008 under licence GPLv3.
- * See LICENCE.txt file at the root folder for more details.
- * This file is part of Maarch software.
- *
- */
-
-/**
-* @brief process convert class
-*
-* <ul>
-* <li>Services to process the convertion of resources</li>
-* </ul>
-*
-* @file
-* @author Laurent Giovannoni <dev@maarch.org>
-* @date $date$
-* @version $Revision$
-* @ingroup convert
-*/
-
-namespace Convert\Controllers;
-
-use Attachment\Models\AttachmentModel;
-use Psr\Http\Message\RequestInterface;
-use Psr\Http\Message\ResponseInterface;
-use Resource\models\ResModel;
-use Respect\Validation\Validator;
-use Convert\Models\ProcessConvertModel;
-use Docserver\models\DocserverModel;
-use Docserver\models\ResDocserverModel;
-use SrcCore\controllers\LogsController;
-use SrcCore\controllers\StoreController;
-
-class ProcessConvertController
-{
-    protected $libreOfficeExecutable;
-
-    //public function __construct($libreOfficeExecutable = 'cloudooo')
-    public function __construct($libreOfficeExecutable = 'soffice')
-    //public function __construct($libreOfficeExecutable = 'unoconv')
-    {
-        $this->libreOfficeExecutable = $libreOfficeExecutable;
-    }
-
-    public function create(RequestInterface $request, ResponseInterface $response)
-    {
-        $data = $request->getParams();
-
-        $check = Validator::notEmpty()->validate($data['collId']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['resTable']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['adrTable']);
-        $check = $check && Validator::intType()->notEmpty()->validate($data['resId']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['tmpDir']);
-        if (!$check) {
-            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
-        }
-
-        $return = ProcessConvertController::convert($data);
-
-        if (empty($return) || !empty($return['errors'])) {
-            return $response->withStatus(500)->withJson(['errors' => '[ProcessConvertController create] ' . $return['errors']]);
-        }
-
-        return $response->withJson($return);
-    }
-
-    /**
-     * Ask for conversion
-     *
-     * @param string $collId collection
-     * @param string $resTable resource table
-     * @param string $adrTable adr table
-     * @param long $resId res_id
-     * @param string $tmpDir path to tmp
-     * @param array $tgtfmt array of target format
-     * @return array $returnArray the result
-     */
-    public function convert(array $args=[])
-    {
-        $timestart = microtime(true);
-        // LogsController::info(['message'=>'debut convert', 'code'=>111, ]);
-        $returnArray = array();
-        if (empty($args['collId'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'collId empty',
-            );
-            return $returnArray;
-        } else {
-            $collId = $args['collId'];
-        }
-        if (empty($args['resTable'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'resTable empty',
-            );
-            return $returnArray;
-        } else {
-            $resTable = $args['resTable'];
-        }
-        if (empty($args['adrTable'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'adrTable empty',
-            );
-            return $returnArray;
-        } else {
-            $adrTable = $args['adrTable'];
-        }
-        if (empty($args['resId'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'resId empty',
-            );
-            return $returnArray;
-        } else {
-            $resId = $args['resId'];
-        }
-
-        if (!isset($args['tmpDir']) || $args['tmpDir'] == '') {
-            $tmpDir = $_SESSION['config']['tmppath'];
-        } else {
-            $tmpDir = $args['tmpDir'];
-        }
-
-        if ($args['resTable'] == 'res_letterbox') {
-            $res = ResModel::getById(['resId' => $resId]);
-        } elseif ($args['resTable'] == 'res_attachments') {
-            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'false']);
-        } else {
-            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'true']);
-        }
-
-        if ($res['res_id'] <> '') {
-            $resourcePath = ResDocserverModel::getSourceResourcePath(
-                [
-                    'resTable' => $resTable, 
-                    'adrTable' => $adrTable, 
-                    'resId' => $res['res_id'],
-                    'adrType' => 'DOC'
-                ]
-            );
-        }
-        if (!file_exists($resourcePath)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'file not exists : ' . $resourcePath,
-            );
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-        //copy the resource on tmp directory
-        $fileNameOnTmp = $tmpDir . rand() . rand();
-        if (!copy($resourcePath, $fileNameOnTmp)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'copy on tmp failed',
-            );
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-        //now do the conversion !
-        if (strtoupper($res['format']) <> 'PDF') {
-            $resultOfConversion = $this->launchConvert(
-                $fileNameOnTmp, 
-                'pdf', 
-                $tmpDir,
-                pathinfo($resourcePath, PATHINFO_EXTENSION)
-            );
-        } else {
-            copy($fileNameOnTmp, $fileNameOnTmp . '.pdf');
-            $resultOfConversion = array(
-                'status' => '0',
-                'value' => '',
-                'error' => '',
-            );
-        }
-        if ($resultOfConversion['status'] <> '0') {
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-        );
-            return $resultOfConversion;
-        }
-        //copy the result on docserver
-        // LogsController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
-        $storeResult = StoreController::storeResourceOnDocServer([
-            'collId'    => $collId,
-            'fileInfos' => [
-                'tmpDir'        => $tmpDir,
-                'size'          => filesize($fileNameOnTmp),
-                'format'        => 'PDF',
-                'tmpFileName'   => pathinfo($fileNameOnTmp, PATHINFO_FILENAME) . '.pdf',
-            ],
-            'docserverTypeId'   => 'CONVERT'
-        ]);
-
-        if (empty($storeResult)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'Ds of collection and ds type not found for convert:' 
-                    . $collId . ' CONVERT',
-            );
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-
-        if (!empty($storeResult['errors'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => $storeResult['errors'] . ' error for convert:' 
-                    . $fileNameOnTmp,
-            );
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-
-        $targetDs = DocserverModel::getById(['id' => $storeResult['docserver_id']]);
-
-        // LogsController::info(['message'=>'avant update', 'code'=>19, ]);
-        //update the \Database
-        $resultOfUpDb = ProcessConvertModel::updateDatabase(
-            [
-                'collId'     => $collId,
-                'resTable'   => $resTable, 
-                'adrTable'   => $adrTable, 
-                'resId'      => $resId,
-                'docserver'  => $targetDs,
-                'path'       => $storeResult['destination_dir'],
-                'fileName'   => $storeResult['file_destination_name']
-            ]
-        );
-        // LogsController::info(['message'=>var_export($resultOfUpDb, true), 'code'=>111111, ]);
-        // LogsController::info(['message'=>$collId, 'code'=>2, ]);
-        // LogsController::info(['message'=>$resTable, 'code'=>3, ]);
-        // LogsController::info(['message'=>$adrTable, 'code'=>4, ]);
-        // LogsController::info(['message'=>$resId, 'code'=>5, ]);
-        // LogsController::info(['message'=>'apres res_id', 'code'=>6, ]);
-        // LogsController::info(['message'=>$targetDs, 'code'=>6, ]);
-        // LogsController::info(['message'=>var_export($resultCopyDs, true), 'code'=>7, ]);
-
-        if ($resultOfUpDb['status'] <> '0') {
-            ProcessConvertModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $resultOfUpDb;
-        }
-
-        unlink($fileNameOnTmp);
-        unlink($fileNameOnTmp . '.pdf');
-
-        $returnArray = array(
-            'status' => '0',
-            'value' => '',
-            'error' => '',
-        );
-        LogsController::executionTimeLog(
-            $timestart, 
-            '', 
-            'debug', 
-            '[TIMER] Convert_ProcessConvertAbstract_Service::convert'
-        );
-        return $returnArray;
-    }
-
-    /**
-     * Launch the conversion
-     *
-     * @param string $srcfile source file
-     * @param string $tgtfmt target format
-     * @param string $tgtdir target dir
-     * @param string $srcfmt source format
-     * @return array $returnArray the result
-     */
-    public function launchConvert(
-        $srcfile, 
-        $tgtfmt, 
-        $tgtdir=false, 
-        $srcfmt=null
-    ) {
-        $timestart=microtime(true);
-
-        $processHtml = false;
-        $executable='';
-        
-        LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert']);
-        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
-            $processHtml = true;
-            LogsController::info(['message'=>'[TIMER] srcfmt ' . $srcfmt]);
-            copy($srcfile, str_ireplace('.maarch', '.', $srcfile) . '.html');
-            if (file_exists('/usr/bin/mywkhtmltopdf')) {
-                $command = "mywkhtmltopdf " 
-                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " " 
-                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.pdf');
-            } else {
-                $envVar = "export DISPLAY=FRPAROEMINT:0.0 ; ";
-                $command = $envVar . "wkhtmltopdf " 
-                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " " 
-                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.pdf');
-            }
-            $executable='wkhtmltopdf';
-        } else {
-            $executable='soffice';
-            LogsController::info(['message'=>'[TIMER] let LO do it ' . $this->libreOfficeExecutable]);
-            if ($this->libreOfficeExecutable == "cloudooo") {
-                $serverAddress = "http://192.168.21.40:8011";
-                $tokens = array();
-                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpc.inc';
-                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpcs.inc';
-                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpc_wrappers.inc';
-                $fileContent = file_get_contents($srcfile, FILE_BINARY);
-                $encodedContent = base64_encode($fileContent);
-                $params = array();
-                array_push($params, new PhpXmlRpc\Value($encodedContent));
-                array_push($params, new PhpXmlRpc\Value($srcfmt));
-                array_push($params, new PhpXmlRpc\Value($tgtfmt));
-                array_push($params, new PhpXmlRpc\Value(false));
-                $v = new PhpXmlRpc\Value($params, "array");
-            } elseif ($this->libreOfficeExecutable == "unoconv") {
-                $tokens = array('"' . $this->libreOfficeExecutable . '"');
-                $tokens[] = "-f";
-                $tokens[] = $tgtfmt;
-                $tokens[] = '-o "' . $srcfile . '.' . $tgtfmt . '"';
-                $tokens[] = '"' . $srcfile . '"';
-            } else {
-                $tokens = array('"' . $this->libreOfficeExecutable . '"');
-                $tokens[] = "--headless";
-                $tokens[] = "--convert-to";
-                $tokens[] = $tgtfmt;
-                $tokens[] = '"' . $srcfile . '"';
-                if (!$tgtdir) {
-                    $tgtdir = dirname($srcfile);
-                }
-                $tokens[] = '--outdir "' . $tgtdir . '"';
-            }
-            
-            if (!$srcfmt) {
-                $tokens[] = $srcfmt;
-            }
-
-            $command = implode(' ', $tokens);
-
-            $output = array();
-            $return = null;
-            $this->errors = array();
-        }
-        //echo $command . '<br />';exit;
-        if ($this->libreOfficeExecutable == "cloudooo" && !$processHtml) {
-            LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
-            LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
-            $req = new PhpXmlRpc\Request('convertFile', $v);
-            //LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
-            LogsController::info(['message'=>'[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
-            $client = new PhpXmlRpc\Client($serverAddress);
-            $resp = $client->send($req);
-            if (!$resp->faultCode()) {
-                $encoder = new PhpXmlRpc\Encoder();
-                $value = $encoder->decode($resp->value());
-                $theFile = fopen($srcfile . '.' . $tgtfmt, 'w+');
-                fwrite($theFile, base64_decode($value));
-                fclose($theFile);
-                $returnArray = array(
-                    'status' => '0',
-                    'value' => '',
-                    'error' => '',
-                );
-            } else {
-                //print "An error occurred: ";
-                //print "Code: " . htmlspecialchars($resp->faultCode()) 
-                //    . " Reason: '" . htmlspecialchars($resp->faultString()) . "'\n";
-                $returnArray = array(
-                    'status' => '1',
-                    'value' => '',
-                    'error' => "Code: " . htmlspecialchars($resp->faultCode()) 
-                        . " Reason: '" . htmlspecialchars($resp->faultString()),
-                );
-            }
-        } else {
-            $timestart_command = microtime(true);
-            exec("timeout -k 5m 3m " . $command, $output, $return);
-            LogsController::debug(['message'=>'[TIMER] commande : ' . $command]);
-            LogsController::executionTimeLog($timestart_command, '', 'info', '[TIMER] ' . $executable . ' - Convert_ProcessConvertAbstract_Service::launchConvert__exec');
-            if ($return === 0) {
-                $returnArray = array(
-                    'status' => '0',
-                    'value' => '',
-                    'error' => '',
-                );
-            } else {
-                $returnArray = array(
-                    'status' => '1',
-                    'value' => '',
-                    'error' => $return . $output,
-                );
-            }
-        }
-        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
-            $returnArray = array();
-            unlink(str_ireplace('.maarch', '.', $srcfile) . '.html');
-            $returnArray = array(
-                'status' => '0',
-                'value' => '',
-                'error' => '',
-            );
-        }
-        LogsController::executionTimeLog(
-            $timestart, 
-            '', 
-            'info', 
-            '[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert'
-        );
-        return $returnArray;
-    }
-}
\ No newline at end of file
+<?php
+
+/**
+ * Copyright Maarch since 2008 under licence GPLv3.
+ * See LICENCE.txt file at the root folder for more details.
+ * This file is part of Maarch software.
+ *
+ */
+
+/**
+* @brief process convert class
+*
+* <ul>
+* <li>Services to process the convertion of resources</li>
+* </ul>
+*
+* @file
+* @author Laurent Giovannoni <dev@maarch.org>
+* @date $date$
+* @version $Revision$
+* @ingroup convert
+*/
+
+namespace Convert\Controllers;
+
+use Attachment\Models\AttachmentModel;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Resource\models\ResModel;
+use Respect\Validation\Validator;
+use Convert\Models\ProcessConvertModel;
+use Docserver\models\DocserverModel;
+use Docserver\models\ResDocserverModel;
+use SrcCore\controllers\LogsController;
+use SrcCore\controllers\StoreController;
+
+class ProcessConvertController
+{
+    protected $libreOfficeExecutable;
+
+    //public function __construct($libreOfficeExecutable = 'cloudooo')
+    public function __construct($libreOfficeExecutable = 'soffice')
+    //public function __construct($libreOfficeExecutable = 'unoconv')
+    {
+        $this->libreOfficeExecutable = $libreOfficeExecutable;
+    }
+
+    public function create(RequestInterface $request, ResponseInterface $response)
+    {
+        $data = $request->getParams();
+
+        $check = Validator::notEmpty()->validate($data['collId']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['resTable']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['adrTable']);
+        $check = $check && Validator::intType()->notEmpty()->validate($data['resId']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['tmpDir']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $return = ProcessConvertController::convert($data);
+
+        if (empty($return) || !empty($return['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => '[ProcessConvertController create] ' . $return['errors']]);
+        }
+
+        return $response->withJson($return);
+    }
+
+    /**
+     * Ask for conversion
+     *
+     * @param string $collId collection
+     * @param string $resTable resource table
+     * @param string $adrTable adr table
+     * @param long $resId res_id
+     * @param string $tmpDir path to tmp
+     * @param array $tgtfmt array of target format
+     * @return array $returnArray the result
+     */
+    public function convert(array $args=[])
+    {
+        $timestart = microtime(true);
+        // LogsController::info(['message'=>'debut convert', 'code'=>111, ]);
+        $returnArray = array();
+        if (empty($args['collId'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'collId empty',
+            );
+            return $returnArray;
+        } else {
+            $collId = $args['collId'];
+        }
+        if (empty($args['resTable'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'resTable empty',
+            );
+            return $returnArray;
+        } else {
+            $resTable = $args['resTable'];
+        }
+        if (empty($args['adrTable'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'adrTable empty',
+            );
+            return $returnArray;
+        } else {
+            $adrTable = $args['adrTable'];
+        }
+        if (empty($args['resId'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'resId empty',
+            );
+            return $returnArray;
+        } else {
+            $resId = $args['resId'];
+        }
+
+        if (!isset($args['tmpDir']) || $args['tmpDir'] == '') {
+            $tmpDir = $_SESSION['config']['tmppath'];
+        } else {
+            $tmpDir = $args['tmpDir'];
+        }
+
+        if ($args['resTable'] == 'res_letterbox') {
+            $res = ResModel::getById(['resId' => $resId]);
+        } elseif ($args['resTable'] == 'res_attachments') {
+            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'false']);
+        } else {
+            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'true']);
+        }
+
+        if ($res['res_id'] <> '') {
+            $resourcePath = ResDocserverModel::getSourceResourcePath(
+                [
+                    'resTable' => $resTable,
+                    'adrTable' => $adrTable,
+                    'resId' => $res['res_id'],
+                    'adrType' => 'DOC'
+                ]
+            );
+        }
+        if (!file_exists($resourcePath)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'file not exists : ' . $resourcePath,
+            );
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+        //copy the resource on tmp directory
+        $fileNameOnTmp = $tmpDir . rand() . rand();
+        if (!copy($resourcePath, $fileNameOnTmp)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'copy on tmp failed',
+            );
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+        //now do the conversion !
+        if (strtoupper($res['format']) <> 'PDF') {
+            $resultOfConversion = $this->launchConvert(
+                $fileNameOnTmp,
+                'pdf',
+                $tmpDir,
+                pathinfo($resourcePath, PATHINFO_EXTENSION)
+            );
+        } else {
+            copy($fileNameOnTmp, $fileNameOnTmp . '.pdf');
+            $resultOfConversion = array(
+                'status' => '0',
+                'value' => '',
+                'error' => '',
+            );
+        }
+        if ($resultOfConversion['status'] <> '0') {
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+        );
+            return $resultOfConversion;
+        }
+        //copy the result on docserver
+        // LogsController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
+        $storeResult = StoreController::storeResourceOnDocServer([
+            'collId'    => $collId,
+            'fileInfos' => [
+                'tmpDir'        => $tmpDir,
+                'size'          => filesize($fileNameOnTmp),
+                'format'        => 'PDF',
+                'tmpFileName'   => pathinfo($fileNameOnTmp, PATHINFO_FILENAME) . '.pdf',
+            ],
+            'docserverTypeId'   => 'CONVERT'
+        ]);
+
+        if (empty($storeResult)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'Ds of collection and ds type not found for convert:'
+                    . $collId . ' CONVERT',
+            );
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+
+        if (!empty($storeResult['errors'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => $storeResult['errors'] . ' error for convert:'
+                    . $fileNameOnTmp,
+            );
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+
+        $targetDs = DocserverModel::getById(['id' => $storeResult['docserver_id']]);
+
+        // LogsController::info(['message'=>'avant update', 'code'=>19, ]);
+        //update the \Database
+        $resultOfUpDb = ProcessConvertModel::updateDatabase(
+            [
+                'collId'     => $collId,
+                'resTable'   => $resTable,
+                'adrTable'   => $adrTable,
+                'resId'      => $resId,
+                'docserver'  => $targetDs,
+                'path'       => $storeResult['destination_dir'],
+                'fileName'   => $storeResult['file_destination_name']
+            ]
+        );
+        // LogsController::info(['message'=>var_export($resultOfUpDb, true), 'code'=>111111, ]);
+        // LogsController::info(['message'=>$collId, 'code'=>2, ]);
+        // LogsController::info(['message'=>$resTable, 'code'=>3, ]);
+        // LogsController::info(['message'=>$adrTable, 'code'=>4, ]);
+        // LogsController::info(['message'=>$resId, 'code'=>5, ]);
+        // LogsController::info(['message'=>'apres res_id', 'code'=>6, ]);
+        // LogsController::info(['message'=>$targetDs, 'code'=>6, ]);
+        // LogsController::info(['message'=>var_export($resultCopyDs, true), 'code'=>7, ]);
+
+        if ($resultOfUpDb['status'] <> '0') {
+            ProcessConvertModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $resultOfUpDb;
+        }
+
+        unlink($fileNameOnTmp);
+        unlink($fileNameOnTmp . '.pdf');
+
+        $returnArray = array(
+            'status' => '0',
+            'value' => '',
+            'error' => '',
+        );
+        LogsController::executionTimeLog(
+            $timestart,
+            '',
+            'debug',
+            '[TIMER] Convert_ProcessConvertAbstract_Service::convert'
+        );
+        return $returnArray;
+    }
+
+    /**
+     * Launch the conversion
+     *
+     * @param string $srcfile source file
+     * @param string $tgtfmt target format
+     * @param string $tgtdir target dir
+     * @param string $srcfmt source format
+     * @return array $returnArray the result
+     */
+    public function launchConvert(
+        $srcfile,
+        $tgtfmt,
+        $tgtdir=false,
+        $srcfmt=null
+    ) {
+        $timestart=microtime(true);
+
+        $processHtml = false;
+        $executable='';
+        
+        // LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert']);
+        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
+            $processHtml = true;
+            // LogsController::info(['message'=>'[TIMER] srcfmt ' . $srcfmt]);
+            copy($srcfile, str_ireplace('.maarch', '.', $srcfile) . '.html');
+            if (file_exists('/usr/bin/mywkhtmltopdf')) {
+                $command = "mywkhtmltopdf "
+                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " "
+                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.pdf');
+            } else {
+                $envVar = "export DISPLAY=FRPAROEMINT:0.0 ; ";
+                $command = $envVar . "wkhtmltopdf "
+                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " "
+                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.pdf');
+            }
+            $executable='wkhtmltopdf';
+        } else {
+            $executable='soffice';
+            // LogsController::info(['message'=>'[TIMER] let LO do it ' . $this->libreOfficeExecutable]);
+            if ($this->libreOfficeExecutable == "cloudooo") {
+                $serverAddress = "http://192.168.21.40:8011";
+                $tokens = array();
+                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpc.inc';
+                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpcs.inc';
+                require_once 'apps/maarch_entreprise/tools/phpxmlrpc/lib/xmlrpc_wrappers.inc';
+                $fileContent = file_get_contents($srcfile, FILE_BINARY);
+                $encodedContent = base64_encode($fileContent);
+                $params = array();
+                array_push($params, new PhpXmlRpc\Value($encodedContent));
+                array_push($params, new PhpXmlRpc\Value($srcfmt));
+                array_push($params, new PhpXmlRpc\Value($tgtfmt));
+                array_push($params, new PhpXmlRpc\Value(false));
+                $v = new PhpXmlRpc\Value($params, "array");
+            } elseif ($this->libreOfficeExecutable == "unoconv") {
+                $tokens = array('"' . $this->libreOfficeExecutable . '"');
+                $tokens[] = "-f";
+                $tokens[] = $tgtfmt;
+                $tokens[] = '-o "' . $srcfile . '.' . $tgtfmt . '"';
+                $tokens[] = '"' . $srcfile . '"';
+            } else {
+                $tokens = array('"' . $this->libreOfficeExecutable . '"');
+                $tokens[] = "--headless";
+                $tokens[] = "--convert-to";
+                $tokens[] = $tgtfmt;
+                $tokens[] = '"' . $srcfile . '"';
+                if (!$tgtdir) {
+                    $tgtdir = dirname($srcfile);
+                }
+                $tokens[] = '--outdir "' . $tgtdir . '"';
+            }
+            
+            if (!$srcfmt) {
+                $tokens[] = $srcfmt;
+            }
+
+            $command = implode(' ', $tokens);
+
+            $output = array();
+            $return = null;
+            $this->errors = array();
+        }
+        //echo $command . '<br />';exit;
+        if ($this->libreOfficeExecutable == "cloudooo" && !$processHtml) {
+            // LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
+            // LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
+            $req = new PhpXmlRpc\Request('convertFile', $v);
+            //LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
+            // LogsController::info(['message'=>'[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
+            $client = new PhpXmlRpc\Client($serverAddress);
+            $resp = $client->send($req);
+            if (!$resp->faultCode()) {
+                $encoder = new PhpXmlRpc\Encoder();
+                $value = $encoder->decode($resp->value());
+                $theFile = fopen($srcfile . '.' . $tgtfmt, 'w+');
+                fwrite($theFile, base64_decode($value));
+                fclose($theFile);
+                $returnArray = array(
+                    'status' => '0',
+                    'value' => '',
+                    'error' => '',
+                );
+            } else {
+                //print "An error occurred: ";
+                //print "Code: " . htmlspecialchars($resp->faultCode())
+                //    . " Reason: '" . htmlspecialchars($resp->faultString()) . "'\n";
+                $returnArray = array(
+                    'status' => '1',
+                    'value' => '',
+                    'error' => "Code: " . htmlspecialchars($resp->faultCode())
+                        . " Reason: '" . htmlspecialchars($resp->faultString()),
+                );
+            }
+        } else {
+            $timestart_command = microtime(true);
+            exec("timeout -k 5m 3m " . $command, $output, $return);
+            // LogsController::debug(['message'=>'[TIMER] commande : ' . $command]);
+            LogsController::executionTimeLog($timestart_command, '', 'info', '[TIMER] ' . $executable . ' - Convert_ProcessConvertAbstract_Service::launchConvert__exec');
+            if ($return === 0) {
+                $returnArray = array(
+                    'status' => '0',
+                    'value' => '',
+                    'error' => '',
+                );
+            } else {
+                $returnArray = array(
+                    'status' => '1',
+                    'value' => '',
+                    'error' => $return . $output,
+                );
+            }
+        }
+        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
+            $returnArray = array();
+            unlink(str_ireplace('.maarch', '.', $srcfile) . '.html');
+            $returnArray = array(
+                'status' => '0',
+                'value' => '',
+                'error' => '',
+            );
+        }
+        LogsController::executionTimeLog(
+            $timestart,
+            '',
+            'info',
+            '[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert'
+        );
+        return $returnArray;
+    }
+}
diff --git a/modules/convert/Controllers/ProcessThumbnailsController.php b/modules/convert/Controllers/ProcessThumbnailsController.php
index 0303afaa127..2a54bff6070 100644
--- a/modules/convert/Controllers/ProcessThumbnailsController.php
+++ b/modules/convert/Controllers/ProcessThumbnailsController.php
@@ -1,345 +1,345 @@
-<?php
-
-/**
- * Copyright Maarch since 2008 under licence GPLv3.
- * See LICENCE.txt file at the root folder for more details.
- * This file is part of Maarch software.
- *
- */
-
-/**
-* @brief process thumbnails class
-*
-* <ul>
-* <li>Services to process the thumbnails of resources</li>
-* </ul>
-*
-* @file
-* @author Laurent Giovannoni <dev@maarch.org>
-* @date $date$
-* @version $Revision$
-* @ingroup convert
-*/
-
-namespace Convert\Controllers;
-
-use Attachment\Models\AttachmentModel;
-use Psr\Http\Message\RequestInterface;
-use Psr\Http\Message\ResponseInterface;
-use Resource\models\ResModel;
-use Respect\Validation\Validator;
-use Convert\Models\ProcessThumbnailsModel;
-use Docserver\models\DocserverModel;
-use Docserver\models\ResDocserverModel;
-use SrcCore\controllers\LogsController;
-use SrcCore\controllers\StoreController;
-
-class ProcessThumbnailsController
-{
-    protected $tnlExecutable;
-
-    public function __construct($tnlExecutable = 'convert')
-    {
-        $this->tnlExecutable = $tnlExecutable;
-    }
-
-    public function create(RequestInterface $request, ResponseInterface $response)
-    {
-        $data = $request->getParams();
-
-        $check = Validator::notEmpty()->validate($data['collId']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['resTable']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['adrTable']);
-        $check = $check && Validator::intType()->notEmpty()->validate($data['resId']);
-        $check = $check && Validator::stringType()->notEmpty()->validate($data['tmpDir']);
-        if (!$check) {
-            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
-        }
-
-        $return = ProcessThumbnailsController::thumbnails($data);
-
-        if (empty($return) || !empty($return['errors'])) {
-            return $response->withStatus(500)->withJson(['errors' => '[ProcessThumbnailsController create] ' . $return['errors']]);
-        }
-
-        return $response->withJson($return);
-    }
-
-    /**
-     * Ask for thumbnails
-     *
-     * @param string $collId collection
-     * @param string $resTable resource table
-     * @param string $adrTable adr table
-     * @param long $resId res_id
-     * @param string $tmpDir path to tmp
-     * @param array $tgtfmt array of target format
-     * @return array $returnArray the result
-     */
-    public function thumbnails(array $args=[])
-    {
-        $timestart = microtime(true);
-        $returnArray = array();
-        if (empty($args['collId'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'collId empty for thumbnails',
-            );
-            return $returnArray;
-        } else {
-            $collId = $args['collId'];
-        }
-        if (empty($args['resTable'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'resTable empty for thumbnails',
-            );
-            return $returnArray;
-        } else {
-            $resTable = $args['resTable'];
-        }
-        if (empty($args['adrTable'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'adrTable empty for thumbnails',
-            );
-            return $returnArray;
-        } else {
-            $adrTable = $args['adrTable'];
-        }
-        if (empty($args['resId'])) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'resId empty for thumbnails',
-            );
-            return $returnArray;
-        } else {
-            $resId = $args['resId'];
-        }
-
-        if (!isset($args['tmpDir']) || $args['tmpDir'] == '') {
-            $tmpDir = $_SESSION['config']['tmppath'];
-        } else {
-            $tmpDir = $args['tmpDir'];
-        }
-
-        if ($args['resTable'] == 'res_letterbox') {
-            $res = ResModel::getById(['resId' => $resId]);
-        } elseif ($args['resTable'] == 'res_attachments') {
-            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'false']);
-        } else {
-            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'true']);
-        }
-
-        if ($res['res_id'] <> '') {
-            $adrType = 'CONV';
-            if (
-                strtoupper($res['format']) == 'HTML' ||
-                strtoupper($res['format']) == 'MAARCH'
-            ) {
-                $adrType = 'DOC';
-            }
-            $resourcePath = ResDocserverModel::getSourceResourcePath(
-                [
-                    'resTable' => $resTable, 
-                    'adrTable' => $adrTable, 
-                    'resId'    => $res['res_id'],
-                    'adrType'  => $adrType
-                ]
-            );
-        }
-        if (!file_exists($resourcePath)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'file not already converted in pdf for thumbnails. path :' 
-                    . $resourcePath . ", adrType : CONV, adr_table : " . $adrTable,
-            );
-            ProcessThumbnailsModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-
-        //copy the resource on tmp directory
-        $fileNameOnTmp = $tmpDir . rand() . rand();
-        if (!copy($resourcePath, $fileNameOnTmp)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'copy on tmp failed for thumbnails. Copy ' . $resourcePath . ' to ' . $fileNameOnTmp,
-            );
-            ProcessThumbnailsModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-
-        //now do the thumbnails !
-        $resultOfConversion = $this->launchThumbnails(
-            $fileNameOnTmp, 
-            $tmpDir,
-            pathinfo($resourcePath, PATHINFO_EXTENSION)
-        );
-
-
-        if ($resultOfConversion['status'] <> '0') {
-            ProcessThumbnailsModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            LogsController::executionTimeLog(
-                $timestart, 
-                '', 
-                'debug', 
-                '[TIMER] Convert_ProcessThumbnailsAbstract_Service::thumbnails aucunContenuAIndexer'
-            );
-            return $resultOfConversion;
-        }
-
-        //copy the result on docserver
-        // LogsController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
-        $storeResult = StoreController::storeResourceOnDocServer([
-            'collId'    => $collId,
-            'fileInfos' => [
-                'tmpDir'        => $tmpDir,
-                'size'          => filesize($fileNameOnTmp),
-                'format'        => 'PNG',
-                'tmpFileName'   => pathinfo($fileNameOnTmp, PATHINFO_FILENAME) . '.png',
-            ],
-            'docserverTypeId'   => 'TNL'
-        ]);
-
-        if (empty($storeResult)) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => 'Ds of collection and ds type not found for thumbnails:' 
-                    . $collId . ' THUMBNAILS',
-            );
-            ProcessThumbnailsModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $returnArray;
-        }
-
-        $targetDs = DocserverModel::getById(['id' => $storeResult['docserver_id']]);
-
-        // LogsController::info(['message'=>'avant update', 'code'=>19, ]);
-        //update the Database
-        $resultOfUpDb = ProcessThumbnailsModel::updateDatabase(
-            [
-                'collId'     => $collId,
-                'resTable'   => $resTable, 
-                'adrTable'   => $adrTable, 
-                'resId'      => $resId,
-                'docserver'  => $targetDs,
-                'path'       => $storeResult['destination_dir'],
-                'fileName'   => $storeResult['file_destination_name']
-            ]
-        );
-
-        if ($resultOfUpDb['status'] <> '0') {
-            ProcessThumbnailsModel::manageErrorOnDb(
-                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
-            );
-            return $resultOfUpDb;
-        }
-
-        unlink($fileNameOnTmp);
-        unlink($fileNameOnTmp . '.png');
-
-        $returnArray = array(
-            'status' => '0',
-            'value' => '',
-            'error' => '',
-        );
-        LogsController::executionTimeLog(
-            $timestart, 
-            '', 
-            'debug', 
-            '[TIMER] Convert_ProcessThumbnailsAbstract_Service::thumbnails'
-        );
-        return $returnArray;
-    }
-
-    /**
-     * Launch the thumbnails process
-     *
-     * @param string $srcfile source file
-     * @param string $tgtdir target dir
-     * @param string $srcfmt source format
-     * @return array $returnArray the result
-     */
-    private function launchThumbnails(
-        $srcfile, 
-        $tgtdir=false, 
-        $srcfmt
-    ) {
-        $timestart = microtime(true);
-        if (!$tgtdir) {
-            $tgtdir = dirname($srcfile);
-        }
-
-        $output = array();
-        $return = null;
-        $this->errors = array();
-
-        //wkhtmltoimage must be installed with compiled sources
-        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
-            copy($srcfile, str_ireplace('.maarch', '.', $srcfile) . '.html');
-            if (file_exists('/usr/bin/mywkhtmltoimage')) {
-                $command = "mywkhtmltoimage  --width 164 --height 105 --quality 100 --zoom 0.2 " 
-                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " " 
-                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.png');
-            } else {
-                $envVar = "export DISPLAY=FRPAROEMINT:0.0 ; ";
-                $command = $envVar . "wkhtmltoimage --width 164 --height 105 --quality 100 --zoom 0.2 " 
-                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " " 
-                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.png');
-            }
-        } else {
-            $command = "convert -thumbnail 200x300 -background white -alpha remove " 
-                . escapeshellarg($srcfile) . "[0] "
-                . escapeshellarg($tgtdir . basename($srcfile) . '.png');
-        }
-        //echo $command . PHP_EOL;exit;
-        $timestart_command = microtime(true);
-        exec($command, $output, $return);
-        LogsController::debug(['message'=>'[TIMER] Commande : ' . $command]);
-        LogsController::executionTimeLog($timestart_command, '', 'debug', '[TIMER] Convert_ProcessThumbnailsAbstract_Service::launchThumbnails__exec');
-
-        if ($return === 0) {
-            $returnArray = array(
-                'status' => '0',
-                'value' => '',
-                'error' => '',
-            );
-        } else {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => $return . $output,
-            );
-        }
-        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
-            $returnArray = array();
-            unlink(str_ireplace('.maarch', '.', $srcfile) . '.html');
-            $returnArray = array(
-                'status' => '0',
-                'value' => '',
-                'error' => '',
-            );
-        }
-        LogsController::executionTimeLog(
-            $timestart, 
-            '', 
-            'debug', 
+<?php
+
+/**
+ * Copyright Maarch since 2008 under licence GPLv3.
+ * See LICENCE.txt file at the root folder for more details.
+ * This file is part of Maarch software.
+ *
+ */
+
+/**
+* @brief process thumbnails class
+*
+* <ul>
+* <li>Services to process the thumbnails of resources</li>
+* </ul>
+*
+* @file
+* @author Laurent Giovannoni <dev@maarch.org>
+* @date $date$
+* @version $Revision$
+* @ingroup convert
+*/
+
+namespace Convert\Controllers;
+
+use Attachment\Models\AttachmentModel;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Resource\models\ResModel;
+use Respect\Validation\Validator;
+use Convert\Models\ProcessThumbnailsModel;
+use Docserver\models\DocserverModel;
+use Docserver\models\ResDocserverModel;
+use SrcCore\controllers\LogsController;
+use SrcCore\controllers\StoreController;
+
+class ProcessThumbnailsController
+{
+    protected $tnlExecutable;
+
+    public function __construct($tnlExecutable = 'convert')
+    {
+        $this->tnlExecutable = $tnlExecutable;
+    }
+
+    public function create(RequestInterface $request, ResponseInterface $response)
+    {
+        $data = $request->getParams();
+
+        $check = Validator::notEmpty()->validate($data['collId']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['resTable']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['adrTable']);
+        $check = $check && Validator::intType()->notEmpty()->validate($data['resId']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['tmpDir']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $return = ProcessThumbnailsController::thumbnails($data);
+
+        if (empty($return) || !empty($return['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => '[ProcessThumbnailsController create] ' . $return['errors']]);
+        }
+
+        return $response->withJson($return);
+    }
+
+    /**
+     * Ask for thumbnails
+     *
+     * @param string $collId collection
+     * @param string $resTable resource table
+     * @param string $adrTable adr table
+     * @param long $resId res_id
+     * @param string $tmpDir path to tmp
+     * @param array $tgtfmt array of target format
+     * @return array $returnArray the result
+     */
+    public function thumbnails(array $args=[])
+    {
+        $timestart = microtime(true);
+        $returnArray = array();
+        if (empty($args['collId'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'collId empty for thumbnails',
+            );
+            return $returnArray;
+        } else {
+            $collId = $args['collId'];
+        }
+        if (empty($args['resTable'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'resTable empty for thumbnails',
+            );
+            return $returnArray;
+        } else {
+            $resTable = $args['resTable'];
+        }
+        if (empty($args['adrTable'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'adrTable empty for thumbnails',
+            );
+            return $returnArray;
+        } else {
+            $adrTable = $args['adrTable'];
+        }
+        if (empty($args['resId'])) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'resId empty for thumbnails',
+            );
+            return $returnArray;
+        } else {
+            $resId = $args['resId'];
+        }
+
+        if (!isset($args['tmpDir']) || $args['tmpDir'] == '') {
+            $tmpDir = $_SESSION['config']['tmppath'];
+        } else {
+            $tmpDir = $args['tmpDir'];
+        }
+
+        if ($args['resTable'] == 'res_letterbox') {
+            $res = ResModel::getById(['resId' => $resId]);
+        } elseif ($args['resTable'] == 'res_attachments') {
+            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'false']);
+        } else {
+            $res = AttachmentModel::getById(['id' => $resId, 'isVersion' => 'true']);
+        }
+
+        if ($res['res_id'] <> '') {
+            $adrType = 'CONV';
+            if (
+                strtoupper($res['format']) == 'HTML' ||
+                strtoupper($res['format']) == 'MAARCH'
+            ) {
+                $adrType = 'DOC';
+            }
+            $resourcePath = ResDocserverModel::getSourceResourcePath(
+                [
+                    'resTable' => $resTable,
+                    'adrTable' => $adrTable,
+                    'resId'    => $res['res_id'],
+                    'adrType'  => $adrType
+                ]
+            );
+        }
+        if (!file_exists($resourcePath)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'file not already converted in pdf for thumbnails. path :'
+                    . $resourcePath . ", adrType : CONV, adr_table : " . $adrTable,
+            );
+            ProcessThumbnailsModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+
+        //copy the resource on tmp directory
+        $fileNameOnTmp = $tmpDir . rand() . rand();
+        if (!copy($resourcePath, $fileNameOnTmp)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'copy on tmp failed for thumbnails. Copy ' . $resourcePath . ' to ' . $fileNameOnTmp,
+            );
+            ProcessThumbnailsModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+
+        //now do the thumbnails !
+        $resultOfConversion = $this->launchThumbnails(
+            $fileNameOnTmp,
+            $tmpDir,
+            pathinfo($resourcePath, PATHINFO_EXTENSION)
+        );
+
+
+        if ($resultOfConversion['status'] <> '0') {
+            ProcessThumbnailsModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            LogsController::executionTimeLog(
+                $timestart,
+                '',
+                'debug',
+                '[TIMER] Convert_ProcessThumbnailsAbstract_Service::thumbnails aucunContenuAIndexer'
+            );
+            return $resultOfConversion;
+        }
+
+        //copy the result on docserver
+        // LogsController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
+        $storeResult = StoreController::storeResourceOnDocServer([
+            'collId'    => $collId,
+            'fileInfos' => [
+                'tmpDir'        => $tmpDir,
+                'size'          => filesize($fileNameOnTmp),
+                'format'        => 'PNG',
+                'tmpFileName'   => pathinfo($fileNameOnTmp, PATHINFO_FILENAME) . '.png',
+            ],
+            'docserverTypeId'   => 'TNL'
+        ]);
+
+        if (empty($storeResult)) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => 'Ds of collection and ds type not found for thumbnails:'
+                    . $collId . ' THUMBNAILS',
+            );
+            ProcessThumbnailsModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $returnArray;
+        }
+
+        $targetDs = DocserverModel::getById(['id' => $storeResult['docserver_id']]);
+
+        // LogsController::info(['message'=>'avant update', 'code'=>19, ]);
+        //update the Database
+        $resultOfUpDb = ProcessThumbnailsModel::updateDatabase(
+            [
+                'collId'     => $collId,
+                'resTable'   => $resTable,
+                'adrTable'   => $adrTable,
+                'resId'      => $resId,
+                'docserver'  => $targetDs,
+                'path'       => $storeResult['destination_dir'],
+                'fileName'   => $storeResult['file_destination_name']
+            ]
+        );
+
+        if ($resultOfUpDb['status'] <> '0') {
+            ProcessThumbnailsModel::manageErrorOnDb(
+                ['resTable' => $resTable, 'resId' => $resId, 'result' => '-1']
+            );
+            return $resultOfUpDb;
+        }
+
+        unlink($fileNameOnTmp);
+        unlink($fileNameOnTmp . '.png');
+
+        $returnArray = array(
+            'status' => '0',
+            'value' => '',
+            'error' => '',
+        );
+        LogsController::executionTimeLog(
+            $timestart,
+            '',
+            'debug',
+            '[TIMER] Convert_ProcessThumbnailsAbstract_Service::thumbnails'
+        );
+        return $returnArray;
+    }
+
+    /**
+     * Launch the thumbnails process
+     *
+     * @param string $srcfile source file
+     * @param string $tgtdir target dir
+     * @param string $srcfmt source format
+     * @return array $returnArray the result
+     */
+    private function launchThumbnails(
+        $srcfile,
+        $tgtdir=false,
+        $srcfmt
+    ) {
+        $timestart = microtime(true);
+        if (!$tgtdir) {
+            $tgtdir = dirname($srcfile);
+        }
+
+        $output = array();
+        $return = null;
+        $this->errors = array();
+
+        //wkhtmltoimage must be installed with compiled sources
+        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
+            copy($srcfile, str_ireplace('.maarch', '.', $srcfile) . '.html');
+            if (file_exists('/usr/bin/mywkhtmltoimage')) {
+                $command = "mywkhtmltoimage  --width 164 --height 105 --quality 100 --zoom 0.2 "
+                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " "
+                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.png');
+            } else {
+                $envVar = "export DISPLAY=FRPAROEMINT:0.0 ; ";
+                $command = $envVar . "wkhtmltoimage --width 164 --height 105 --quality 100 --zoom 0.2 "
+                    . escapeshellarg(str_ireplace('.maarch', '.', $srcfile) . '.html') . " "
+                    . escapeshellarg($tgtdir . basename(str_ireplace('.maarch', '.', $srcfile)) . '.png');
+            }
+        } else {
+            $command = "convert -thumbnail 200x300 -background white -alpha remove "
+                . escapeshellarg($srcfile) . "[0] "
+                . escapeshellarg($tgtdir . basename($srcfile) . '.png');
+        }
+        //echo $command . PHP_EOL;exit;
+        $timestart_command = microtime(true);
+        exec($command, $output, $return);
+        // LogsController::debug(['message'=>'[TIMER] Commande : ' . $command]);
+        LogsController::executionTimeLog($timestart_command, '', 'debug', '[TIMER] Convert_ProcessThumbnailsAbstract_Service::launchThumbnails__exec');
+
+        if ($return === 0) {
+            $returnArray = array(
+                'status' => '0',
+                'value' => '',
+                'error' => '',
+            );
+        } else {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => $return . $output,
+            );
+        }
+        if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
+            $returnArray = array();
+            unlink(str_ireplace('.maarch', '.', $srcfile) . '.html');
+            $returnArray = array(
+                'status' => '0',
+                'value' => '',
+                'error' => '',
+            );
+        }
+        LogsController::executionTimeLog(
+            $timestart,
+            '',
+            'debug',
             '[TIMER] Convert_ProcessThumbnailsAbstract_Service::launchThumbnails
-        ');
-        return $returnArray;
-    }
-}
+        ');
+        return $returnArray;
+    }
+}
diff --git a/rest/index.php b/rest/index.php
index 38bb53df53e..ce55c4f4737 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -242,11 +242,11 @@ $app->put('/priorities/{id}', \Priority\controllers\PriorityController::class .
 $app->delete('/priorities/{id}', \Priority\controllers\PriorityController::class . ':delete');
 
 //History
-$app->get('/administration/history/eventDate/{date}', \History\controllers\HistoryController::class . ':getForAdministration'); //TODO No date
+$app->get('/administration/history/eventDate/{date}', \History\controllers\HistoryController::class . ':get'); //TODO No date
 $app->get('/histories/users/{userSerialId}', \History\controllers\HistoryController::class . ':getByUserId');
 
 //HistoryBatch
-$app->get('/administration/historyBatch/eventDate/{date}', \History\controllers\HistoryController::class . ':getBatchForAdministration');//TODO No date
+$app->get('/administration/historyBatch/eventDate/{date}', \History\controllers\HistoryBatchController::class . ':get');//TODO No date
 
 //actions
 $app->get('/actions', \Action\controllers\ActionController::class . ':get');
diff --git a/src/app/history/controllers/HistoryController.php b/src/app/history/controllers/HistoryController.php
index ee854eedaf3..cc15af2ab49 100644
--- a/src/app/history/controllers/HistoryController.php
+++ b/src/app/history/controllers/HistoryController.php
@@ -15,7 +15,7 @@
 namespace History\controllers;
 
 use Core\Models\ServiceModel;
-use SrcCore\models\TextFormatModel;
+use SrcCore\controllers\LogsController;
 use SrcCore\models\ValidatorModel;
 use History\models\HistoryModel;
 use Notification\controllers\NotificationsEventsController;
@@ -25,52 +25,22 @@ use User\models\UserModel;
 
 class HistoryController
 {
-
     public static function add(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['tableName', 'recordId', 'eventType', 'info', 'eventId']);
         ValidatorModel::stringType($aArgs, ['tableName', 'eventType', 'info', 'eventId', 'moduleId', 'level']);
 
-        if(empty($aArgs['isTech'])){
+        if (empty($aArgs['isTech'])) {
             $aArgs['isTech'] = false;
         }
-        if(empty($aArgs['moduleId'])){
+        if (empty($aArgs['moduleId'])) {
             $aArgs['moduleId'] = 'admin';
         }
-        if(empty($aArgs['level'])){
+        if (empty($aArgs['level'])) {
             $aArgs['level'] = 'DEBUG';
         }
 
-        $traceInformations = [
-            'WHERE'         => $aArgs['tableName'],
-            'ID'            => $aArgs['recordId'],
-            'HOW'           => $aArgs['eventType'],
-            'USER'          => $GLOBALS['userId'],
-            'WHAT'          => $aArgs['eventId'],
-            'ID_MODULE'     => $aArgs['moduleId'],
-            'REMOTE_IP'     => $_SERVER['REMOTE_ADDR'],
-            'LEVEL'         => $aArgs['level']
-        ];
-
-        $loggingMethods = HistoryModel::buildLoggingMethod();
-
-        foreach ($loggingMethods as $loggingMethod) {
-            if ($loggingMethod['ACTIVATED'] == true) {
-                if ($loggingMethod['ID'] == 'log4php') {
-                    if (empty($loggingMethod['LOGGER_NAME_TECH'])) {
-                        $loggingMethod['LOGGER_NAME_TECH'] = 'loggerTechnique';
-                    }
-                    if (empty($loggingMethod['LOGGER_NAME_FUNC'])) {
-                        $loggingMethod['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
-                    }
-                    HistoryController::addToLog4php([
-                        'traceInformations' => $traceInformations,
-                        'loggingMethod'     => $loggingMethod,
-                        'isTech'            => $aArgs['isTech'],
-                    ]);
-                }
-            }
-        }
+        LogsController::add($aArgs);
 
         HistoryModel::create([
             'tableName' => $aArgs['tableName'],
@@ -82,55 +52,12 @@ class HistoryController
             'eventId'   => $aArgs['eventId'],
         ]);
 
-       NotificationsEventsController::fill_event_stack([
-        "eventId"   => $aArgs['eventId'],
-        "tableName" => $aArgs['tableName'],
-        "recordId"  => $aArgs['recordId'],
-        "userId"    => $GLOBALS['userId'],
-        "info"      => $aArgs['info'],
-       ]);
-
-    }
-
-    private static function addToLog4php(array $aArgs)
-    {
-        ValidatorModel::notEmpty($aArgs, ['traceInformations', 'loggingMethod']);
-        ValidatorModel::arrayType($aArgs, ['traceInformations', 'loggingMethod']);
-
-        $logLine = str_replace(
-            [
-                '%RESULT%',
-                '%CODE_METIER%',
-                '%WHERE%',
-                '%ID%',
-                '%HOW%',
-                '%USER%',
-                '%WHAT%',
-                '%ID_MODULE%',
-                '%REMOTE_IP%'
-            ],
-            [
-                'OK',
-                $aArgs['loggingMethod']['CODE_METIER'],
-                $aArgs['traceInformations']['WHERE'],
-                $aArgs['traceInformations']['ID'],
-                $aArgs['traceInformations']['HOW'],
-                $aArgs['traceInformations']['USER'],
-                $aArgs['traceInformations']['WHAT'],
-                $aArgs['traceInformations']['ID_MODULE'],
-                $aArgs['traceInformations']['REMOTE_IP']
-            ],
-            $aArgs['loggingMethod']['LOG_FORMAT']
-        );
-
-        $loggerName = (empty($aArgs['isTech']) ? $aArgs['loggingMethod']['LOGGER_NAME_FUNC'] : $aArgs['loggingMethod']['LOGGER_NAME_TECH']);
-        $logLine = TextFormatModel::htmlWasher($logLine);
-        $logLine = TextFormatModel::removeAccent(['string' => $logLine]);
-
-        HistoryModel::writeLog([
-            'loggerName'    => $loggerName,
-            'logLine'       => $logLine,
-            'level'         => $aArgs['traceInformations']['LEVEL']
+        NotificationsEventsController::fill_event_stack([
+            "eventId"   => $aArgs['eventId'],
+            "tableName" => $aArgs['tableName'],
+            "recordId"  => $aArgs['recordId'],
+            "userId"    => $GLOBALS['userId'],
+            "info"      => $aArgs['info'],
         ]);
     }
 
@@ -146,28 +73,16 @@ class HistoryController
         return $response->withJson(['histories' => $aHistories]);
     }
 
-    public function getForAdministration(Request $request, Response $response, array $aArgs)
+    public function get(Request $request, Response $response, array $aArgs)
     {
         if (!ServiceModel::hasService(['id' => 'view_history', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
             return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
         }
 
-        $historyList = HistoryModel::getHistoryList(['event_date' => $aArgs['date']]);
-        $historyListFilters['users'] = HistoryModel::getFilter(['select' => 'user_id', 'event_date' => $aArgs['date']]);
+        $historyList                     = HistoryModel::getHistoryList(['event_date' => $aArgs['date']]);
+        $historyListFilters['users']     = HistoryModel::getFilter(['select' => 'user_id', 'event_date' => $aArgs['date']]);
         $historyListFilters['eventType'] = HistoryModel::getFilter(['select' => 'event_type', 'event_date' => $aArgs['date']]);
 
         return $response->withJson(['filters' => $historyListFilters, 'historyList' => $historyList]);
     }
-
-    public function getBatchForAdministration(Request $request, Response $response, array $aArgs)
-    {
-        if (!ServiceModel::hasService(['id' => 'view_history_batch', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
-            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
-        }
-
-        $historyList = HistoryModel::getHistoryBatchList(['event_date' => $aArgs['date']]);
-        $historyListFilters['modules'] = HistoryModel::getBatchFilter(['select' => 'module_name', 'event_date' => $aArgs['date']]);
-        
-        return $response->withJson(['filters' => $historyListFilters, 'historyList' => $historyList]);
-    }
 }
diff --git a/src/app/history/models/HistoryModelAbstract.php b/src/app/history/models/HistoryModelAbstract.php
index 4f30762c6b2..e998338dfaa 100644
--- a/src/app/history/models/HistoryModelAbstract.php
+++ b/src/app/history/models/HistoryModelAbstract.php
@@ -14,91 +14,11 @@
 
 namespace History\models;
 
-
 use SrcCore\models\ValidatorModel;
-use SrcCore\models\CoreConfigModel;
 use SrcCore\models\DatabaseModel;
 
-require_once('apps/maarch_entreprise/tools/log4php/Logger.php'); //TODO composer
-
 class HistoryModelAbstract
 {
-    public static function buildLoggingMethod()
-    {
-        $loggingMethods = [];
-
-        $customId = CoreConfigModel::getCustomId();
-        if (file_exists("custom/{$customId}/apps/maarch_entreprise/xml/logging_method.xml")) {
-            $path = "custom/{$customId}/apps/maarch_entreprise/xml/logging_method.xml";
-        } else {
-            $path = 'apps/maarch_entreprise/xml/logging_method.xml';
-        }
-
-        if (file_exists($path)) {
-            $xmlConfig = simplexml_load_file($path);
-
-            if ($xmlConfig) {
-                foreach ($xmlConfig->METHOD as $METHOD) {
-                    $loggingMethods[] = [
-                        'ID'               => (string)$METHOD->ID,
-                        'ACTIVATED'        => (boolean)$METHOD->ENABLED,
-                        'LOGGER_NAME_TECH' => (string)$METHOD->LOGGER_NAME_TECH,
-                        'LOGGER_NAME_FUNC' => (string)$METHOD->LOGGER_NAME_FUNC,
-                        'LOG_FORMAT'       => (string)$METHOD->APPLI_LOG_FORMAT,
-                        'CODE_METIER'      => (string)$METHOD->CODE_METIER
-                    ];
-                }
-            }
-        } else {
-            $loggingMethods[0]['ID']               = 'database';
-            $loggingMethods[0]['ACTIVATED']        = true;
-            $loggingMethods[1]['ID']               = 'log4php';
-            $loggingMethods[1]['ACTIVATED']        = true;
-            $loggingMethods[1]['LOGGER_NAME_TECH'] = 'loggerTechnique';
-            $loggingMethods[1]['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
-            $loggingMethods[1]['LOG_FORMAT']       = '[%RESULT%][%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%][%WHAT%][%ID_MODULE%][%REMOTE_IP%]';
-            $loggingMethods[1]['CODE_METIER']      = 'MAARCH';
-        }
-
-        return $loggingMethods;
-    }
-
-    public static function writeLog(array $aArgs)
-    {
-        ValidatorModel::notEmpty($aArgs, ['logLine', 'level', 'loggerName']);
-        ValidatorModel::stringType($aArgs, ['logLine', 'level', 'loggerName']);
-
-        $customId = CoreConfigModel::getCustomId();
-        if (file_exists("custom/{$customId}/apps/maarch_entreprise/xml/log4php.xml")) {
-            $path = "custom/{$customId}/apps/maarch_entreprise/xml/log4php.xml";
-        } else if (file_exists('apps/maarch_entreprise/xml/log4php.xml')) {
-            $path = 'apps/maarch_entreprise/xml/log4php.xml';
-        } else {
-            $path = 'apps/maarch_entreprise/xml/log4php.default.xml';
-        }
-
-        \Logger::configure($path);
-        $logger = \Logger::getLogger($aArgs['loggerName']);
-
-        switch ($aArgs['level']) {
-            case 'DEBUG':
-                $logger->debug($aArgs['logLine']);
-                break;
-            case 'INFO':
-                $logger->info($aArgs['logLine']);
-                break;
-            case 'WARN':
-                $logger->warn($aArgs['logLine']);
-                break;
-            case 'ERROR':
-                $logger->error($aArgs['logLine']);
-                break;
-            case 'FATAL':
-                $logger->fatal($aArgs['logLine']);
-                break;
-        }
-    }
-
     public static function create(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['tableName', 'recordId', 'eventType', 'userId', 'info', 'moduleId', 'eventId']);
@@ -107,44 +27,30 @@ class HistoryModelAbstract
         DatabaseModel::insert([
             'table'         => 'history',
             'columnsValues' => [
-                'table_name'    => $aArgs['tableName'],
-                'record_id'     => $aArgs['recordId'],
-                'event_type'    => $aArgs['eventType'],
-                'user_id'       => $aArgs['userId'],
-                'event_date'    => 'CURRENT_TIMESTAMP',
-                'info'          => $aArgs['info'],
-                'id_module'     => $aArgs['moduleId'],
-                'remote_ip'     => $_SERVER['REMOTE_ADDR'],
-                'event_id'      => $aArgs['eventId'],
+                'table_name' => $aArgs['tableName'],
+                'record_id'  => $aArgs['recordId'],
+                'event_type' => $aArgs['eventType'],
+                'user_id'    => $aArgs['userId'],
+                'event_date' => 'CURRENT_TIMESTAMP',
+                'info'       => $aArgs['info'],
+                'id_module'  => $aArgs['moduleId'],
+                'remote_ip'  => $_SERVER['REMOTE_ADDR'],
+                'event_id'   => $aArgs['eventId'],
             ]
         ]);
 
         return true;
     }
 
-    public static function getHistoryList(array $aArgs = [])
+    public static function get(array $aArgs = [])
     {
         ValidatorModel::notEmpty($aArgs, ['event_date']);
 
         $aReturn = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['history'],
-            'where'     => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
-            'order_by'  => ['event_date DESC']
-        ]);
-
-        return $aReturn;
-    }
-
-    public static function getHistoryBatchList(array $aArgs = [])
-    {
-        ValidatorModel::notEmpty($aArgs, ['event_date']);
-
-        $aReturn = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['history_batch'],
-            'where'     => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
-            'order_by'  => ['event_date DESC']
+            'select'   => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'    => ['history'],
+            'where'    => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
+            'order_by' => ['event_date DESC']
         ]);
 
         return $aReturn;
@@ -156,12 +62,12 @@ class HistoryModelAbstract
         ValidatorModel::stringType($aArgs, ['userId']);
 
         $aHistories = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['history'],
-            'where'     => ['user_id = ?', 'event_date > (CURRENT_TIMESTAMP - interval \'7 DAYS\')'],
-            'data'      => [$aArgs['userId']],
-            'order_by'  => ['event_date DESC'],
-            'limit'     => 200
+            'select'   => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'    => ['history'],
+            'where'    => ['user_id = ?', 'event_date > (CURRENT_TIMESTAMP - interval \'7 DAYS\')'],
+            'data'     => [$aArgs['userId']],
+            'order_by' => ['event_date DESC'],
+            'limit'    => 200
         ]);
 
         return $aHistories;
@@ -174,27 +80,10 @@ class HistoryModelAbstract
 
         $aReturn = DatabaseModel::select(
             [
-            'select'    => ['DISTINCT('.$aArgs['select'].')'],
-            'table'     => ['history'],
-            'where'     => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
-            'order_by'  => [$aArgs['select'].' ASC']
-            ]
-        );
-
-        return $aReturn;
-    }
-
-    public static function getBatchFilter(array $aArgs = [])
-    {
-        ValidatorModel::notEmpty($aArgs, ['select','event_date']);
-        ValidatorModel::stringType($aArgs, ['select']);
-
-        $aReturn = DatabaseModel::select(
-            [
-            'select'    => ['DISTINCT('.$aArgs['select'].')'],
-            'table'     => ['history_batch'],
-            'where'     => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
-            'order_by'  => [$aArgs['select'].' ASC']
+            'select'   => ['DISTINCT('.$aArgs['select'].')'],
+            'table'    => ['history'],
+            'where'    => ["event_date >= date '".$aArgs['event_date']."'","event_date < date '".$aArgs['event_date']."' + interval '1 month'"],
+            'order_by' => [$aArgs['select'].' ASC']
             ]
         );
 
diff --git a/src/core/controllers/LogsController.php b/src/core/controllers/LogsController.php
index 3e83b4ff518..51d6bcf4e80 100644
--- a/src/core/controllers/LogsController.php
+++ b/src/core/controllers/LogsController.php
@@ -17,331 +17,179 @@ namespace SrcCore\controllers;
 
 use SrcCore\models\TextFormatModel;
 use SrcCore\models\ValidatorModel;
+use SrcCore\models\CoreConfigModel;
 
-if (!defined('_LOG4PHP'))
-    define(
-        '_LOG4PHP',
-        'log4php'
-    );
-if (!defined('_LOGGER_NAME_TECH_DEFAULT'))
-    define(
-        '_LOGGER_NAME_TECH_DEFAULT',
-        'loggerTechnique'
-    );
-if (!defined('_LOGGER_NAME_FUNC_DEFAULT'))
-    define(
-        '_LOGGER_NAME_FUNC_DEFAULT',
-        'loggerFonctionnel'
-    );
+require_once 'apps/maarch_entreprise/tools/log4php/Logger.php'; //TODO composer
 
-require_once 'apps/maarch_entreprise/tools/log4php/Logger.php';
-
-//TODO Cleaning Refactoring
 class LogsController
 {
-    protected static function getLoggingMethodConfFile()
+    /*
+    timestart : timestamp Debut
+    timeend : timestamp Fin
+    level : level log4php
+    message : message dans les logs
+    */
+    public function executionTimeLog($timestart, $timeend, $level, $message)
     {
-        $xmlFileName = 'logging_method.xml';
-        if (file_exists($sLoggingMethodConfFile = 'custom'
-            .DIRECTORY_SEPARATOR.$_SESSION['custom_override_id']
-            .DIRECTORY_SEPARATOR . 'apps'
-            .DIRECTORY_SEPARATOR.$_SESSION['config']['app_id']
-            .DIRECTORY_SEPARATOR.'xml'
-            .DIRECTORY_SEPARATOR.$xmlFileName
-        )) {
-            return $sLoggingMethodConfFile;
-        }
-        if (file_exists($sLoggingMethodConfFile =
-            'apps'
-            .DIRECTORY_SEPARATOR.$_SESSION['config']['app_id']
-            .DIRECTORY_SEPARATOR.'xml'
-            .DIRECTORY_SEPARATOR.$xmlFileName
-        )) {
-            return $sLoggingMethodConfFile;
+        if (empty($timeend)) {
+            $timeend = microtime(true);
         }
+        $time = $timeend - $timestart;
 
-        return null;
-    }
-
-    public static function getLoggingFormat(array $aArgs = []) 
-    {
-        ValidatorModel::notEmpty($aArgs,['key']);
-        ValidatorModel::intVal($aArgs,['key']);
-        $logging_methods = self::getLoggingMethod($aArgs);
-        return empty($logging_methods[$aArgs['key']]['LOG_FORMAT']) ? '[%RESULT%]' 
-            . '[%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%]' 
-            . '[%WHAT%][%ID_MODULE%][%REMOTE_IP%]' : $logging_methods[$aArgs['key']]['LOG_FORMAT'];
+        self::$level(
+            ['message' => $message.'. Done in ' . number_format($time, 3) . ' secondes.']
+        );
     }
 
-    public static function getLoggingCodeMetier(array $aArgs = [])
+    public static function buildLoggingMethod()
     {
-        ValidatorModel::notEmpty($aArgs,['key']);
-        ValidatorModel::intVal($aArgs,['key']);
-        $logging_methods = self::getLoggingFormat($aArgs);
-        return empty($logging_methods[$aArgs['key']]['CODE_METIER']) ? '[%RESULT%]' 
-            . '[%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%]' 
-            . '[%WHAT%][%ID_MODULE%][%REMOTE_IP%]' : $logging_methods[$aArgs['key']]['CODE_METIER'];
-    }
+        $loggingMethods = [];
 
-    /**
-    * Get the logging method in the configuration file
-    */
-    protected static function getLoggingMethod(array $aArgs = [])
-    {
-        $sLoggingMethodConfFile = self::getLoggingMethodConfFile();
-        $logging_methods = [];
-        if ( ! $sLoggingMethodConfFile = self::getLoggingMethodConfFile() ) {
-            $logging_methods[0]['ID'] = 'database';
-            $logging_methods[0]['ACTIVATED'] = true;
-            $logging_methods[1]['ID'] = 'log4php';
-            $logging_methods[1]['ACTIVATED'] = true;
-            $logging_methods[1]['LOGGER_NAME_TECH'] = 'loggerTechnique';
-            $logging_methods[1]['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
-            $logging_methods[1]['LOG_FORMAT'] = '[%RESULT%][%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%][%WHAT%][%ID_MODULE%][%REMOTE_IP%]';
-            $logging_methods[1]['CODE_METIER'] = 'MAARCH';
-            return $logging_methods;
+        $customId = CoreConfigModel::getCustomId();
+        if (file_exists("custom/{$customId}/apps/maarch_entreprise/xml/logging_method.xml")) {
+            $path = "custom/{$customId}/apps/maarch_entreprise/xml/logging_method.xml";
+        } else {
+            $path = 'apps/maarch_entreprise/xml/logging_method.xml';
         }
 
-        if (! file_exists($sLoggingMethodConfFile) ) {
-            throw new \Exception('not file_exists : '.$sLoggingMethodConfFile);
-        }
-        $xmlConfig = @simplexml_load_file($sLoggingMethodConfFile);
-        if (! $xmlConfig) {
-            throw new \Exception('simplexml_load_file failed : '.$sLoggingMethodConfFile);
-        }
-        if (! $xmlConfig->METHOD) {
-            throw new \Exception('no data METHOD found : '.$sLoggingMethodConfFile);
+        if (file_exists($path)) {
+            $xmlConfig = simplexml_load_file($path);
+
+            if ($xmlConfig) {
+                foreach ($xmlConfig->METHOD as $METHOD) {
+                    $loggingMethods[] = [
+                        'ID'               => (string)$METHOD->ID,
+                        'ACTIVATED'        => (boolean)$METHOD->ENABLED,
+                        'LOGGER_NAME_TECH' => (string)$METHOD->LOGGER_NAME_TECH,
+                        'LOGGER_NAME_FUNC' => (string)$METHOD->LOGGER_NAME_FUNC,
+                        'LOG_FORMAT'       => (string)$METHOD->APPLI_LOG_FORMAT,
+                        'CODE_METIER'      => (string)$METHOD->CODE_METIER
+                    ];
+                }
+            }
+        } else {
+            $loggingMethods[0]['ID']               = 'database';
+            $loggingMethods[0]['ACTIVATED']        = true;
+            $loggingMethods[1]['ID']               = 'log4php';
+            $loggingMethods[1]['ACTIVATED']        = true;
+            $loggingMethods[1]['LOGGER_NAME_TECH'] = 'loggerTechnique';
+            $loggingMethods[1]['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
+            $loggingMethods[1]['LOG_FORMAT']       = '[%RESULT%][%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%][%WHAT%][%ID_MODULE%][%REMOTE_IP%]';
+            $loggingMethods[1]['CODE_METIER']      = 'MAARCH';
         }
 
-        foreach ($xmlConfig->METHOD as $METHOD) {
-            $id = ((string)$METHOD->ID);
-            $activated = ((boolean)$METHOD->ENABLED);
-            $loggerNameTech = ((string)$METHOD->LOGGER_NAME_TECH);
-            $loggerNameFunc = ((string)$METHOD->LOGGER_NAME_FUNC);
-            $logFormat = ((string)$METHOD->APPLI_LOG_FORMAT);
-            $codeMetier = ((string)$METHOD->CODE_METIER);
-
-            array_push(
-                $logging_methods,
-                array(
-                    'ID'         => $id,
-                    'ACTIVATED'  => $activated,
-                    'LOGGER_NAME_TECH' => $loggerNameTech,
-                    'LOGGER_NAME_FUNC' => $loggerNameFunc,
-                    'LOG_FORMAT'    => $logFormat,
-                    'CODE_METIER'   => $codeMetier
-                )
-            );
-        }
-        $oCache->set($sCache, $logging_methods);
-        return $logging_methods;
+        return $loggingMethods;
     }
 
-    protected static function getConfFile(array $aArgs = [])
+    public static function writeLog(array $aArgs)
     {
-        if ( empty($_SESSION['config']['app_id']) ) {
-            $_SESSION['config']['app_id'] = 'maarch_entreprise';
+        ValidatorModel::notEmpty($aArgs, ['logLine', 'level', 'loggerName']);
+        ValidatorModel::stringType($aArgs, ['logLine', 'level', 'loggerName']);
+
+        $customId = CoreConfigModel::getCustomId();
+        if (file_exists("custom/{$customId}/apps/maarch_entreprise/xml/log4php.xml")) {
+            $path = "custom/{$customId}/apps/maarch_entreprise/xml/log4php.xml";
+        } elseif (file_exists('apps/maarch_entreprise/xml/log4php.xml')) {
+            $path = 'apps/maarch_entreprise/xml/log4php.xml';
+        } else {
+            $path = 'apps/maarch_entreprise/xml/log4php.default.xml';
         }
-        if (
-            !empty($_SESSION['config']['corepath']) && !empty($_SESSION['custom_override_id'])
-            && file_exists($configFileLog4PHP =
-            $_SESSION['config']['corepath']. DIRECTORY_SEPARATOR . 'custom'
-            . DIRECTORY_SEPARATOR . $_SESSION['custom_override_id']
-            . DIRECTORY_SEPARATOR . 'apps'
-            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
-            . DIRECTORY_SEPARATOR . 'xml'
-            . DIRECTORY_SEPARATOR . 'log4php.xml'
-        )) {
-            return $configFileLog4PHP;
-        }
-        if (file_exists($configFileLog4PHP =
-            'apps'
-            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
-            . DIRECTORY_SEPARATOR . 'xml'
-            . DIRECTORY_SEPARATOR . 'log4php.xml'
-        )) {
-            return $configFileLog4PHP;
-        }
-        return 'apps'
-            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
-            . DIRECTORY_SEPARATOR . 'xml'
-            . DIRECTORY_SEPARATOR . 'log4php.default.xml';
-    }
 
-    protected static function format_message(array $aArgs)
-    {
-        $aArgs['message'] = @$aArgs['message'];
-        switch (true) {
-            case is_object($aArgs['message']):
-                if ( $aArgs['message'] instanceof \Exception ) {
-                    $e = $aArgs['message'];
-                    $aArgs['code'] = $e->getCode();
-                    $aArgs['message'] = 'Exception: '.$e->getMessage();
-                    $aArgs['debug'] = $e->getTraceAsString();
-                    break;
-                }
-                $aArgs['message'] = '--object--';
+        \Logger::configure($path);
+        $logger = \Logger::getLogger($aArgs['loggerName']);
+
+        switch ($aArgs['level']) {
+            case 'DEBUG':
+                $logger->debug($aArgs['logLine']);
                 break;
-            case is_array($aArgs['message']):
-                $aArgs['message'] = '--array--';
+            case 'INFO':
+                $logger->info($aArgs['logLine']);
                 break;
-            default:
-                $aArgs['message'] = (string) $aArgs['message'];
+            case 'WARN':
+                $logger->warn($aArgs['logLine']);
+                break;
+            case 'ERROR':
+                $logger->error($aArgs['logLine']);
+                break;
+            case 'FATAL':
+                $logger->fatal($aArgs['logLine']);
                 break;
         }
-        $aArgs['message'] = str_replace("\n", '\n', $aArgs['message']);
-
-        // Old method :
-        $aArgs['message'] = TextFormatModel::htmlWasher($aArgs['message'], '');
-        $aArgs['message'] = TextFormatModel::removeAccent(['string' => $aArgs['message']]);
-
-        if(!empty($_SESSION['user']['UserId'])){
-            $aArgs['message'] = '[' . $_SESSION['user']['UserId'] . '] ' . $aArgs['message'];
-        }
-
-        return $aArgs;
     }
 
-    protected static function logs(array $aArgs = [])
+    protected static function addToLog4php(array $aArgs)
     {
-        // Initialisation du Logger :
-        \Logger::configure(
-            self::getConfFile()
+        ValidatorModel::notEmpty($aArgs, ['traceInformations', 'loggingMethod']);
+        ValidatorModel::arrayType($aArgs, ['traceInformations', 'loggingMethod']);
+
+        $logLine = str_replace(
+            [
+                '%RESULT%',
+                '%CODE_METIER%',
+                '%WHERE%',
+                '%ID%',
+                '%HOW%',
+                '%USER%',
+                '%WHAT%',
+                '%ID_MODULE%',
+                '%REMOTE_IP%'
+            ],
+            [
+                'OK',
+                $aArgs['loggingMethod']['CODE_METIER'],
+                $aArgs['traceInformations']['WHERE'],
+                $aArgs['traceInformations']['ID'],
+                $aArgs['traceInformations']['HOW'],
+                $aArgs['traceInformations']['USER'],
+                $aArgs['traceInformations']['WHAT'],
+                $aArgs['traceInformations']['ID_MODULE'],
+                $aArgs['traceInformations']['REMOTE_IP']
+            ],
+            $aArgs['loggingMethod']['LOG_FORMAT']
         );
-        if ( @$aArgs['class'] ) {
-            \Logger::getLogger($aArgs['class']);
-        }
-        $aLoggingMethods = self::getLoggingMethod();
 
-        $aArgs = self::format_message($aArgs);
-            if ( @$aArgs['class'] ) {
-                $sLog .= "[class:{$aArgs['class']}]";
-                \Logger::getLogger($aArgs['class']);
-            }
+        $loggerName = (empty($aArgs['isTech']) ? $aArgs['loggingMethod']['LOGGER_NAME_FUNC'] : $aArgs['loggingMethod']['LOGGER_NAME_TECH']);
+        $logLine    = TextFormatModel::htmlWasher($logLine);
+        $logLine    = TextFormatModel::removeAccent(['string' => $logLine]);
 
-        foreach ($aLoggingMethods as $logging_method) {
-            if ( ! $logging_method['ACTIVATED'] ) {
-                continue;
-            }
-
-            if (isset($aArgs['isTech']) && $aArgs['isTech']) {
-                $logger = \Logger::getLogger(
-                    $logging_method['LOGGER_NAME_TECH']
-                );
-            } else {
-                if(!isset($logging_method['LOGGER_NAME_FUNC'])){
-                    $logging_method['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
-                }
-                $logger = \Logger::getLogger(
-                    $logging_method['LOGGER_NAME_FUNC']
-                );
-            }
-            if ( empty($logger) ) {
-                throw new \Exception('logger not-loading', 1);
-            }
-            // Format :
-            $sLog = '';
-            if ( @$aArgs['file'] ) {
-                $sLog .= "[file:{$aArgs['file']}]";
-            }
-            if ( @$aArgs['class'] ) {
-                $sLog .= "[class:{$aArgs['class']}]";
-            }
-            if ( @$aArgs['function'] ) {
-                $sLog .= "[function:{$aArgs['function']}]";
-            }
-            if ( @$aArgs['code'] ) {
-                $aArgs['code'] = (int)$aArgs['code'];
-                $sLog .= "[code:{$aArgs['code']}]";
-            }
-
-            if(!isset($logging_method['CODE_METIER'])){
-                $logging_method['CODE_METIER'] = 'SIPol';
-            }
-            $sLog = str_replace(
-                '%CODE_METIER%', 
-                $logging_method['CODE_METIER'], 
-                "{$sLog}{$aArgs['message']}"
-            );
-
-            // Log :
-            switch ($aArgs['type']) {
-                case 'debug':
-                case _LEVEL_DEBUG:
-                    $logger->debug($sLog);
-                    break;
-
-                case 'info':
-                case _LEVEL_INFO:
-                    $logger->info($sLog);
-                    break;
-
-                case 'warning':
-                case _LEVEL_WARN:
-                    $logger->warn($sLog);
-                    break;
-
-                case 'error':
-                case _LEVEL_ERROR:
-                    $logger->error($sLog);
-                    break;
-
-                case _LEVEL_FATAL:
-                    $logger->fatal($sLog);
-                    break;
-
-                default:
-                    $logger->error($sLog);
-            }
-        }
-        return true;
-    }
-
-    public static function debug(array $aArgs = [])
-    {
-        $aArgs['type'] = 'debug';
-        return self::logs($aArgs);
-    }
-
-    public static function info(array $aArgs = [])
-    {
-        $aArgs['type'] = 'info';
-        return self::logs($aArgs);
-    }
-
-    public static function warning(array $aArgs = [])
-    {
-        $aArgs['type'] = 'warning';
-        return self::logs($aArgs);
-    }
-
-    public static function error(array $aArgs = [])
-    {
-        $aArgs['type'] = 'error';
-        return self::logs($aArgs);
+        LogsController::writeLog([
+            'loggerName' => $loggerName,
+            'logLine'    => $logLine,
+            'level'      => $aArgs['traceInformations']['LEVEL']
+        ]);
     }
 
-    public static function fatal(array $aArgs = [])
-    {
-        $aArgs['type'] = _LEVEL_FATAL;
-        return self::logs($aArgs);
-    }
-
-    /*
-    timestart : timestamp Debut
-    timeend : timestamp Fin
-    level : level log4php
-    message : message dans les logs
-    */
-    public function executionTimeLog($timestart, $timeend, $level, $message)
+    public static function add(array $aArgs)
     {
-        if (empty($timeend)){
-            $timeend = microtime(true);
+        $traceInformations = [
+            'WHERE'     => $aArgs['tableName'],
+            'ID'        => $aArgs['recordId'],
+            'HOW'       => $aArgs['eventType'],
+            'USER'      => $GLOBALS['userId'],
+            'WHAT'      => $aArgs['eventId'],
+            'ID_MODULE' => $aArgs['moduleId'],
+            'REMOTE_IP' => $_SERVER['REMOTE_ADDR'],
+            'LEVEL'     => $aArgs['level']
+        ];
+
+        $loggingMethods = LogsController::buildLoggingMethod();
+
+        foreach ($loggingMethods as $loggingMethod) {
+            if ($loggingMethod['ACTIVATED'] == true) {
+                if ($loggingMethod['ID'] == 'log4php') {
+                    if (empty($loggingMethod['LOGGER_NAME_TECH'])) {
+                        $loggingMethod['LOGGER_NAME_TECH'] = 'loggerTechnique';
+                    }
+                    if (empty($loggingMethod['LOGGER_NAME_FUNC'])) {
+                        $loggingMethod['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
+                    }
+                    LogsController::addToLog4php([
+                        'traceInformations' => $traceInformations,
+                        'loggingMethod'     => $loggingMethod,
+                        'isTech'            => $aArgs['isTech'],
+                    ]);
+                }
+            }
         }
-        $time = $timeend - $timestart;
-
-        self::$level(
-            ['message' => $message.'. Done in ' . number_format($time, 3) . ' secondes.']
-        );
     }
 }
-- 
GitLab