2
0

document.class.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. <?php
  2. /**
  3. * Classe document
  4. *
  5. * Cette classe gère les documents, y compris leur création, mise à jour, suppression,
  6. * gestion des fichiers joints, et envoi d'emails liés aux documents.
  7. */
  8. class document
  9. {
  10. /**
  11. * Télécharge un fichier temporaire et l'enregistre dans le répertoire des données des documents.
  12. *
  13. * @param array $_temp Tableau contenant les informations du fichier temporaire.
  14. * @return string|false Retourne le chemin du fichier enregistré ou FALSE en cas d'échec.
  15. */
  16. static public function uploadFile(array $_temp){
  17. $tmp = file::record($_temp, DIR_DATAS_DOCS);
  18. if($tmp != FALSE){
  19. return $tmp;
  20. } else {
  21. return FALSE;
  22. }
  23. }
  24. /**
  25. * Lit un fichier spécifique à partir du répertoire des données des documents.
  26. *
  27. * @param string $_id Identifiant du fichier à lire.
  28. * @return string Retourne le contenu du fichier.
  29. */
  30. static public function readFile(string $_id){
  31. return file::download($_id, DIR_DATAS_DOCS);
  32. }
  33. /**
  34. * Supprime un fichier spécifique du répertoire des données des documents.
  35. *
  36. * @param string $_id Identifiant du fichier à supprimer.
  37. * @return void
  38. */
  39. static public function deleteFile(string $_id){
  40. db::query("DELETE FROM ". DB_T_DOCUMENT_FILES ." WHERE id_files = :id_files");
  41. db::bind(':id_files', $_id);
  42. db::execute();
  43. file::delete($_id, DIR_DATAS_DOCS);
  44. }
  45. /**
  46. * Supprime tous les fichiers associés à un document spécifique.
  47. *
  48. * @param float $_id Identifiant du document.
  49. * @return void
  50. */
  51. static public function deleteFiles(float $_id){
  52. foreach (self::getFiles($_id) as $file) {
  53. db::query("DELETE FROM ". DB_T_DOCUMENT_FILES ." WHERE id_files = :id_files");
  54. db::bind(':id_files', $file["id"]);
  55. db::execute();
  56. file::delete($file["id"], DIR_DATAS_DOCS);
  57. }
  58. }
  59. /**
  60. * Récupère les types de documents disponibles.
  61. *
  62. * @return array Retourne un tableau associatif des types de documents.
  63. */
  64. static public function getTypes(){
  65. db::query("SELECT "
  66. . "id, label "
  67. . "FROM " . DB_T_TYPE_DOCUMENT . " "
  68. . "ORDER BY " . DB_T_TYPE_DOCUMENT . ".id ASC");
  69. foreach (db::resultset() as $value) {
  70. $return[$value["id"]] = $value["label"];
  71. }
  72. return $return;
  73. }
  74. /**
  75. * Supprime un document spécifique et ses fichiers associés.
  76. *
  77. * @param float $_id Identifiant du document à supprimer.
  78. * @return bool Retourne TRUE en cas de succès, FALSE en cas d'échec.
  79. */
  80. public static function delete(float $_id)
  81. {
  82. try {
  83. db::query("DELETE FROM ". DB_T_DOCUMENT_TAGS ." WHERE id_documents = :id_documents");
  84. db::bind(':id_documents', $_id);
  85. db::execute();
  86. self::deleteFiles($_id);
  87. db::query("DELETE FROM " . DB_T_DOCUMENTS . " WHERE id = :id");
  88. db::bind(':id', $_id);
  89. db::execute();
  90. alert::recSuccess("Le document vient d'être supprimé");
  91. return TRUE;
  92. } catch (Exception $ex) {
  93. alert::recError("Erreur à la suppression du document");
  94. return FALSE;
  95. }
  96. }
  97. /**
  98. * Récupère l'identifiant du dernier document ajouté.
  99. *
  100. * @return int Identifiant du dernier document.
  101. */
  102. public static function lastAdd()
  103. {
  104. db::query("SELECT MAX(id) AS id FROM " . DB_T_DOCUMENTS);
  105. return db::single()["id"];
  106. }
  107. /**
  108. * Ajoute un fichier à un document spécifique.
  109. *
  110. * @param float $_idDocument Identifiant du document.
  111. * @param string $_idFile Identifiant du fichier.
  112. * @param int|null $_principal Indique si le fichier est principal (1) ou non (0).
  113. * @return bool Retourne TRUE en cas de succès, FALSE en cas d'échec.
  114. */
  115. private static function addFile(float $_idDocument, string $_idFile, int $_principal = NULL)
  116. {
  117. db::query("INSERT INTO " . DB_T_DOCUMENT_FILES . " (id_documents, id_files, principal) VALUES (:id_documents, :id_files, :principal)");
  118. db::bind(':id_documents', $_idDocument);
  119. db::bind(':id_files', $_idFile);
  120. db::bind(':principal', $_principal);
  121. try {
  122. db::execute();
  123. return TRUE;
  124. } catch (Exception $ex) {
  125. echo "error";
  126. echo $ex;
  127. exit();
  128. return FALSE;
  129. }
  130. }
  131. /**
  132. * Ajoute des tags à un document spécifique.
  133. *
  134. * @param float $_idDocument Identifiant du document.
  135. * @param string|null $_tags Liste des tags séparés par des virgules.
  136. * @param float $_type Type des tags.
  137. * @return bool Retourne TRUE en cas de succès, FALSE en cas d'échec.
  138. */
  139. private static function addTags(float $_idDocument, string $_tags = NULL, float $_type)
  140. {
  141. db::query("DELETE FROM " . DB_T_DOCUMENT_TAGS . " WHERE id_documents = :id_documents AND id_type_tags = :id_type_tags");
  142. db::bind(':id_documents', $_idDocument);
  143. db::bind(':id_type_tags', $_type);
  144. db::execute();
  145. if($_tags != NULL){
  146. $tags = explode(",", $_tags);
  147. $sqlMaj = "";
  148. foreach ($tags as $tag) {
  149. $sqlMaj .= " (:id_documents, ".$tag.", :id_type_tags),";
  150. }
  151. $sqlMaj = substr($sqlMaj, 0, -1);
  152. db::query("INSERT INTO " . DB_T_DOCUMENT_TAGS . " (id_documents, id_tags, id_type_tags) VALUES" . $sqlMaj);
  153. db::bind(':id_documents', $_idDocument);
  154. db::bind(':id_type_tags', $_type);
  155. try {
  156. db::execute();
  157. return TRUE;
  158. } catch (Exception $ex) {
  159. return FALSE;
  160. }
  161. }
  162. }
  163. /**
  164. * Récupère les tags orphelins (non associés à des documents).
  165. *
  166. * @return array Retourne un tableau des tags orphelins.
  167. */
  168. public static function getOrphanTags(){
  169. db::query("SELECT
  170. " . DB_T_TAGS . ".id
  171. FROM " . DB_T_TAGS . "
  172. LEFT JOIN " . DB_T_DOCUMENT_TAGS . " ON tags.id = " . DB_T_DOCUMENT_TAGS . ".id_tags
  173. WHERE " . DB_T_DOCUMENT_TAGS . ".id_tags IS NULL AND " . DB_T_TAGS . ".id_type = 2");
  174. return db::resultset();
  175. }
  176. /**
  177. * Supprime les tags orphelins de la base de données.
  178. *
  179. * @return void
  180. */
  181. public static function cleanOrphanTags(){
  182. foreach (self::getOrphanTags() as $value) {
  183. db::query("DELETE FROM ". DB_T_TAGS ." WHERE id = :id");
  184. db::bind(':id', $value["id"]);
  185. db::execute();
  186. }
  187. }
  188. /**
  189. * Ajoute un nouveau document avec ses fichiers et tags associés.
  190. *
  191. * @return int|false Retourne l'identifiant du document ajouté ou FALSE en cas d'échec.
  192. */
  193. public static function add()
  194. {
  195. session::setTemp(core::getPost(), "document");
  196. $file = core::getFiles("document-import");
  197. $checkFile = file::getErrorUpload($file);
  198. if(isset($checkFile["status"]) AND $checkFile["status"] == "error"){
  199. alert::recError($checkFile["description"]);
  200. return FALSE;
  201. }
  202. $md5 = md5_file($file["tmp_name"]);
  203. if(file::findM5($md5) == TRUE){
  204. alert::recError("Ce fichier a déjà été utilisé : " . $file["name"]);
  205. } else {
  206. db::query("INSERT INTO " . DB_T_DOCUMENTS . " (id_type, titre, date, deadline, description, montant, rapprochement, id_client, id_user) VALUES (:id_type, :titre, :date, :deadline, :description, :montant, :rapprochement, :id_client, :id_user)");
  207. db::bind(':id_type', core::getPost("id_type"));
  208. db::bind(':titre', core::getPost("titre"));
  209. db::bind(':date', core::getPost("date"));
  210. db::bind(':deadline', core::getPost("deadline"));
  211. db::bind(':description', core::getPost("description"));
  212. db::bind(':montant', !empty(core::getPost("montant")) ? floatval(core::getPost("montant")) : 0.0);
  213. db::bind(':rapprochement', core::getPost("rapprochement"));
  214. db::bind(':id_client', core::getPost("id_client") == "" ? NULL : core::getPost("id_client"));
  215. db::bind(':id_user', session::getId());
  216. try {
  217. db::execute();
  218. $lastId = db::lastInsertId();
  219. } catch (Exception $ex) {
  220. alert::recError("Erreur à l'enregistrement de la fiche : " . core::getPost("titre"));
  221. if(debug::isFile("debug")) { alert::recError("Stack : " . $ex); }
  222. return FALSE;
  223. }
  224. try {
  225. $idFile = self::uploadFile($file);
  226. } catch (Exception $ex) {
  227. alert::recError("Erreur à l'enregistrement de la pièce jointe : " . $idFile);
  228. if(debug::isFile("debug")) { alert::recError("Stack : " . $ex); }
  229. return FALSE;
  230. }
  231. try {
  232. self::addFile($lastId, $idFile, 1);
  233. } catch (Exception $ex) {
  234. alert::recError("Erreur à l'enregistrement de la liaison : " . $idFile);
  235. if(debug::isFile("debug")) { alert::recError("Stack : " . $ex); }
  236. return FALSE;
  237. }
  238. try {
  239. $tagsUser = tags::textToId(core::getPost("tagsUser"), 1);
  240. self::addTags($lastId, $tagsUser, 1);
  241. $tagsSupplier = tags::textToId(core::getPost("tagsSupplier"), 2);
  242. self::addTags($lastId, $tagsSupplier, 2);
  243. } catch (Exception $ex) {
  244. alert::recError("Erreur à l'enregistrement de la liaison : " . $idFile);
  245. if(debug::isFile("debug")) { alert::recError("Stack : " . $ex); }
  246. return FALSE;
  247. }
  248. return $lastId;
  249. }
  250. }
  251. /**
  252. * Met à jour un document existant, y compris ses fichiers et tags associés.
  253. *
  254. * @return bool Retourne TRUE en cas de succès, FALSE en cas d'échec.
  255. */
  256. public static function update()
  257. {
  258. $file = core::getFiles("attachement-document");
  259. if($file != NULL AND $file["name"] != ""){
  260. $checkFile = file::getErrorUpload($file);
  261. if(isset($checkFile["status"]) AND $checkFile["status"] == "error"){
  262. alert::recError($checkFile["description"]);
  263. return FALSE;
  264. }
  265. $md5 = md5_file($file["tmp_name"]);
  266. }
  267. if(isset($md5) AND file::findM5($md5) == TRUE){
  268. alert::recError("Le fichier \"" . $file["name"] . "\" a déjà été utilisé");
  269. session::setTemp(core::getPost(), "document");
  270. } else {
  271. if(isset($md5)){
  272. try {
  273. $idFile = self::uploadFile($file);
  274. } catch (Exception $ex) {
  275. alert::recError("Erreur à l'enregistrement de la pièce jointe : " . $idFile);
  276. return FALSE;
  277. }
  278. try {
  279. self::addFile(core::getPost("id"), $idFile, 0);
  280. } catch (Exception $ex) {
  281. alert::recError("Erreur à l'enregistrement de la liaison : " . $idFile);
  282. return FALSE;
  283. }
  284. }
  285. if(core::getPost("delete-attachement")){
  286. foreach (core::getPost("delete-attachement") as $deleteAttach) {
  287. self::deleteFile($deleteAttach);
  288. }
  289. }
  290. if(core::getPost("default-attachement")){
  291. self::principalFile(core::getPost("id"), core::getPost("default-attachement"));
  292. }
  293. try {
  294. $tagsUser = tags::textToId(core::getPost("tagsUser"), 1);
  295. self::addTags(core::getPost("id"), $tagsUser, 1);
  296. $tagsSupplier = tags::textToId(core::getPost("tagsSupplier"), 2);
  297. self::addTags(core::getPost("id"), $tagsSupplier, 2);
  298. } catch (Exception $ex) {
  299. alert::recError("Erreur à l'enregistrement de la liaison : " . core::getPost("id"));
  300. return FALSE;
  301. }
  302. if(core::ifPost("date_done") AND core::getPost("date_done") != ""){
  303. $sql = ", id_user_done = :id_user_done, date_done = :date_done ";
  304. } else {
  305. $sql = "";
  306. }
  307. db::query("UPDATE " . DB_T_DOCUMENTS . " SET "
  308. . "id_type = :id_type, "
  309. . "titre = :titre, "
  310. . "date = :date, "
  311. . "deadline = :deadline, "
  312. . "description = :description, "
  313. . "montant = :montant, "
  314. . "rapprochement = :rapprochement, "
  315. . "id_client = :id_client "
  316. . $sql
  317. . "WHERE id = :id");
  318. db::bind(':id_type', core::getPost("id_type"));
  319. db::bind(':titre', core::getPost("titre"));
  320. db::bind(':date', core::getPost("date"));
  321. db::bind(':deadline', core::getPost("deadline"));
  322. db::bind(':description', core::getPost("description"));
  323. db::bind(':montant', core::getPost("montant"));
  324. db::bind(':rapprochement', core::getPost("rapprochement"));
  325. db::bind(':id_client', core::getPost("id_client") == "" ? NULL : core::getPost("id_client"));
  326. db::bind(':id', core::getPost("id"));
  327. if(core::ifPost("date_done") AND core::getPost("date_done") == TRUE){
  328. db::bind(':id_user_done', session::getId());
  329. db::bind(':date_done', core::getPost("date_done"));
  330. }
  331. try {
  332. db::execute();
  333. alert::recSuccess("Document mis à jour avec succès");
  334. return TRUE;
  335. } catch (Exception $ex) {
  336. alert::recError("Erreur de mise à jour du document : " . $ex);
  337. return FALSE;
  338. }
  339. }
  340. }
  341. /**
  342. * Imprime un fichier spécifique.
  343. *
  344. * @param string $_id Identifiant du fichier à imprimer.
  345. * @return void
  346. */
  347. static public function printFile(string $_id) {
  348. $filePatch = file::download($_id, DIR_DATAS_DOCS);
  349. if (file_exists($filePatch) && is_readable($filePatch)) {
  350. $file_info = new finfo(FILEINFO_MIME_TYPE);
  351. $mime_type = $file_info->file($filePatch);
  352. // Vérification si le fichier est de type XML
  353. if ($mime_type === 'application/xml' || $mime_type === 'text/xml') {
  354. // Chargement du contenu XML
  355. $xml_content = file_get_contents($filePatch);
  356. xml::print($xml_content);
  357. } else {
  358. // Si ce n'est pas un fichier XML, comportement normal pour servir le fichier
  359. header('Content-Type: ' . $mime_type);
  360. header('Content-Length: ' . filesize($filePatch));
  361. readfile($filePatch);
  362. }
  363. } else {
  364. echo "Le fichier n'a pas été trouvé ou n'est pas lisible.";
  365. }
  366. }
  367. /**
  368. * Récupère un fichier spécifique.
  369. *
  370. * @param string $_id Identifiant du fichier à récupérer.
  371. * @return void
  372. */
  373. static public function getFile(string $_id) {
  374. $filePatch = file::download($_id, DIR_DATAS_DOCS);
  375. if (file_exists($filePatch) && is_readable($filePatch)) {
  376. $file_info = new finfo(FILEINFO_MIME_TYPE);
  377. $mime_type = $file_info->file($filePatch);
  378. header('Content-Type: ' . $mime_type);
  379. header('Content-Length: ' . filesize($filePatch));
  380. readfile($filePatch);
  381. } else {
  382. echo "Le fichier n'a pas été trouvé ou n'est pas lisible.";
  383. }
  384. }
  385. /**
  386. * Récupère les informations d'un document spécifique.
  387. *
  388. * @param float $_id Identifiant du document.
  389. * @return array Retourne un tableau contenant les informations du document et ses fichiers associés.
  390. */
  391. static public function get(float $_id){
  392. db::query("SELECT "
  393. . "" . DB_T_DOCUMENTS . ".id, "
  394. . "" . DB_T_DOCUMENTS . ".id_type, "
  395. . "" . DB_T_DOCUMENTS . ".titre, "
  396. . "" . DB_T_DOCUMENTS . ".date, "
  397. . "" . DB_T_DOCUMENTS . ".deadline, "
  398. . "" . DB_T_DOCUMENTS . ".description, "
  399. . "" . DB_T_DOCUMENTS . ".montant, "
  400. . "" . DB_T_DOCUMENTS . ".rapprochement, "
  401. . "" . DB_T_DOCUMENTS . ".id_client, "
  402. . "" . DB_T_DOCUMENTS . ".id_user_done, "
  403. . "" . DB_T_DOCUMENTS . ".date_done, "
  404. . "CONCAT(" . DB_T_USER . ".prenom, ' ', " . DB_T_USER . ".nom) AS doneUser "
  405. . "FROM " . DB_T_DOCUMENTS . " "
  406. . "LEFT JOIN " . DB_T_USER . " ON " . DB_T_USER . ".id = " . DB_T_DOCUMENTS . ".id_user_done "
  407. . "WHERE " . DB_T_DOCUMENTS . ".id = :id");
  408. db::bind(':id', $_id);
  409. $document = db::single();
  410. if(empty($document)){
  411. $document = [];
  412. }
  413. $document["tagsSupplier"] = self::getTags($_id, 2);
  414. $document["tagsUser"] = self::getTags($_id, 1);
  415. $files = self::getFiles($_id);
  416. return array("document" => $document, "files" => $files);
  417. }
  418. /**
  419. * Récupère les tags associés à un document spécifique.
  420. *
  421. * @param float $_idDocument Identifiant du document.
  422. * @param float $_idTypeTags Type des tags.
  423. * @return string|null Retourne une chaîne de caractères contenant les tags ou NULL si aucun tag n'est trouvé.
  424. */
  425. static public function getTags(float $_idDocument, float $_idTypeTags){
  426. db::query("SELECT "
  427. . "" . DB_T_TAGS . ".label "
  428. . "FROM " . DB_T_DOCUMENT_TAGS . " "
  429. . "INNER JOIN " . DB_T_TAGS . " ON " . DB_T_TAGS . ".id = " . DB_T_DOCUMENT_TAGS . ".id_tags "
  430. . "WHERE " . DB_T_DOCUMENT_TAGS . ".id_documents = :idDocument AND " . DB_T_DOCUMENT_TAGS . ".id_type_tags = :idTypeTags "
  431. . "ORDER BY " . DB_T_DOCUMENT_TAGS . ".creer ASC");
  432. db::bind(':idDocument', $_idDocument);
  433. db::bind(':idTypeTags', $_idTypeTags);
  434. $tmp = db::resultset();
  435. if(isset($tmp[0])){
  436. $return = NULL;
  437. foreach ($tmp as $value) {
  438. $return .= $value["label"].",";
  439. }
  440. $return = substr($return, 0, -1);
  441. return $return;
  442. } else {
  443. return NULL;
  444. }
  445. }
  446. /**
  447. * Récupère les fichiers associés à un document spécifique.
  448. *
  449. * @param float $_idDocument Identifiant du document.
  450. * @return array|null Retourne un tableau des fichiers ou NULL si aucun fichier n'est trouvé.
  451. */
  452. static public function getFiles(float $_idDocument){
  453. db::query("SELECT "
  454. . "" . DB_T_FILES . ".id, "
  455. . "" . DB_T_FILES . ".name, "
  456. . "" . DB_T_FILES . ".size, "
  457. . "" . DB_T_FILES . ".creer, "
  458. . "" . DB_T_FILES . ".id_user, "
  459. . "CONCAT(" . DB_T_USER . ".prenom, ' ', " . DB_T_USER . ".nom) AS user, "
  460. . "" . DB_T_DOCUMENT_FILES . ".principal "
  461. . "FROM " . DB_T_DOCUMENT_FILES . " "
  462. . "INNER JOIN " . DB_T_FILES . " ON " . DB_T_FILES . ".id = " . DB_T_DOCUMENT_FILES . ".id_files "
  463. . "INNER JOIN " . DB_T_USER . " ON " . DB_T_USER . ".id = " . DB_T_FILES . ".id_user "
  464. . "WHERE " . DB_T_DOCUMENT_FILES . ".id_documents = :id "
  465. . "ORDER BY " . DB_T_FILES . ".creer");
  466. db::bind(':id', $_idDocument);
  467. $tmp = db::resultset();
  468. if(isset($tmp[0])){
  469. foreach ($tmp as $file) {
  470. if($file["principal"] == TRUE){
  471. $return["principal"] = $file;
  472. } else {
  473. $return[] = $file;
  474. }
  475. }
  476. if(empty($return["principal"])){
  477. $return["principal"] = $return[0];
  478. self::principalFile($_idDocument, $return["principal"]["id"]);
  479. unset($return[0]);
  480. }
  481. return $return;
  482. } else {
  483. return NULL;
  484. }
  485. }
  486. /**
  487. * Définit un fichier comme principal pour un document spécifique.
  488. *
  489. * @param float $_idDocument Identifiant du document.
  490. * @param string $_idFile Identifiant du fichier à définir comme principal.
  491. * @return void
  492. */
  493. static public function principalFile(float $_idDocument, string $_idFile){
  494. db::query("UPDATE " . DB_T_DOCUMENT_FILES . " SET principal = :principal WHERE id_documents = :id_documents");
  495. db::bind(':principal', 0);
  496. db::bind(':id_documents', $_idDocument);
  497. db::execute();
  498. db::query("UPDATE " . DB_T_DOCUMENT_FILES . " SET principal = :principal WHERE id_documents = :id_documents AND id_files = :id_files");
  499. db::bind(':principal', 1);
  500. db::bind(':id_documents', $_idDocument);
  501. db::bind(':id_files', $_idFile);
  502. db::execute();
  503. }
  504. /**
  505. * Récupère les documents assignés à un utilisateur spécifique.
  506. *
  507. * @param float|null $_id Identifiant de l'utilisateur (facultatif).
  508. * @return array Retourne un tableau des documents assignés.
  509. */
  510. static public function getAssign(float $_id = NULL){
  511. $idUser = is_null($_id) ? session::getId() : $_id;
  512. $tags = user::getIdTags($idUser);
  513. $where = NULL;
  514. foreach ($tags AS $key => $value) {
  515. if($key == 0){
  516. $where = " WHERE " . DB_T_DOCUMENTS . ".id_user_done IS NULL AND (" . DB_T_DOCUMENT_TAGS . ".id_tags = " . $value . "";
  517. } else {
  518. $where .= " OR " . DB_T_DOCUMENT_TAGS . ".id_tags = " . $value . "";
  519. }
  520. }
  521. $where .= ")";
  522. db::query("SELECT
  523. " . DB_T_DOCUMENTS . ".id,
  524. " . DB_T_DOCUMENTS . ".titre,
  525. " . DB_T_DOCUMENTS . ".date,
  526. " . DB_T_DOCUMENTS . ".deadline,
  527. " . DB_T_DOCUMENTS . ".description,
  528. " . DB_T_DOCUMENTS . ".montant,
  529. ( SELECT GROUP_CONCAT(" . DB_T_TAGS . ".label SEPARATOR ', ')
  530. FROM " . DB_T_DOCUMENT_TAGS . "
  531. INNER JOIN " . DB_T_TAGS . " ON " . DB_T_TAGS . ".id = " . DB_T_DOCUMENT_TAGS . ".id_tags
  532. WHERE id_documents = " . DB_T_DOCUMENTS . ".id AND " . DB_T_DOCUMENT_TAGS . ".id_type_tags = 2
  533. ORDER BY " . DB_T_DOCUMENT_TAGS . ".creer) AS tags,
  534. ( SELECT GROUP_CONCAT(" . DB_T_TAGS . ".label SEPARATOR ', ')
  535. FROM " . DB_T_DOCUMENT_TAGS . "
  536. INNER JOIN " . DB_T_TAGS . " ON " . DB_T_TAGS . ".id = " . DB_T_DOCUMENT_TAGS . ".id_tags
  537. WHERE id_documents = " . DB_T_DOCUMENTS . ".id AND " . DB_T_DOCUMENT_TAGS . ".id_type_tags = 1
  538. ORDER BY " . DB_T_DOCUMENT_TAGS . ".creer) AS assign,
  539. " . DB_T_TYPE_DOCUMENT . ".label
  540. FROM " . DB_T_DOCUMENT_TAGS . "
  541. INNER JOIN " . DB_T_DOCUMENTS . " ON " . DB_T_DOCUMENTS . ".id = " . DB_T_DOCUMENT_TAGS . ".id_documents
  542. INNER JOIN " . DB_T_TYPE_DOCUMENT . " ON " . DB_T_TYPE_DOCUMENT . ".id = " . DB_T_DOCUMENTS . ".id_type
  543. " . $where .
  544. " GROUP BY documents.id");
  545. return db::resultset();
  546. }
  547. /**
  548. * Affiche les pièces jointes d'un document sous forme de liste HTML.
  549. *
  550. * @param array $_attachs Tableau des pièces jointes.
  551. * @return void
  552. */
  553. static public function printAttachement(array $_attachs){
  554. $principal = $_attachs["principal"];
  555. echo '<ol class="list-group list-group-numbered">';
  556. echo ' <li class="list-group-item d-flex justify-content-between align-items-start" id="attach-'.$principal["id"].'">
  557. <div class="ms-2 me-auto">
  558. <div><span class="fw-bold">'.$principal["name"].'</span> ('.core::convertBytes($principal["size"]).')</div>
  559. Chargé le '.core::convertDate($principal["creer"]).' par '.$principal["user"].'
  560. <div id="select-attach-'.$principal["id"].'" style="color:red;"></div>
  561. </div>
  562. <div class="btn-group">
  563. <button type="button" title="Voir le document" class="btn btn btn-outline-secondary" onclick="window.open(\'/document.php?id=' . $principal["id"] . '\', \'_blank\')">' . icon::getFont(["icon" => "bi bi-eye-fill"]) . '</button>
  564. <button type="button" title="Télécharger le document" class="btn btn btn-outline-secondary" onclick="downloadFile(\'/document.php?id=' . $principal["id"] . '&download=1\', \''.$principal["name"].'\')">' . icon::getFont(["icon" => "bi bi-arrow-down-square-fill"]) . '</button>
  565. </div>
  566. </li>';
  567. foreach ($_attachs as $key => $attach) {
  568. if($key != "principal"){
  569. echo ' <li class="list-group-item d-flex justify-content-between align-items-start" id="attach-'.$attach["id"].'">
  570. <div class="ms-2 me-auto">
  571. <div><span class="fw-bold">'.$attach["name"].'</span> ('.core::convertBytes($attach["size"]).')</div>
  572. Chargé le '.core::convertDate($attach["creer"]).' par '.$attach["user"].'
  573. <div id="select-attach-'.$attach["id"].'"></div>
  574. </div><div class="btn-group">
  575. <button type="button" title="Voir le document" class="btn btn btn-outline-secondary" onclick="window.open(\'/document.php?id=' . $attach["id"] . '\', \'_blank\')">' . icon::getFont(["icon" => "bi bi-eye-fill"]) . '</button>
  576. <button type="button" title="Télécharger le document" class="btn btn btn-outline-secondary" onclick="downloadFile(\'/document.php?id=' . $attach["id"] . '&download=1\', \''.$attach["name"].'\')">' . icon::getFont(["icon" => "bi bi-arrow-down-square-fill"]) . '</button>';
  577. if (access::ifAccesss("add-document")) {
  578. echo '<button type="button" title="Document mis en avant" class="btn btn btn-outline-primary" onclick="defaultAttachment(\''.$attach["id"].'\')" id="button-default-'.$attach["id"].'">' . icon::getFont(["icon" => "bi bi-star-fill"]) . '</button>
  579. <button type="button" title="Supprimer ce document" class="btn btn-outline-danger" onclick="deleteAttachment(\''.$attach["id"].'\')" id="button-delete-'.$attach["id"].'">' . icon::getFont(["icon" => "bi bi-trash"]) . '</button>';
  580. }
  581. echo '</div>
  582. </li>';
  583. }
  584. }
  585. echo '</ol><br />';
  586. }
  587. /**
  588. * Récupère les documents assignés à un utilisateur en fonction de ses tags.
  589. *
  590. * @param array|null $_tags Tableau des tags de l'utilisateur.
  591. * @return int|null Retourne le nombre de documents assignés ou NULL si aucun document n'est trouvé.
  592. */
  593. static public function myAssign(?array $_tags = NULL){
  594. if($_tags == NULL){
  595. return NULL;
  596. } else {
  597. $where = NULL;
  598. foreach ($_tags AS $key => $value) {
  599. if($key == 0){
  600. $where = "WHERE " . DB_T_DOCUMENTS . ".id_user_done IS NULL AND (" . DB_T_DOCUMENT_TAGS . ".id_tags = " . $value . "";
  601. } else {
  602. $where .= " OR " . DB_T_DOCUMENT_TAGS . ".id_tags = " . $value . "";
  603. }
  604. }
  605. $where .= ")";
  606. }
  607. db::query("SELECT "
  608. . "COUNT(" . DB_T_DOCUMENT_TAGS . ".id_tags) AS nb "
  609. . "FROM " . DB_T_DOCUMENT_TAGS . " "
  610. . "INNER JOIN " . DB_T_DOCUMENTS . " ON " . DB_T_DOCUMENTS . ".id = " . DB_T_DOCUMENT_TAGS . ".id_documents "
  611. . $where);
  612. return db::single()["nb"];
  613. }
  614. /**
  615. * Retourne une alerte pour les documents assignés.
  616. *
  617. * @return int|null Retourne le nombre de documents assignés ou NULL si aucun document n'est trouvé.
  618. */
  619. static public function badgeAlert(){
  620. $return = self::myAssign(user::getIdTags(session::getId()));
  621. return $return > 0 ? $return : NULL;
  622. }
  623. /**
  624. * Récupère les utilisateurs assignés à un document pour l'envoi d'emails.
  625. *
  626. * @return array Retourne un tableau des utilisateurs assignés.
  627. */
  628. static public function assignMailDocument(){
  629. db::query("SELECT "
  630. . "" . DB_T_USER . ".id, "
  631. . "" . DB_T_USER . ".email, "
  632. . "CONCAT(" . DB_T_USER . ".prenom, ' ', " . DB_T_USER . ".nom) AS name "
  633. . "FROM " . DB_T_USER_TAGS . " "
  634. . "INNER JOIN " . DB_T_USER . " ON " . DB_T_USER . ".id = " . DB_T_USER_TAGS . ".id_user "
  635. . "WHERE (" . DB_T_USER_TAGS . ".id_tags = 1 OR " . DB_T_USER_TAGS . ".id_tags = 2) AND " . DB_T_USER . ".deleted = 0 "
  636. . "GROUP BY " . DB_T_USER . ".id");
  637. return db::resultset();
  638. }
  639. /**
  640. * Envoie un email récapitulatif des documents assignés à un utilisateur.
  641. *
  642. * @param array $_data Données nécessaires pour l'envoi de l'email.
  643. * @return void
  644. */
  645. public static function sendEmailCronAssign(array $_data)
  646. {
  647. $list = self::getAssign($_data["id"]);
  648. $nb = count($list);
  649. if ($nb > 0) {
  650. $titre = $nb > 1 ? $nb . " documents en attentes de validation" : "Un document en attente de validation";
  651. $message = "Cet email est un récapitulatif des documents qui vous ont été assignés sur le CMS du CSE Invent.<br />A ce jour ";
  652. $message .= $nb > 1 ? $nb . " documents sont en attentes de validation." : "un seul document est en attente de validation.";
  653. $message .= "<br />Ce bilan sera mis à jour une fois par semaine et sera envoyé à l'ensemble des personnes assignées à ces documents.";
  654. $tmp = [
  655. "name" => $_data["name"],
  656. "subject" => $titre,
  657. "message" => $message,
  658. "table" => self::getMailArray($list)
  659. ];
  660. $data = [
  661. "to" => $_data["email"],
  662. "name" => $_data["name"],
  663. "subject" => $titre,
  664. "template" => self::templateMail($tmp)
  665. ];
  666. try {
  667. email::send($data);
  668. historique::recRef("script");
  669. historique::add(
  670. array(
  671. "idType" => historique::getIdRef("CRON"),
  672. "idUser" => NULL,
  673. "idPage" => historique::getIdRef("script"),
  674. "log" => "Email d'assignation envoyé à " . $data["name"]
  675. )
  676. );
  677. } catch (\Throwable $th) {
  678. debug::log($th);
  679. }
  680. }
  681. }
  682. /**
  683. * Génère un template d'email pour les documents assignés.
  684. *
  685. * @param array $_data Données nécessaires pour générer le template.
  686. * @return string|false Retourne le template généré ou FALSE en cas d'échec.
  687. */
  688. public static function templateMail(array $_data)
  689. {
  690. $logo_url = empty($_data["logo_url"]) ? "https://" . DOMAIN_CMS . "/img/logo.png" : $_data["logo_url"];
  691. $date = empty($_data["date"]) ? core::printDateTxt() : $_data["date"];
  692. $name = empty($_data["name"]) ? NULL : $_data["name"];
  693. $subject = empty($_data["subject"]) ? NULL : $_data["subject"];
  694. $message = empty($_data["message"]) ? NULL : $_data["message"];
  695. $cms_url = empty($_data["cms_url"]) ? "https://" . DOMAIN_CMS : $_data["cms_url"];
  696. $table = empty($_data["table"]) ? NULL : $_data["table"];
  697. $template = email::loadTemplate('cms.documents.html');
  698. if ($template === false) {
  699. echo "Impossible de lire le template d'email.";
  700. return false;
  701. }
  702. // Remplacer les variables dans le template
  703. $template = str_replace([
  704. '{{logo_url}}',
  705. '{{date}}',
  706. '{{name}}',
  707. '{{subject}}',
  708. '{{message}}',
  709. '{{cms_url}}',
  710. '{{table}}'
  711. ], [
  712. $logo_url,
  713. $date,
  714. $name,
  715. $subject,
  716. $message,
  717. $cms_url,
  718. $table
  719. ], $template);
  720. // Si debug
  721. if(debug::isFile("email")){
  722. debug::log($template);
  723. }
  724. return $template;
  725. }
  726. /**
  727. * Génère un tableau HTML pour les emails assignés.
  728. *
  729. * @param array $_array Tableau des données des documents.
  730. * @return string Retourne le tableau HTML généré.
  731. */
  732. private static function getMailArray(array $_array){
  733. $return = NULL;
  734. foreach ($_array as $value) {
  735. $return .= ' <tr>
  736. <td>' . core::convertDate($value["date"], FALSE) . '</td>
  737. <td>' . $value["titre"] . '</td>
  738. <td>' . $value["label"] . '</td>
  739. <td>' . $value["deadline"] . '</td>
  740. <td>' . $value["assign"] . '</td>
  741. <td style="text-align:right;">' . core::formatEuro($value["montant"]) . '</td>
  742. </tr>';
  743. }
  744. return $return;
  745. }
  746. }