notify.class.php 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. <?php
  2. /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
  5. * Copyright (C) 2018 Philippe Grand <philippe.grand@atoo-net.com>
  6. * Copyright (C) 2021 Thibault FOUCART <support@ptibogxiv.net>
  7. * Copyright (C) 2022 Anthony Berton <anthony.berton@bb2a.fr>
  8. * Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  22. */
  23. /**
  24. * \file htdocs/core/class/notify.class.php
  25. * \ingroup notification
  26. * \brief File of class to manage notifications
  27. */
  28. require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  29. /**
  30. * Class to manage notifications
  31. */
  32. class Notify
  33. {
  34. /**
  35. * @var int ID
  36. */
  37. public $id;
  38. /**
  39. * @var DoliDB Database handler.
  40. */
  41. public $db;
  42. /**
  43. * @var string Error code (or message)
  44. */
  45. public $error = '';
  46. /**
  47. * @var string[] Error codes (or messages)
  48. */
  49. public $errors = array();
  50. public $author;
  51. public $ref;
  52. public $date;
  53. public $duree;
  54. public $note;
  55. /**
  56. * @var int Project ID
  57. */
  58. public $fk_project;
  59. // This codes actions are defined into table llx_notify_def
  60. public static $arrayofnotifsupported = array(
  61. 'BILL_VALIDATE',
  62. 'BILL_PAYED',
  63. 'ORDER_CREATE',
  64. 'ORDER_VALIDATE',
  65. 'ORDER_CLOSE',
  66. 'PROPAL_VALIDATE',
  67. 'PROPAL_CLOSE_SIGNED',
  68. 'PROPAL_CLOSE_REFUSED',
  69. 'FICHINTER_VALIDATE',
  70. 'FICHINTER_CLOSE',
  71. 'FICHINTER_ADD_CONTACT',
  72. 'ORDER_SUPPLIER_VALIDATE',
  73. 'ORDER_SUPPLIER_APPROVE',
  74. 'ORDER_SUPPLIER_SUBMIT',
  75. 'ORDER_SUPPLIER_REFUSE',
  76. 'SHIPPING_VALIDATE',
  77. 'EXPENSE_REPORT_VALIDATE',
  78. 'EXPENSE_REPORT_APPROVE',
  79. 'HOLIDAY_VALIDATE',
  80. 'HOLIDAY_APPROVE',
  81. 'ACTION_CREATE'
  82. );
  83. /**
  84. * Constructor
  85. *
  86. * @param DoliDB $db Database handler
  87. */
  88. public function __construct($db)
  89. {
  90. $this->db = $db;
  91. }
  92. /**
  93. * Return message that say how many notification (and to which email) will occurs on requested event.
  94. * This is to show confirmation messages before event is recorded.
  95. *
  96. * @param string $action Id of action in llx_c_action_trigger
  97. * @param int $socid Id of third party
  98. * @param Object $object Object the notification is about
  99. * @return string Message
  100. */
  101. public function confirmMessage($action, $socid, $object)
  102. {
  103. global $conf, $langs;
  104. $langs->load("mails");
  105. // Get full list of all notifications subscribed for $action, $socid and $object
  106. $listofnotiftodo = $this->getNotificationsArray($action, $socid, $object, 0);
  107. if (getDolGlobalString('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_USER')) {
  108. foreach ($listofnotiftodo as $val) {
  109. if ($val['type'] == 'touser') {
  110. unset($listofnotiftodo[$val['email']]);
  111. //$listofnotiftodo = array_merge($listofnotiftodo);
  112. }
  113. }
  114. }
  115. if (getDolGlobalString('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT')) {
  116. foreach ($listofnotiftodo as $val) {
  117. if ($val['type'] == 'tocontact') {
  118. unset($listofnotiftodo[$val['email']]);
  119. //$listofnotiftodo = array_merge($listofnotiftodo);
  120. }
  121. }
  122. }
  123. if (getDolGlobalString('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_FIX')) {
  124. foreach ($listofnotiftodo as $val) {
  125. if ($val['type'] == 'tofixedemail') {
  126. unset($listofnotiftodo[$val['email']]);
  127. //$listofnotiftodo = array_merge($listofnotiftodo);
  128. }
  129. }
  130. }
  131. $texte = '';
  132. $nb = -1;
  133. if (is_array($listofnotiftodo)) {
  134. $nb = count($listofnotiftodo);
  135. }
  136. if ($nb < 0) {
  137. $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("ErrorFailedToGetListOfNotificationsToSend");
  138. } elseif ($nb == 0) {
  139. $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("NoNotificationsWillBeSent");
  140. } elseif ($nb == 1) {
  141. $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("ANotificationsWillBeSent");
  142. } elseif ($nb >= 2) {
  143. $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("SomeNotificationsWillBeSent", $nb);
  144. }
  145. if (is_array($listofnotiftodo)) {
  146. $i = 0;
  147. foreach ($listofnotiftodo as $val) {
  148. if ($i) {
  149. $texte .= ', ';
  150. } else {
  151. $texte .= ' (';
  152. }
  153. if ($val['isemailvalid']) {
  154. $texte .= $val['email'];
  155. } else {
  156. $texte .= $val['emaildesc'];
  157. }
  158. $i++;
  159. }
  160. if ($i) {
  161. $texte .= ')';
  162. }
  163. }
  164. return $texte;
  165. }
  166. /**
  167. * Return number of notifications activated for action code (and third party)
  168. *
  169. * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
  170. * @param int $socid Id of third party or 0 for all thirdparties or -1 for no thirdparties
  171. * @param Object $object Object the notification is about (need it to check threshold value of some notifications)
  172. * @param int $userid Id of user or 0 for all users or -1 for no users
  173. * @param array $scope Scope where to search
  174. * @return array|int Return integer <0 if KO, array of notifications to send if OK
  175. */
  176. public function getNotificationsArray($notifcode, $socid = 0, $object = null, $userid = 0, $scope = array('thirdparty', 'user', 'global'))
  177. {
  178. global $conf, $user;
  179. $error = 0;
  180. $resarray = array();
  181. $valueforthreshold = 0;
  182. if (is_object($object)) {
  183. $valueforthreshold = $object->total_ht;
  184. }
  185. $sqlnotifcode = '';
  186. if ($notifcode) {
  187. if (is_numeric($notifcode)) {
  188. $sqlnotifcode = " AND n.fk_action = ".((int) $notifcode); // Old usage
  189. } else {
  190. $sqlnotifcode = " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
  191. }
  192. }
  193. if (!$error) {
  194. if ($socid >= 0 && in_array('thirdparty', $scope)) {
  195. $sql = "SELECT a.code, c.email, c.rowid";
  196. $sql .= " FROM ".$this->db->prefix()."notify_def as n,";
  197. $sql .= " ".$this->db->prefix()."socpeople as c,";
  198. $sql .= " ".$this->db->prefix()."c_action_trigger as a,";
  199. $sql .= " ".$this->db->prefix()."societe as s";
  200. $sql .= " WHERE n.fk_contact = c.rowid";
  201. $sql .= " AND a.rowid = n.fk_action";
  202. $sql .= " AND n.fk_soc = s.rowid";
  203. $sql .= $sqlnotifcode;
  204. $sql .= " AND s.entity IN (".getEntity('societe').")";
  205. if ($socid > 0) {
  206. $sql .= " AND s.rowid = ".((int) $socid);
  207. }
  208. dol_syslog(__METHOD__." ".$notifcode.", ".$socid, LOG_DEBUG);
  209. $resql = $this->db->query($sql);
  210. if ($resql) {
  211. $num = $this->db->num_rows($resql);
  212. $i = 0;
  213. while ($i < $num) {
  214. $obj = $this->db->fetch_object($resql);
  215. if ($obj) {
  216. $newval2 = trim($obj->email);
  217. $isvalid = isValidEmail($newval2);
  218. if (empty($resarray[$newval2])) {
  219. $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
  220. }
  221. }
  222. $i++;
  223. }
  224. } else {
  225. $error++;
  226. $this->error = $this->db->lasterror();
  227. }
  228. }
  229. }
  230. if (!$error) {
  231. if ($userid >= 0 && in_array('user', $scope)) {
  232. $sql = "SELECT a.code, c.email, c.rowid";
  233. $sql .= " FROM ".$this->db->prefix()."notify_def as n,";
  234. $sql .= " ".$this->db->prefix()."user as c,";
  235. $sql .= " ".$this->db->prefix()."c_action_trigger as a";
  236. $sql .= " WHERE n.fk_user = c.rowid";
  237. $sql .= " AND a.rowid = n.fk_action";
  238. $sql .= $sqlnotifcode;
  239. $sql .= " AND c.entity IN (".getEntity('user').")";
  240. if ($userid > 0) {
  241. $sql .= " AND c.rowid = ".((int) $userid);
  242. }
  243. dol_syslog(__METHOD__." ".$notifcode.", ".$socid, LOG_DEBUG);
  244. $resql = $this->db->query($sql);
  245. if ($resql) {
  246. $num = $this->db->num_rows($resql);
  247. $i = 0;
  248. while ($i < $num) {
  249. $obj = $this->db->fetch_object($resql);
  250. if ($obj) {
  251. $newval2 = trim($obj->email);
  252. $isvalid = isValidEmail($newval2);
  253. if (empty($resarray[$newval2])) {
  254. $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
  255. }
  256. }
  257. $i++;
  258. }
  259. } else {
  260. $error++;
  261. $this->error = $this->db->lasterror();
  262. }
  263. }
  264. }
  265. if (!$error) {
  266. if (in_array('global', $scope)) {
  267. // List of notifications enabled for fixed email
  268. foreach ($conf->global as $key => $val) {
  269. if ($notifcode) {
  270. if ($val == '' || !preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) {
  271. continue;
  272. }
  273. } else {
  274. if ($val == '' || !preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) {
  275. continue;
  276. }
  277. }
  278. $threshold = (float) $reg[1];
  279. if ($valueforthreshold < $threshold) {
  280. continue;
  281. }
  282. $tmpemail = explode(',', $val);
  283. foreach ($tmpemail as $key2 => $val2) {
  284. $newval2 = trim($val2);
  285. if ($newval2 == '__SUPERVISOREMAIL__') {
  286. if ($user->fk_user > 0) {
  287. $tmpuser = new User($this->db);
  288. $tmpuser->fetch($user->fk_user);
  289. if ($tmpuser->email) {
  290. $newval2 = trim($tmpuser->email);
  291. } else {
  292. $newval2 = '';
  293. }
  294. } else {
  295. $newval2 = '';
  296. }
  297. }
  298. if ($newval2) {
  299. $isvalid = isValidEmail($newval2, 0);
  300. if (empty($resarray[$newval2])) {
  301. $resarray[$newval2] = array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid);
  302. }
  303. }
  304. }
  305. }
  306. }
  307. }
  308. if ($error) {
  309. return -1;
  310. }
  311. //var_dump($resarray);
  312. return $resarray;
  313. }
  314. /**
  315. * Check if notification are active for couple action/company.
  316. * If yes, send mail and save trace into llx_notify.
  317. *
  318. * @param string $notifcode Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
  319. * @param Object $object Object the notification deals on
  320. * @param array $filename_list List of files to attach (full path of filename on file system)
  321. * @param array $mimetype_list List of MIME type of attached files
  322. * @param array $mimefilename_list List of attached file name in message
  323. * @return int Return integer <0 if KO, or number of changes if OK
  324. */
  325. public function send($notifcode, $object, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array())
  326. {
  327. global $user, $conf, $langs, $mysoc;
  328. global $hookmanager;
  329. global $dolibarr_main_url_root;
  330. global $action;
  331. // Complete the array Notify::$arrayofnotifsupported
  332. if (!is_object($hookmanager)) {
  333. include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
  334. $hookmanager = new HookManager($this->db);
  335. }
  336. $hookmanager->initHooks(array('notification'));
  337. $parameters = array('notifcode' => $notifcode);
  338. $reshook = $hookmanager->executeHooks('notifsupported', $parameters, $object, $action);
  339. if (empty($reshook)) {
  340. if (!empty($hookmanager->resArray['arrayofnotifsupported'])) {
  341. Notify::$arrayofnotifsupported = array_merge(Notify::$arrayofnotifsupported, $hookmanager->resArray['arrayofnotifsupported']);
  342. }
  343. }
  344. // If the trigger code is not managed by the Notification module
  345. if (!in_array($notifcode, Notify::$arrayofnotifsupported)) {
  346. return 0;
  347. }
  348. include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  349. dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object id=".$object->id);
  350. $langs->load("other");
  351. // Define $urlwithroot
  352. $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
  353. $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  354. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  355. // Define some vars
  356. $application = 'Dolibarr';
  357. if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
  358. $application = $conf->global->MAIN_APPLICATION_TITLE;
  359. }
  360. $replyto = $conf->notification->email_from;
  361. $object_type = '';
  362. $link = '';
  363. $num = 0;
  364. $error = 0;
  365. $oldref = (empty($object->oldref) ? $object->ref : $object->oldref);
  366. $newref = (empty($object->newref) ? $object->ref : $object->newref);
  367. $sql = '';
  368. // Check notification per third party
  369. if (!empty($object->socid) && $object->socid > 0) {
  370. $sql .= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
  371. $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
  372. $sql .= " FROM ".$this->db->prefix()."socpeople as c,";
  373. $sql .= " ".$this->db->prefix()."c_action_trigger as a,";
  374. $sql .= " ".$this->db->prefix()."notify_def as n,";
  375. $sql .= " ".$this->db->prefix()."societe as s";
  376. $sql .= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
  377. $sql .= " AND n.fk_soc = s.rowid";
  378. $sql .= " AND c.statut = 1";
  379. if (is_numeric($notifcode)) {
  380. $sql .= " AND n.fk_action = ".((int) $notifcode); // Old usage
  381. } else {
  382. $sql .= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
  383. }
  384. $sql .= " AND s.rowid = ".((int) $object->socid);
  385. $sql .= "\nUNION\n";
  386. }
  387. // Check notification per user
  388. $sql .= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
  389. $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
  390. $sql .= " FROM ".$this->db->prefix()."user as c,";
  391. $sql .= " ".$this->db->prefix()."c_action_trigger as a,";
  392. $sql .= " ".$this->db->prefix()."notify_def as n";
  393. $sql .= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
  394. $sql .= " AND c.statut = 1";
  395. if (is_numeric($notifcode)) {
  396. $sql .= " AND n.fk_action = ".((int) $notifcode); // Old usage
  397. } else {
  398. $sql .= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
  399. }
  400. // Check notification fixed
  401. // TODO Move part found after, into a sql here
  402. // Loop on all notifications enabled
  403. $result = $this->db->query($sql);
  404. if ($result) {
  405. $num = $this->db->num_rows($result);
  406. $projtitle = '';
  407. if (is_object($object->project) || $object->fetch_project() > 0) {
  408. $projtitle = '('.$object->project->title.')';
  409. }
  410. if ($num > 0) {
  411. $i = 0;
  412. while ($i < $num && !$error) { // For each notification couple defined (third party/actioncode)
  413. $obj = $this->db->fetch_object($result);
  414. $sendto = dolGetFirstLastname($obj->firstname, $obj->lastname)." <".$obj->email.">";
  415. $notifcodedefid = $obj->adid;
  416. $trackid = '';
  417. if ($obj->type_target == 'tocontactid') {
  418. $trackid = 'ctc'.$obj->cid;
  419. }
  420. if ($obj->type_target == 'touserid') {
  421. $trackid = 'use'.$obj->cid;
  422. }
  423. if (dol_strlen($obj->email)) {
  424. // Set output language
  425. $outputlangs = $langs;
  426. if ($obj->default_lang && $obj->default_lang != $langs->defaultlang) {
  427. $outputlangs = new Translate('', $conf);
  428. $outputlangs->setDefaultLang($obj->default_lang);
  429. $outputlangs->loadLangs(array("main", "other"));
  430. }
  431. $appli = $mysoc->name;
  432. $subject = '['.$appli.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification").($projtitle ? ' '.$projtitle : '');
  433. switch ($notifcode) {
  434. case 'BILL_VALIDATE':
  435. $link = '<a href="'.$urlwithroot.'/compta/facture/card.php?facid='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  436. $dir_output = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice');
  437. $object_type = 'facture';
  438. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated", $link);
  439. break;
  440. case 'BILL_PAYED':
  441. $link = '<a href="'.$urlwithroot.'/compta/facture/card.php?facid='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  442. $dir_output = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice');
  443. $object_type = 'facture';
  444. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed", $link);
  445. break;
  446. case 'ORDER_VALIDATE':
  447. $link = '<a href="'.$urlwithroot.'/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  448. $dir_output = $conf->commande->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'commande');
  449. $object_type = 'order';
  450. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated", $link);
  451. break;
  452. case 'ORDER_CLOSE':
  453. $link = '<a href="'.$urlwithroot.'/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  454. $dir_output = $conf->commande->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'commande');
  455. $object_type = 'order';
  456. $labeltouse = $conf->global->ORDER_CLOSE_TEMPLATE;
  457. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderClose", $link);
  458. break;
  459. case 'PROPAL_VALIDATE':
  460. $link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  461. $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
  462. $object_type = 'propal';
  463. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated", $link);
  464. break;
  465. case 'PROPAL_CLOSE_REFUSED':
  466. $link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  467. $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
  468. $object_type = 'propal';
  469. $labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
  470. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefused", $link);
  471. if (!empty($object->context['closedfromonlinesignature'])) {
  472. $mesg .= ' - From online page';
  473. }
  474. break;
  475. case 'PROPAL_CLOSE_SIGNED':
  476. $link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  477. $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
  478. $object_type = 'propal';
  479. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
  480. if (!empty($object->context['closedfromonlinesignature'])) {
  481. $mesg .= ' - From online page';
  482. }
  483. break;
  484. case 'FICHINTER_ADD_CONTACT':
  485. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  486. $dir_output = $conf->ficheinter->dir_output;
  487. $object_type = 'ficheinter';
  488. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact", $link);
  489. break;
  490. case 'FICHINTER_VALIDATE':
  491. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  492. $dir_output = $conf->ficheinter->dir_output;
  493. $object_type = 'ficheinter';
  494. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated", $link);
  495. break;
  496. case 'FICHINTER_CLOSE':
  497. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  498. $dir_output = $conf->ficheinter->dir_output;
  499. $object_type = 'ficheinter';
  500. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionClosed", $link);
  501. break;
  502. case 'ORDER_SUPPLIER_VALIDATE':
  503. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  504. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  505. $object_type = 'order_supplier';
  506. $labeltouse = isset($conf->global->ORDER_SUPPLIER_VALIDATE_TEMPLATE) ? $conf->global->ORDER_SUPPLIER_VALIDATE_TEMPLATE : '';
  507. $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
  508. $mesg .= $outputlangs->transnoentitiesnoconv("EMailTextSupplierOrderValidatedBy", $link, $user->getFullName($outputlangs));
  509. $mesg .= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
  510. break;
  511. case 'ORDER_SUPPLIER_APPROVE':
  512. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  513. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  514. $object_type = 'order_supplier';
  515. $labeltouse = isset($conf->global->ORDER_SUPPLIER_APPROVE_TEMPLATE) ? $conf->global->ORDER_SUPPLIER_APPROVE_TEMPLATE : '';
  516. $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
  517. $mesg .= $outputlangs->transnoentitiesnoconv("EMailTextSupplierOrderApprovedBy", $link, $user->getFullName($outputlangs));
  518. $mesg .= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
  519. break;
  520. case 'ORDER_SUPPLIER_SUBMIT':
  521. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  522. $dir_output = $conf->fournisseur->commande->dir_output;
  523. $object_type = 'order_supplier';
  524. $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
  525. $mesg .= $outputlangs->transnoentitiesnoconv("EMailTextSupplierOrderSubmittedBy", $link, $user->getFullName($outputlangs));
  526. $mesg .= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
  527. break;
  528. case 'ORDER_SUPPLIER_REFUSE':
  529. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  530. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  531. $object_type = 'order_supplier';
  532. $labeltouse = isset($conf->global->ORDER_SUPPLIER_REFUSE_TEMPLATE) ? $conf->global->ORDER_SUPPLIER_REFUSE_TEMPLATE : '';
  533. $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
  534. $mesg .= $outputlangs->transnoentitiesnoconv("EMailTextSupplierOrderRefusedBy", $link, $user->getFullName($outputlangs));
  535. $mesg .= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
  536. break;
  537. case 'SHIPPING_VALIDATE':
  538. $link = '<a href="'.$urlwithroot.'/expedition/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  539. $dir_output = $conf->expedition->dir_output."/sending/".get_exdir(0, 0, 0, 1, $object, 'shipment');
  540. $object_type = 'shipping';
  541. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated", $link);
  542. break;
  543. case 'EXPENSE_REPORT_VALIDATE':
  544. $link = '<a href="'.$urlwithroot.'/expensereport/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  545. $dir_output = $conf->expensereport->dir_output;
  546. $object_type = 'expensereport';
  547. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $link);
  548. break;
  549. case 'EXPENSE_REPORT_APPROVE':
  550. $link = '<a href="'.$urlwithroot.'/expensereport/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  551. $dir_output = $conf->expensereport->dir_output;
  552. $object_type = 'expensereport';
  553. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $link);
  554. break;
  555. case 'HOLIDAY_VALIDATE':
  556. $link = '<a href="'.$urlwithroot.'/holiday/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  557. $dir_output = $conf->holiday->dir_output;
  558. $object_type = 'holiday';
  559. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated", $link);
  560. break;
  561. case 'HOLIDAY_APPROVE':
  562. $link = '<a href="'.$urlwithroot.'/holiday/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  563. $dir_output = $conf->holiday->dir_output;
  564. $object_type = 'holiday';
  565. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link);
  566. break;
  567. case 'ACTION_CREATE':
  568. $link = '<a href="'.$urlwithroot.'/comm/action/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  569. $dir_output = $conf->agenda->dir_output;
  570. $object_type = 'action';
  571. $mesg = $outputlangs->transnoentitiesnoconv("EMailTextActionAdded", $link);
  572. break;
  573. default:
  574. $object_type = $object->element;
  575. $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type);
  576. $template = $notifcode.'_TEMPLATE';
  577. $mesg = $outputlangs->transnoentitiesnoconv('Notify_'.$notifcode).' '.$newref.' '.$dir_output;
  578. break;
  579. }
  580. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
  581. $formmail = new FormMail($this->db);
  582. $arraydefaultmessage = null;
  583. $template = $notifcode.'_TEMPLATE';
  584. $labeltouse = getDolGlobalString($template);
  585. if (!empty($labeltouse)) {
  586. $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $object_type.'_send', $user, $outputlangs, 0, 1, $labeltouse);
  587. }
  588. if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
  589. $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
  590. complete_substitutions_array($substitutionarray, $outputlangs, $object);
  591. $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
  592. $message = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
  593. } else {
  594. $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification", $application, $mysoc->name)."\n";
  595. $message .= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n";
  596. $message .= "\n";
  597. $message .= $mesg;
  598. }
  599. $ref = dol_sanitizeFileName($newref);
  600. $pdf_path = $dir_output."/".$ref.".pdf";
  601. if (!dol_is_file($pdf_path)||(is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0 && !$arraydefaultmessage->joinfiles)) {
  602. // We can't add PDF as it is not generated yet.
  603. $filepdf = '';
  604. } else {
  605. $filepdf = $pdf_path;
  606. $filename_list[] = $filepdf;
  607. $mimetype_list[] = mime_content_type($filepdf);
  608. $mimefilename_list[] = $ref.".pdf";
  609. }
  610. $labeltouse = !empty($labeltouse) ? $labeltouse : '';
  611. // Replace keyword __SUPERVISOREMAIL__
  612. if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) {
  613. $newval = '';
  614. if ($user->fk_user > 0) {
  615. $supervisoruser = new User($this->db);
  616. $supervisoruser->fetch($user->fk_user);
  617. if ($supervisoruser->email) {
  618. $newval = trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
  619. }
  620. }
  621. dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
  622. $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
  623. $sendto = preg_replace('/,\s*,/', ',', $sendto); // in some case you can have $sendto like "email, __SUPERVISOREMAIL__ , otheremail" then you have "email, , othermail" and it's not valid
  624. $sendto = preg_replace('/^[\s,]+/', '', $sendto); // Clean start of string
  625. $sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string
  626. }
  627. $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse);
  628. if (!isset($action)) {
  629. $action = '';
  630. }
  631. $reshook = $hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  632. if (empty($reshook)) {
  633. if (!empty($hookmanager->resArray['files'])) {
  634. $filename_list = $hookmanager->resArray['files']['file'];
  635. $mimetype_list = $hookmanager->resArray['files']['mimefile'];
  636. $mimefilename_list = $hookmanager->resArray['files']['filename'];
  637. }
  638. if (!empty($hookmanager->resArray['subject'])) {
  639. $subject .= $hookmanager->resArray['subject'];
  640. }
  641. if (!empty($hookmanager->resArray['message'])) {
  642. $message .= $hookmanager->resArray['message'];
  643. }
  644. }
  645. $mailfile = new CMailFile(
  646. $subject,
  647. $sendto,
  648. $replyto,
  649. $message,
  650. $filename_list,
  651. $mimetype_list,
  652. $mimefilename_list,
  653. '',
  654. '',
  655. 0,
  656. -1,
  657. '',
  658. '',
  659. $trackid,
  660. '',
  661. 'notification'
  662. );
  663. if ($mailfile->sendfile()) {
  664. if ($obj->type_target == 'touserid') {
  665. $sql = "INSERT INTO ".$this->db->prefix()."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)";
  666. $sql .= " VALUES ('".$this->db->idate(dol_now())."', ".((int) $notifcodedefid).", ".($object->socid > 0 ? ((int) $object->socid) : 'null').", ".((int) $obj->cid).", '".$this->db->escape($obj->type)."', '".$this->db->escape($object_type)."', '".$this->db->escape($obj->type_target)."', ".((int) $object->id).", '".$this->db->escape($obj->email)."')";
  667. } else {
  668. $sql = "INSERT INTO ".$this->db->prefix()."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)";
  669. $sql .= " VALUES ('".$this->db->idate(dol_now())."', ".((int) $notifcodedefid).", ".($object->socid > 0 ? ((int) $object->socid) : 'null').", ".((int) $obj->cid).", '".$this->db->escape($obj->type)."', '".$this->db->escape($object_type)."', '".$this->db->escape($obj->type_target)."', ".((int) $object->id).", '".$this->db->escape($obj->email)."')";
  670. }
  671. if (!$this->db->query($sql)) {
  672. dol_print_error($this->db);
  673. }
  674. } else {
  675. $error++;
  676. $this->errors[] = $mailfile->error;
  677. }
  678. } else {
  679. dol_syslog("No notification sent for ".$sendto." because email is empty");
  680. }
  681. $i++;
  682. }
  683. } else {
  684. dol_syslog("No notification to thirdparty sent, nothing into notification setup for the thirdparty socid = ".(empty($object->socid) ? '' : $object->socid));
  685. }
  686. } else {
  687. $error++;
  688. $this->errors[] = $this->db->lasterror();
  689. dol_syslog("Failed to get list of notification to send ".$this->db->lasterror(), LOG_ERR);
  690. return -1;
  691. }
  692. // Check notification using fixed email
  693. // TODO Move vars NOTIFICATION_FIXEDEMAIL into table llx_notify_def and inclulde the case into previous loop of sql result
  694. if (!$error) {
  695. foreach ($conf->global as $key => $val) {
  696. $reg = array();
  697. if ($val == '' || !preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) {
  698. continue;
  699. }
  700. $sendto = $val;
  701. $threshold = (float) $reg[1];
  702. if (!empty($object->total_ht) && $object->total_ht <= $threshold) {
  703. dol_syslog("A notification is requested for notifcode = ".$notifcode." but amount = ".$object->total_ht." so lower than threshold = ".$threshold.". We discard this notification");
  704. continue;
  705. }
  706. $notifcodedefid = dol_getIdFromCode($this->db, $notifcode, 'c_action_trigger', 'code', 'rowid');
  707. if ($notifcodedefid <= 0) {
  708. dol_print_error($this->db, 'Failed to get id from code');
  709. }
  710. $trackid = '';
  711. $object_type = '';
  712. $link = '';
  713. $num++;
  714. $appli = $mysoc->name;
  715. $subject = '['.$appli.'] '.$langs->transnoentitiesnoconv("DolibarrNotification").($projtitle ? ' '.$projtitle : '');
  716. switch ($notifcode) {
  717. case 'BILL_VALIDATE':
  718. $link = '<a href="'.$urlwithroot.'/compta/facture/card.php?facid='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  719. $dir_output = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice');
  720. $object_type = 'facture';
  721. $mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated", $link);
  722. break;
  723. case 'BILL_PAYED':
  724. $link = '<a href="'.$urlwithroot.'/compta/facture/card.php?facid='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  725. $dir_output = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice');
  726. $object_type = 'facture';
  727. $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed", $link);
  728. break;
  729. case 'ORDER_VALIDATE':
  730. $link = '<a href="'.$urlwithroot.'/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  731. $dir_output = $conf->commande->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'commande');
  732. $object_type = 'order';
  733. $mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated", $link);
  734. break;
  735. case 'ORDER_CLOSE':
  736. $link = '<a href="'.$urlwithroot.'/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  737. $dir_output = $conf->commande->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'commande');
  738. $object_type = 'order';
  739. $mesg = $langs->transnoentitiesnoconv("EMailTextOrderClose", $link);
  740. break;
  741. case 'PROPAL_VALIDATE':
  742. $link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  743. $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
  744. $object_type = 'propal';
  745. $mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated", $link);
  746. break;
  747. case 'PROPAL_CLOSE_SIGNED':
  748. $link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  749. $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
  750. $object_type = 'propal';
  751. $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
  752. break;
  753. case 'FICHINTER_ADD_CONTACT':
  754. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  755. $dir_output = $conf->ficheinter->dir_output;
  756. $object_type = 'ficheinter';
  757. $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact", $link);
  758. break;
  759. case 'FICHINTER_VALIDATE':
  760. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  761. $dir_output = $conf->facture->dir_output;
  762. $object_type = 'ficheinter';
  763. $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated", $link);
  764. break;
  765. case 'FICHINTER_CLOSE':
  766. $link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  767. $dir_output = $conf->facture->dir_output;
  768. $object_type = 'ficheinter';
  769. $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionClosed", $link);
  770. break;
  771. case 'ORDER_SUPPLIER_VALIDATE':
  772. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  773. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  774. $object_type = 'order_supplier';
  775. $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
  776. $mesg .= $langs->transnoentitiesnoconv("EMailTextSupplierOrderValidatedBy", $link, $user->getFullName($langs));
  777. $mesg .= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
  778. break;
  779. case 'ORDER_SUPPLIER_APPROVE':
  780. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  781. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  782. $object_type = 'order_supplier';
  783. $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
  784. $mesg .= $langs->transnoentitiesnoconv("EMailTextSupplierOrderApprovedBy", $link, $user->getFullName($langs));
  785. $mesg .= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
  786. break;
  787. case 'ORDER_SUPPLIER_SUBMIT':
  788. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  789. $dir_output = $conf->fournisseur->commande->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object);
  790. $object_type = 'order_supplier';
  791. $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
  792. $mesg .= $langs->transnoentitiesnoconv("EMailTextSupplierOrderSubmittedBy", $link, $user->getFullName($langs));
  793. $mesg .= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
  794. break;
  795. case 'ORDER_SUPPLIER_REFUSE':
  796. $link = '<a href="'.$urlwithroot.'/fourn/commande/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  797. $dir_output = $conf->fournisseur->dir_output.'/commande/';
  798. $object_type = 'order_supplier';
  799. $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
  800. $mesg .= $langs->transnoentitiesnoconv("EMailTextSupplierOrderRefusedBy", $link, $user->getFullName($langs));
  801. $mesg .= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
  802. break;
  803. case 'SHIPPING_VALIDATE':
  804. $link = '<a href="'.$urlwithroot.'/expedition/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  805. $dir_output = $conf->expedition->dir_output."/sending/".get_exdir(0, 0, 0, 1, $object, 'shipment');
  806. $object_type = 'order_supplier';
  807. $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $link);
  808. break;
  809. case 'EXPENSE_REPORT_VALIDATE':
  810. $link = '<a href="'.$urlwithroot.'/expensereport/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  811. $dir_output = $conf->expensereport->dir_output;
  812. $object_type = 'expensereport';
  813. $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $link);
  814. break;
  815. case 'EXPENSE_REPORT_APPROVE':
  816. $link = '<a href="'.$urlwithroot.'/expensereport/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  817. $dir_output = $conf->expensereport->dir_output;
  818. $object_type = 'expensereport';
  819. $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $link);
  820. break;
  821. case 'HOLIDAY_VALIDATE':
  822. $link = '<a href="'.$urlwithroot.'/holiday/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  823. $dir_output = $conf->holiday->dir_output;
  824. $object_type = 'holiday';
  825. $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated", $link);
  826. break;
  827. case 'HOLIDAY_APPROVE':
  828. $link = '<a href="'.$urlwithroot.'/holiday/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  829. $dir_output = $conf->holiday->dir_output;
  830. $object_type = 'holiday';
  831. $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $link);
  832. break;
  833. case 'ACTION_CREATE':
  834. $link = '<a href="'.$urlwithroot.'/comm/action/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
  835. $dir_output = $conf->agenda->dir_output;
  836. $object_type = 'action';
  837. $mesg = $langs->transnoentitiesnoconv("EMailTextActionAdded", $link);
  838. break;
  839. default:
  840. $object_type = $object->element;
  841. $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type);
  842. $mesg = $langs->transnoentitiesnoconv('Notify_'.$notifcode).' '.$newref;
  843. break;
  844. }
  845. $ref = dol_sanitizeFileName($newref);
  846. $pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
  847. if (!dol_is_file($pdf_path)) {
  848. // We can't add PDF as it is not generated yet.
  849. $filepdf = '';
  850. } else {
  851. $filepdf = $pdf_path;
  852. $filename_list[] = $pdf_path;
  853. $mimetype_list[] = mime_content_type($filepdf);
  854. $mimefilename_list[] = $ref.".pdf";
  855. }
  856. $message = '';
  857. $message .= $langs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n";
  858. $message .= "\n";
  859. $message .= $mesg;
  860. $message = nl2br($message);
  861. // Replace keyword __SUPERVISOREMAIL__
  862. if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) {
  863. $newval = '';
  864. if ($user->fk_user > 0) {
  865. $supervisoruser = new User($this->db);
  866. $supervisoruser->fetch($user->fk_user);
  867. if ($supervisoruser->email) {
  868. $newval = trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
  869. }
  870. }
  871. dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
  872. $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
  873. $sendto = preg_replace('/,\s*,/', ',', $sendto); // in some case you can have $sendto like "email, __SUPERVISOREMAIL__ , otheremail" then you have "email, , othermail" and it's not valid
  874. $sendto = preg_replace('/^[\s,]+/', '', $sendto); // Clean start of string
  875. $sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string
  876. }
  877. if ($sendto) {
  878. $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'subject'=>&$subject, 'message'=>&$message);
  879. $reshook = $hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  880. if (empty($reshook)) {
  881. if (!empty($hookmanager->resArray['files'])) {
  882. $filename_list = $hookmanager->resArray['files']['file'];
  883. $mimetype_list = $hookmanager->resArray['files']['mimefile'];
  884. $mimefilename_list = $hookmanager->resArray['files']['filename'];
  885. }
  886. if (!empty($hookmanager->resArray['subject'])) {
  887. $subject .= $hookmanager->resArray['subject'];
  888. }
  889. if (!empty($hookmanager->resArray['message'])) {
  890. $message .= $hookmanager->resArray['message'];
  891. }
  892. }
  893. $mailfile = new CMailFile(
  894. $subject,
  895. $sendto,
  896. $replyto,
  897. $message,
  898. $filename_list,
  899. $mimetype_list,
  900. $mimefilename_list,
  901. '',
  902. '',
  903. 0,
  904. 1,
  905. '',
  906. $trackid,
  907. '',
  908. '',
  909. 'notification'
  910. );
  911. if ($mailfile->sendfile()) {
  912. $sql = "INSERT INTO ".$this->db->prefix()."notify (daten, fk_action, fk_soc, fk_contact, type, type_target, objet_type, objet_id, email)";
  913. $sql .= " VALUES ('".$this->db->idate(dol_now())."', ".((int) $notifcodedefid).", ".($object->socid > 0 ? ((int) $object->socid) : 'null').", null, 'email', 'tofixedemail', '".$this->db->escape($object_type)."', ".((int) $object->id).", '".$this->db->escape($sendto)."')";
  914. if (!$this->db->query($sql)) {
  915. dol_print_error($this->db);
  916. }
  917. } else {
  918. $error++;
  919. $this->errors[] = $mailfile->error;
  920. }
  921. }
  922. }
  923. }
  924. if (!$error) {
  925. return $num;
  926. } else {
  927. return -1 * $error;
  928. }
  929. }
  930. }