blockedlog.class.php 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. <?php
  2. /* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
  3. * Copyright (C) 2017-2020 Laurent Destailleur <eldy@destailleur.fr>
  4. * Copyright (C) 2022 charlene benke <charlene@patas-monkey.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. *
  19. * See https://medium.com/@lhartikk/a-blockchain-in-200-lines-of-code-963cc1cc0e54
  20. */
  21. /**
  22. * Class to manage Blocked Log
  23. */
  24. class BlockedLog
  25. {
  26. /**
  27. * @var DoliDB Database handler
  28. */
  29. public $db;
  30. /**
  31. * Id of the log
  32. * @var int
  33. */
  34. public $id;
  35. /**
  36. * Entity
  37. * @var int
  38. */
  39. public $entity;
  40. /**
  41. * @var string Error message
  42. */
  43. public $error = '';
  44. /**
  45. * @var string[] Error codes (or messages)
  46. */
  47. public $errors = array();
  48. /**
  49. * Unique fingerprint of the log
  50. * @var string
  51. */
  52. public $signature = '';
  53. /**
  54. * Unique fingerprint of the line log content
  55. * @var string
  56. */
  57. public $signature_line = '';
  58. public $amounts = null;
  59. /**
  60. * trigger action
  61. * @var string
  62. */
  63. public $action = '';
  64. /**
  65. * Object element
  66. * @var string
  67. */
  68. public $element = '';
  69. /**
  70. * Object id
  71. * @var int
  72. */
  73. public $fk_object = 0;
  74. /**
  75. * Log certified by remote authority or not
  76. * @var boolean
  77. */
  78. public $certified = false;
  79. /**
  80. * Author
  81. * @var int
  82. */
  83. public $fk_user = 0;
  84. /**
  85. * @var integer|string date_creation
  86. */
  87. public $date_creation;
  88. /**
  89. * @var integer|string $date_modification;
  90. */
  91. public $date_modification;
  92. public $date_object = 0;
  93. public $ref_object = '';
  94. public $object_data = null;
  95. public $object_version = '';
  96. public $user_fullname = '';
  97. /**
  98. * Array of tracked event codes
  99. * @var string[]
  100. */
  101. public $trackedevents = array();
  102. /**
  103. * Constructor
  104. *
  105. * @param DoliDB $db Database handler
  106. */
  107. public function __construct(DoliDB $db)
  108. {
  109. $this->db = $db;
  110. }
  111. /**
  112. * Load list of tracked events into $this->trackedevents.
  113. *
  114. * @return int Always 1
  115. */
  116. public function loadTrackedEvents()
  117. {
  118. global $conf;
  119. $this->trackedevents = array();
  120. // Customer Invoice/Facture / Payment
  121. if (isModEnabled('facture')) {
  122. $this->trackedevents['BILL_VALIDATE'] = 'logBILL_VALIDATE';
  123. $this->trackedevents['BILL_DELETE'] = 'logBILL_DELETE';
  124. $this->trackedevents['BILL_SENTBYMAIL'] = 'logBILL_SENTBYMAIL';
  125. $this->trackedevents['DOC_DOWNLOAD'] = 'BlockedLogBillDownload';
  126. $this->trackedevents['DOC_PREVIEW'] = 'BlockedLogBillPreview';
  127. $this->trackedevents['PAYMENT_CUSTOMER_CREATE'] = 'logPAYMENT_CUSTOMER_CREATE';
  128. $this->trackedevents['PAYMENT_CUSTOMER_DELETE'] = 'logPAYMENT_CUSTOMER_DELETE';
  129. }
  130. /* Supplier
  131. // Supplier Invoice / Payment
  132. if (isModEnabled("fournisseur")) {
  133. $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate';
  134. $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete';
  135. $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done
  136. $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload'; // Trigger key does not exists, we want just into array to list it as done
  137. $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview'; // Trigger key does not exists, we want just into array to list it as done
  138. $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate';
  139. $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate';
  140. }
  141. */
  142. // Donation
  143. if (isModEnabled('don')) {
  144. $this->trackedevents['DON_VALIDATE'] = 'logDON_VALIDATE';
  145. $this->trackedevents['DON_DELETE'] = 'logDON_DELETE';
  146. //$this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL';
  147. $this->trackedevents['DONATION_PAYMENT_CREATE'] = 'logDONATION_PAYMENT_CREATE';
  148. $this->trackedevents['DONATION_PAYMENT_DELETE'] = 'logDONATION_PAYMENT_DELETE';
  149. }
  150. /*
  151. // Salary
  152. if (!empty($conf->salary->enabled)) {
  153. $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate';
  154. $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate';
  155. $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate';
  156. }
  157. */
  158. // Members
  159. if (isModEnabled('adherent')) {
  160. $this->trackedevents['MEMBER_SUBSCRIPTION_CREATE'] = 'logMEMBER_SUBSCRIPTION_CREATE';
  161. $this->trackedevents['MEMBER_SUBSCRIPTION_MODIFY'] = 'logMEMBER_SUBSCRIPTION_MODIFY';
  162. $this->trackedevents['MEMBER_SUBSCRIPTION_DELETE'] = 'logMEMBER_SUBSCRIPTION_DELETE';
  163. }
  164. // Bank
  165. if (isModEnabled("banque")) {
  166. $this->trackedevents['PAYMENT_VARIOUS_CREATE'] = 'logPAYMENT_VARIOUS_CREATE';
  167. $this->trackedevents['PAYMENT_VARIOUS_MODIFY'] = 'logPAYMENT_VARIOUS_MODIFY';
  168. $this->trackedevents['PAYMENT_VARIOUS_DELETE'] = 'logPAYMENT_VARIOUS_DELETE';
  169. }
  170. // Cashdesk
  171. // $conf->global->BANK_ENABLE_POS_CASHCONTROL must be set to 1 by all external POS modules
  172. $moduleposenabled = (!empty($conf->cashdesk->enabled) || !empty($conf->takepos->enabled) || getDolGlobalString('BANK_ENABLE_POS_CASHCONTROL'));
  173. if ($moduleposenabled) {
  174. $this->trackedevents['CASHCONTROL_VALIDATE'] = 'logCASHCONTROL_VALIDATE';
  175. }
  176. // Add more action to track from a conf variable
  177. // For example: STOCK_MOVEMENT,...
  178. if (getDolGlobalString('BLOCKEDLOG_ADD_ACTIONS_SUPPORTED')) {
  179. $tmparrayofmoresupportedevents = explode(',', $conf->global->BLOCKEDLOG_ADD_ACTIONS_SUPPORTED);
  180. foreach ($tmparrayofmoresupportedevents as $val) {
  181. $this->trackedevents[$val] = 'log'.$val;
  182. }
  183. }
  184. return 1;
  185. }
  186. /**
  187. * Try to retrieve source object (it it still exists).
  188. *
  189. * @return string URL string of source object
  190. */
  191. public function getObjectLink()
  192. {
  193. global $langs;
  194. if ($this->element === 'facture') {
  195. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  196. $object = new Facture($this->db);
  197. if ($object->fetch($this->fk_object) > 0) {
  198. return $object->getNomUrl(1);
  199. } else {
  200. $this->error++;
  201. }
  202. }
  203. if ($this->element === 'invoice_supplier') {
  204. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  205. $object = new FactureFournisseur($this->db);
  206. if ($object->fetch($this->fk_object) > 0) {
  207. return $object->getNomUrl(1);
  208. } else {
  209. $this->error++;
  210. }
  211. } elseif ($this->element === 'payment') {
  212. require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
  213. $object = new Paiement($this->db);
  214. if ($object->fetch($this->fk_object) > 0) {
  215. return $object->getNomUrl(1);
  216. } else {
  217. $this->error++;
  218. }
  219. } elseif ($this->element === 'payment_supplier') {
  220. require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
  221. $object = new PaiementFourn($this->db);
  222. if ($object->fetch($this->fk_object) > 0) {
  223. return $object->getNomUrl(1);
  224. } else {
  225. $this->error++;
  226. }
  227. } elseif ($this->element === 'payment_donation') {
  228. require_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php';
  229. $object = new PaymentDonation($this->db);
  230. if ($object->fetch($this->fk_object) > 0) {
  231. return $object->getNomUrl(1);
  232. } else {
  233. $this->error++;
  234. }
  235. } elseif ($this->element === 'payment_various') {
  236. require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
  237. $object = new PaymentVarious($this->db);
  238. if ($object->fetch($this->fk_object) > 0) {
  239. return $object->getNomUrl(1);
  240. } else {
  241. $this->error++;
  242. }
  243. } elseif ($this->element === 'don' || $this->element === 'donation') {
  244. require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
  245. $object = new Don($this->db);
  246. if ($object->fetch($this->fk_object) > 0) {
  247. return $object->getNomUrl(1);
  248. } else {
  249. $this->error++;
  250. }
  251. } elseif ($this->element === 'subscription') {
  252. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  253. $object = new Subscription($this->db);
  254. if ($object->fetch($this->fk_object) > 0) {
  255. return $object->getNomUrl(1);
  256. } else {
  257. $this->error++;
  258. }
  259. } elseif ($this->element === 'cashcontrol') {
  260. require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php';
  261. $object = new CashControl($this->db);
  262. if ($object->fetch($this->fk_object) > 0) {
  263. return $object->getNomUrl(1);
  264. } else {
  265. $this->error++;
  266. }
  267. } elseif ($this->element === 'stockmouvement') {
  268. require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
  269. $object = new MouvementStock($this->db);
  270. if ($object->fetch($this->fk_object) > 0) {
  271. return $object->getNomUrl(1);
  272. } else {
  273. $this->error++;
  274. }
  275. } elseif ($this->action == 'MODULE_SET') {
  276. return '<i class="opacitymedium">'.$langs->trans("BlockedLogEnabled").'</i>';
  277. } elseif ($this->action == 'MODULE_RESET') {
  278. if ($this->signature == '0000000000') {
  279. return '<i class="opacitymedium">'.$langs->trans("BlockedLogDisabled").'</i>';
  280. } else {
  281. return '<i class="opacitymedium">'.$langs->trans("BlockedLogDisabledBis").'</i>';
  282. }
  283. }
  284. return '<i class="opacitymedium">'.$langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object).'</i>';
  285. }
  286. /**
  287. * try to retrieve user author
  288. * @return string
  289. */
  290. public function getUser()
  291. {
  292. global $langs, $cachedUser;
  293. if (empty($cachedUser)) {
  294. $cachedUser = array();
  295. }
  296. if (empty($cachedUser[$this->fk_user])) {
  297. $u = new User($this->db);
  298. if ($u->fetch($this->fk_user) > 0) {
  299. $cachedUser[$this->fk_user] = $u;
  300. }
  301. }
  302. if (!empty($cachedUser[$this->fk_user])) {
  303. return $cachedUser[$this->fk_user]->getNomUrl(1);
  304. }
  305. return $langs->trans('ImpossibleToRetrieveUser', $this->fk_user);
  306. }
  307. /**
  308. * Populate properties of log from object data
  309. *
  310. * @param Object $object object to store
  311. * @param string $action action
  312. * @param string $amounts amounts
  313. * @param User $fuser User object (forced)
  314. * @return int >0 if OK, <0 if KO
  315. */
  316. public function setObjectData(&$object, $action, $amounts, $fuser = null)
  317. {
  318. global $langs, $user, $mysoc;
  319. if (is_object($fuser)) {
  320. $user = $fuser;
  321. }
  322. // Generic fields
  323. // action
  324. $this->action = $action;
  325. // amount
  326. $this->amounts = $amounts;
  327. // date
  328. if ($object->element == 'payment' || $object->element == 'payment_supplier') {
  329. $this->date_object = empty($object->datepaye) ? $object->date : $object->datepaye;
  330. } elseif ($object->element == 'payment_salary') {
  331. $this->date_object = $object->datev;
  332. } elseif ($object->element == 'payment_donation' || $object->element == 'payment_various') {
  333. $this->date_object = empty($object->datepaid) ? $object->datep : $object->datepaid;
  334. } elseif ($object->element == 'subscription') {
  335. $this->date_object = $object->dateh;
  336. } elseif ($object->element == 'cashcontrol') {
  337. $this->date_object = $object->date_creation;
  338. } elseif (property_exists($object, 'date')) {
  339. // Generic case
  340. $this->date_object = $object->date;
  341. } elseif (property_exists($object, 'datem')) {
  342. // Generic case (second chance, for example for stock movement)
  343. $this->date_object = $object->datem;
  344. }
  345. // ref
  346. $this->ref_object = ((!empty($object->newref)) ? $object->newref : $object->ref); // newref is set when validating a draft, ref is set in other cases
  347. // type of object
  348. $this->element = $object->element;
  349. // id of object
  350. $this->fk_object = $object->id;
  351. // Set object_data
  352. $this->object_data = new stdClass();
  353. // Add fields to exclude
  354. $arrayoffieldstoexclude = array(
  355. 'table_element', 'fields', 'ref_previous', 'ref_next', 'origin', 'origin_id', 'oldcopy', 'picto', 'error', 'errors', 'model_pdf', 'modelpdf', 'last_main_doc', 'civility_id', 'contact', 'contact_id',
  356. 'table_element_line', 'ismultientitymanaged', 'isextrafieldmanaged',
  357. 'array_languages',
  358. 'childtables',
  359. 'contact_ids',
  360. 'context',
  361. 'labelStatus',
  362. 'labelStatusShort',
  363. 'linkedObjectsIds',
  364. 'linkedObjects',
  365. 'fk_delivery_address',
  366. 'projet', // There is already ->fk_project
  367. 'restrictiononfksoc',
  368. 'specimen',
  369. );
  370. // Add more fields to exclude depending on object type
  371. if ($this->element == 'cashcontrol') {
  372. $arrayoffieldstoexclude = array_merge($arrayoffieldstoexclude, array(
  373. 'name', 'lastname', 'firstname', 'region', 'region_id', 'region_code', 'state', 'state_id', 'state_code', 'country', 'country_id', 'country_code',
  374. 'total_ht', 'total_tva', 'total_ttc', 'total_localtax1', 'total_localtax2',
  375. 'barcode_type', 'barcode_type_code', 'barcode_type_label', 'barcode_type_coder', 'mode_reglement_id', 'cond_reglement_id', 'mode_reglement', 'cond_reglement', 'shipping_method_id',
  376. 'fk_incoterms', 'label_incoterms', 'location_incoterms', 'lines'));
  377. }
  378. // Add thirdparty info
  379. if (empty($object->thirdparty) && method_exists($object, 'fetch_thirdparty')) {
  380. $object->fetch_thirdparty();
  381. }
  382. if (!empty($object->thirdparty)) {
  383. $this->object_data->thirdparty = new stdClass();
  384. foreach ($object->thirdparty as $key => $value) {
  385. if (in_array($key, $arrayoffieldstoexclude)) {
  386. continue; // Discard some properties
  387. }
  388. if (!in_array($key, array(
  389. 'name', 'name_alias', 'ref_ext', 'address', 'zip', 'town', 'state_code', 'country_code', 'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6', 'phone', 'fax', 'email', 'barcode',
  390. 'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
  391. ))) {
  392. continue; // Discard if not into a dedicated list
  393. }
  394. if (!is_object($value) && !is_null($value) && $value !== '') {
  395. $this->object_data->thirdparty->$key = $value;
  396. }
  397. }
  398. }
  399. // Add company info
  400. if (!empty($mysoc)) {
  401. $this->object_data->mycompany = new stdClass();
  402. foreach ($mysoc as $key => $value) {
  403. if (in_array($key, $arrayoffieldstoexclude)) {
  404. continue; // Discard some properties
  405. }
  406. if (!in_array($key, array(
  407. 'name', 'name_alias', 'ref_ext', 'address', 'zip', 'town', 'state_code', 'country_code', 'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6', 'phone', 'fax', 'email', 'barcode',
  408. 'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
  409. ))) {
  410. continue; // Discard if not into a dedicated list
  411. }
  412. if (!is_object($value) && !is_null($value) && $value !== '') {
  413. $this->object_data->mycompany->$key = $value;
  414. }
  415. }
  416. }
  417. // Add user info
  418. if (!empty($user)) {
  419. $this->fk_user = $user->id;
  420. $this->user_fullname = $user->getFullName($langs);
  421. }
  422. // Field specific to object
  423. if ($this->element == 'facture') {
  424. foreach ($object as $key => $value) {
  425. if (in_array($key, $arrayoffieldstoexclude)) {
  426. continue; // Discard some properties
  427. }
  428. if (!in_array($key, array(
  429. 'ref', 'ref_client', 'ref_supplier', 'date', 'datef', 'datev', 'type', 'total_ht', 'total_tva', 'total_ttc', 'localtax1', 'localtax2', 'revenuestamp', 'datepointoftax', 'note_public', 'lines'
  430. ))) {
  431. continue; // Discard if not into a dedicated list
  432. }
  433. if ($key == 'lines') {
  434. $lineid = 0;
  435. foreach ($value as $tmpline) { // $tmpline is object FactureLine
  436. $lineid++;
  437. foreach ($tmpline as $keyline => $valueline) {
  438. if (!in_array($keyline, array(
  439. 'ref', 'multicurrency_code', 'multicurrency_total_ht', 'multicurrency_total_tva', 'multicurrency_total_ttc', 'qty', 'product_type', 'vat_src_code', 'tva_tx', 'info_bits', 'localtax1_tx', 'localtax2_tx', 'total_ht', 'total_tva', 'total_ttc', 'total_localtax1', 'total_localtax2'
  440. ))) {
  441. continue; // Discard if not into a dedicated list
  442. }
  443. if (empty($this->object_data->invoiceline[$lineid]) || !is_object($this->object_data->invoiceline[$lineid])) { // To avoid warning
  444. $this->object_data->invoiceline[$lineid] = new stdClass();
  445. }
  446. if (!is_object($valueline) && !is_null($valueline) && $valueline !== '') {
  447. $this->object_data->invoiceline[$lineid]->$keyline = $valueline;
  448. }
  449. }
  450. }
  451. } elseif (!is_object($value) && !is_null($value) && $value !== '') {
  452. $this->object_data->$key = $value;
  453. }
  454. }
  455. if (!empty($object->newref)) {
  456. $this->object_data->ref = $object->newref;
  457. }
  458. } elseif ($this->element == 'invoice_supplier') {
  459. foreach ($object as $key => $value) {
  460. if (in_array($key, $arrayoffieldstoexclude)) {
  461. continue; // Discard some properties
  462. }
  463. if (!in_array($key, array(
  464. 'ref', 'ref_client', 'ref_supplier', 'date', 'datef', 'type', 'total_ht', 'total_tva', 'total_ttc', 'localtax1', 'localtax2', 'revenuestamp', 'datepointoftax', 'note_public'
  465. ))) {
  466. continue; // Discard if not into a dedicated list
  467. }
  468. if (!is_object($value) && !is_null($value) && $value !== '') {
  469. $this->object_data->$key = $value;
  470. }
  471. }
  472. if (!empty($object->newref)) {
  473. $this->object_data->ref = $object->newref;
  474. }
  475. } elseif ($this->element == 'payment' || $this->element == 'payment_supplier' || $this->element == 'payment_donation' || $this->element == 'payment_various') {
  476. $datepayment = $object->datepaye ? $object->datepaye : ($object->datepaid ? $object->datepaid : $object->datep);
  477. $paymenttypeid = $object->paiementid ? $object->paiementid : ($object->paymenttype ? $object->paymenttype : $object->type_payment);
  478. $this->object_data->ref = $object->ref;
  479. $this->object_data->date = $datepayment;
  480. $this->object_data->type_code = dol_getIdFromCode($this->db, $paymenttypeid, 'c_paiement', 'id', 'code');
  481. if (!empty($object->num_payment)) {
  482. $this->object_data->payment_num = $object->num_payment;
  483. }
  484. if (!empty($object->note_private)) {
  485. $this->object_data->note_private = $object->note_private;
  486. }
  487. //$this->object_data->fk_account = $object->fk_account;
  488. //var_dump($this->object_data);exit;
  489. $totalamount = 0;
  490. // Loop on each invoice payment amount (payment_part)
  491. if (is_array($object->amounts) && !empty($object->amounts)) {
  492. $paymentpartnumber = 0;
  493. foreach ($object->amounts as $objid => $amount) {
  494. if (empty($amount)) {
  495. continue;
  496. }
  497. $totalamount += $amount;
  498. $tmpobject = null;
  499. if ($this->element == 'payment_supplier') {
  500. include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  501. $tmpobject = new FactureFournisseur($this->db);
  502. } elseif ($this->element == 'payment') {
  503. include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  504. $tmpobject = new Facture($this->db);
  505. } elseif ($this->element == 'payment_donation') {
  506. include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
  507. $tmpobject = new Don($this->db);
  508. } elseif ($this->element == 'payment_various') {
  509. include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
  510. $tmpobject = new PaymentVarious($this->db);
  511. }
  512. if (!is_object($tmpobject)) {
  513. continue;
  514. }
  515. $result = $tmpobject->fetch($objid);
  516. if ($result <= 0) {
  517. $this->error = $tmpobject->error;
  518. $this->errors = $tmpobject->errors;
  519. dol_syslog("Failed to fetch object with id ".$objid, LOG_ERR);
  520. return -1;
  521. }
  522. $paymentpart = new stdClass();
  523. $paymentpart->amount = $amount;
  524. if (!in_array($this->element, array('payment_donation', 'payment_various'))) {
  525. $result = $tmpobject->fetch_thirdparty();
  526. if ($result == 0) {
  527. $this->error = 'Failed to fetch thirdparty for object with id '.$tmpobject->id;
  528. $this->errors[] = $this->error;
  529. dol_syslog("Failed to fetch thirdparty for object with id ".$tmpobject->id, LOG_ERR);
  530. return -1;
  531. } elseif ($result < 0) {
  532. $this->error = $tmpobject->error;
  533. $this->errors = $tmpobject->errors;
  534. return -1;
  535. }
  536. $paymentpart->thirdparty = new stdClass();
  537. foreach ($tmpobject->thirdparty as $key => $value) {
  538. if (in_array($key, $arrayoffieldstoexclude)) {
  539. continue; // Discard some properties
  540. }
  541. if (!in_array($key, array(
  542. 'name', 'name_alias', 'ref_ext', 'address', 'zip', 'town', 'state_code', 'country_code', 'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6', 'phone', 'fax', 'email', 'barcode',
  543. 'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
  544. ))) {
  545. continue; // Discard if not into a dedicated list
  546. }
  547. if (!is_object($value) && !is_null($value) && $value !== '') {
  548. $paymentpart->thirdparty->$key = $value;
  549. }
  550. }
  551. }
  552. // Init object to avoid warnings
  553. if ($this->element == 'payment_donation') {
  554. $paymentpart->donation = new stdClass();
  555. } else {
  556. $paymentpart->invoice = new stdClass();
  557. }
  558. if ($this->element != 'payment_various') {
  559. foreach ($tmpobject as $key => $value) {
  560. if (in_array($key, $arrayoffieldstoexclude)) {
  561. continue; // Discard some properties
  562. }
  563. if (!in_array($key, array(
  564. 'ref', 'ref_client', 'ref_supplier', 'date', 'datef', 'type', 'total_ht', 'total_tva', 'total_ttc', 'localtax1', 'localtax2', 'revenuestamp', 'datepointoftax', 'note_public'
  565. ))) {
  566. continue; // Discard if not into a dedicated list
  567. }
  568. if (!is_object($value) && !is_null($value) && $value !== '') {
  569. if ($this->element == 'payment_donation') {
  570. $paymentpart->donation->$key = $value;
  571. } elseif ($this->element == 'payment_various') {
  572. $paymentpart->various->$key = $value;
  573. } else {
  574. $paymentpart->invoice->$key = $value;
  575. }
  576. }
  577. }
  578. $paymentpartnumber++; // first payment will be 1
  579. $this->object_data->payment_part[$paymentpartnumber] = $paymentpart;
  580. }
  581. }
  582. } elseif (!empty($object->amount)) {
  583. $totalamount = $object->amount;
  584. }
  585. $this->object_data->amount = $totalamount;
  586. if (!empty($object->newref)) {
  587. $this->object_data->ref = $object->newref;
  588. }
  589. } elseif ($this->element == 'payment_salary') {
  590. $this->object_data->amounts = array($object->amount);
  591. if (!empty($object->newref)) {
  592. $this->object_data->ref = $object->newref;
  593. }
  594. } elseif ($this->element == 'subscription') {
  595. foreach ($object as $key => $value) {
  596. if (in_array($key, $arrayoffieldstoexclude)) {
  597. continue; // Discard some properties
  598. }
  599. if (!in_array($key, array(
  600. 'id', 'datec', 'dateh', 'datef', 'fk_adherent', 'amount', 'import_key', 'statut', 'note'
  601. ))) {
  602. continue; // Discard if not into a dedicated list
  603. }
  604. if (!is_object($value) && !is_null($value) && $value !== '') {
  605. $this->object_data->$key = $value;
  606. }
  607. }
  608. if (!empty($object->newref)) {
  609. $this->object_data->ref = $object->newref;
  610. }
  611. } elseif ($this->element == 'stockmouvement') {
  612. foreach ($object as $key => $value) {
  613. if (in_array($key, $arrayoffieldstoexclude)) {
  614. continue; // Discard some properties
  615. }
  616. if (!is_object($value) && !is_null($value) && $value !== '') {
  617. $this->object_data->$key = $value;
  618. }
  619. }
  620. } else {
  621. // Generic case
  622. foreach ($object as $key => $value) {
  623. if (in_array($key, $arrayoffieldstoexclude)) {
  624. continue; // Discard some properties
  625. }
  626. if (!is_object($value) && !is_null($value) && $value !== '') {
  627. $this->object_data->$key = $value;
  628. }
  629. }
  630. if (!empty($object->newref)) {
  631. $this->object_data->ref = $object->newref;
  632. }
  633. }
  634. // A trick to be sure all the object_data is an associative array
  635. // json_encode and json_decode are not able to manage mixed object (with array/object, only full arrays or full objects)
  636. $this->object_data = json_decode(json_encode($this->object_data, JSON_FORCE_OBJECT), false);
  637. return 1;
  638. }
  639. /**
  640. * Get object from database
  641. *
  642. * @param int $id Id of object to load
  643. * @return int >0 if OK, <0 if KO, 0 if not found
  644. */
  645. public function fetch($id)
  646. {
  647. global $langs;
  648. if (empty($id)) {
  649. $this->error = 'BadParameter';
  650. return -1;
  651. }
  652. $sql = "SELECT b.rowid, b.date_creation, b.signature, b.signature_line, b.amounts, b.action, b.element, b.fk_object, b.entity,";
  653. $sql .= " b.certified, b.tms, b.fk_user, b.user_fullname, b.date_object, b.ref_object, b.object_data, b.object_version";
  654. $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog as b";
  655. if ($id) {
  656. $sql .= " WHERE b.rowid = ".((int) $id);
  657. }
  658. $resql = $this->db->query($sql);
  659. if ($resql) {
  660. $obj = $this->db->fetch_object($resql);
  661. if ($obj) {
  662. $this->id = $obj->rowid;
  663. $this->entity = $obj->entity;
  664. $this->date_creation = $this->db->jdate($obj->date_creation);
  665. $this->date_modification = $this->db->jdate($obj->tms);
  666. $this->amounts = (float) $obj->amounts;
  667. $this->action = $obj->action;
  668. $this->element = $obj->element;
  669. $this->fk_object = $obj->fk_object;
  670. $this->date_object = $this->db->jdate($obj->date_object);
  671. $this->ref_object = $obj->ref_object;
  672. $this->fk_user = $obj->fk_user;
  673. $this->user_fullname = $obj->user_fullname;
  674. $this->object_data = $this->dolDecodeBlockedData($obj->object_data);
  675. $this->object_version = $obj->object_version;
  676. $this->signature = $obj->signature;
  677. $this->signature_line = $obj->signature_line;
  678. $this->certified = ($obj->certified == 1);
  679. return 1;
  680. } else {
  681. $langs->load("blockedlog");
  682. $this->error = $langs->trans("RecordNotFound");
  683. return 0;
  684. }
  685. } else {
  686. $this->error = $this->db->error();
  687. return -1;
  688. }
  689. }
  690. /**
  691. * Encode data
  692. *
  693. * @param string $data Data to serialize
  694. * @param string $mode 0=serialize, 1=json_encode
  695. * @return string Value serialized, an object (stdClass)
  696. */
  697. public function dolEncodeBlockedData($data, $mode = 0)
  698. {
  699. try {
  700. $aaa = json_encode($data);
  701. } catch (Exception $e) {
  702. //print $e->getErrs);
  703. }
  704. //var_dump($aaa);
  705. return $aaa;
  706. }
  707. /**
  708. * Decode data
  709. *
  710. * @param string $data Data to unserialize
  711. * @param string $mode 0=unserialize, 1=json_decode
  712. * @return object Value unserialized, an object (stdClass)
  713. */
  714. public function dolDecodeBlockedData($data, $mode = 0)
  715. {
  716. try {
  717. $aaa = (object) jsonOrUnserialize($data);
  718. } catch (Exception $e) {
  719. //print $e->getErrs);
  720. }
  721. //var_dump($aaa);
  722. return $aaa;
  723. }
  724. /**
  725. * Set block certified by authority
  726. *
  727. * @return boolean
  728. */
  729. public function setCertified()
  730. {
  731. $res = $this->db->query("UPDATE ".MAIN_DB_PREFIX."blockedlog SET certified=1 WHERE rowid=".((int) $this->id));
  732. if (!$res) {
  733. return false;
  734. }
  735. return true;
  736. }
  737. /**
  738. * Create blocked log in database.
  739. *
  740. * @param User $user Object user that create
  741. * @param int $forcesignature Force signature (for example '0000000000' when we disabled the module)
  742. * @return int Return integer <0 if KO, >0 if OK
  743. */
  744. public function create($user, $forcesignature = '')
  745. {
  746. global $conf, $langs, $hookmanager;
  747. $langs->load('blockedlog');
  748. $error = 0;
  749. // Clean data
  750. $this->amounts = (float) $this->amounts;
  751. dol_syslog(get_class($this).'::create action='.$this->action.' fk_user='.$this->fk_user.' user_fullname='.$this->user_fullname, LOG_DEBUG);
  752. // Check parameters/properties
  753. if (!isset($this->amounts)) { // amount can be 0 for some events (like when module is disabled)
  754. $this->error = $langs->trans("BlockLogNeedAmountsValue");
  755. dol_syslog($this->error, LOG_WARNING);
  756. return -1;
  757. }
  758. if (empty($this->element)) {
  759. $this->error = $langs->trans("BlockLogNeedElement");
  760. dol_syslog($this->error, LOG_WARNING);
  761. return -2;
  762. }
  763. if (empty($this->action)) {
  764. $this->error = $langs->trans("BadParameterWhenCallingCreateOfBlockedLog");
  765. dol_syslog($this->error, LOG_WARNING);
  766. return -3;
  767. }
  768. if (empty($this->fk_user)) {
  769. $this->user_fullname = '(Anonymous)';
  770. }
  771. $this->date_creation = dol_now();
  772. $this->object_version = ((float) DOL_VERSION);
  773. $this->db->begin();
  774. $previoushash = $this->getPreviousHash(1, 0); // This get last record and lock database until insert is done
  775. $keyforsignature = $this->buildKeyForSignature();
  776. include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
  777. $this->signature_line = dol_hash($keyforsignature, '5'); // Not really usefull
  778. $this->signature = dol_hash($previoushash.$keyforsignature, '5');
  779. if ($forcesignature) {
  780. $this->signature = $forcesignature;
  781. }
  782. //var_dump($keyforsignature);var_dump($previoushash);var_dump($this->signature_line);var_dump($this->signature);
  783. $sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog (";
  784. $sql .= " date_creation,";
  785. $sql .= " action,";
  786. $sql .= " amounts,";
  787. $sql .= " signature,";
  788. $sql .= " signature_line,";
  789. $sql .= " element,";
  790. $sql .= " fk_object,";
  791. $sql .= " date_object,";
  792. $sql .= " ref_object,";
  793. $sql .= " object_data,";
  794. $sql .= " object_version,";
  795. $sql .= " certified,";
  796. $sql .= " fk_user,";
  797. $sql .= " user_fullname,";
  798. $sql .= " entity";
  799. $sql .= ") VALUES (";
  800. $sql .= "'".$this->db->idate($this->date_creation)."',";
  801. $sql .= "'".$this->db->escape($this->action)."',";
  802. $sql .= $this->amounts.",";
  803. $sql .= "'".$this->db->escape($this->signature)."',";
  804. $sql .= "'".$this->db->escape($this->signature_line)."',";
  805. $sql .= "'".$this->db->escape($this->element)."',";
  806. $sql .= $this->fk_object.",";
  807. $sql .= "'".$this->db->idate($this->date_object)."',";
  808. $sql .= "'".$this->db->escape($this->ref_object)."',";
  809. $sql .= "'".$this->db->escape($this->dolEncodeBlockedData($this->object_data))."',";
  810. $sql .= "'".$this->db->escape($this->object_version)."',";
  811. $sql .= "0,";
  812. $sql .= $this->fk_user.",";
  813. $sql .= "'".$this->db->escape($this->user_fullname)."',";
  814. $sql .= ($this->entity ? $this->entity : $conf->entity);
  815. $sql .= ")";
  816. /*
  817. $a = serialize($this->object_data); $a2 = unserialize($a); $a4 = print_r($a2, true);
  818. $b = json_encode($this->object_data); $b2 = json_decode($b); $b4 = print_r($b2, true);
  819. var_dump($a4 == print_r($this->object_data, true) ? 'a=a' : 'a not = a');
  820. var_dump($b4 == print_r($this->object_data, true) ? 'b=b' : 'b not = b');
  821. exit;
  822. */
  823. $res = $this->db->query($sql);
  824. if ($res) {
  825. $id = $this->db->last_insert_id(MAIN_DB_PREFIX."blockedlog");
  826. if ($id > 0) {
  827. $this->id = $id;
  828. $this->db->commit();
  829. return $this->id;
  830. } else {
  831. $this->db->rollback();
  832. return -2;
  833. }
  834. } else {
  835. $this->error = $this->db->error();
  836. $this->db->rollback();
  837. return -1;
  838. }
  839. // The commit will release the lock so we can insert nex record
  840. }
  841. /**
  842. * Check if current signature still correct compared to the value in chain
  843. *
  844. * @param string $previoushash If previous signature hash is known, we can provide it to avoid to make a search of it in database.
  845. * @param int $returnarray 1=Return array of details, 2=Return array of details including keyforsignature, 0=Boolean
  846. * @return boolean|array True if OK, False if KO
  847. */
  848. public function checkSignature($previoushash = '', $returnarray = 0)
  849. {
  850. if (empty($previoushash)) {
  851. $previoushash = $this->getPreviousHash(0, $this->id);
  852. }
  853. // Recalculate hash
  854. $keyforsignature = $this->buildKeyForSignature();
  855. //$signature_line = dol_hash($keyforsignature, '5'); // Not really usefull
  856. $signature = dol_hash($previoushash.$keyforsignature, 'sha256');
  857. //var_dump($previoushash); var_dump($keyforsignature); var_dump($signature_line); var_dump($signature);
  858. $res = ($signature === $this->signature);
  859. if (!$res) {
  860. $this->error = 'Signature KO';
  861. }
  862. if ($returnarray) {
  863. if ($returnarray == 1) {
  864. unset($keyforsignature);
  865. return array('checkresult' => $res, 'calculatedsignature' => $signature, 'previoushash' => $previoushash);
  866. } else { // Consume much memory ($keyforsignature is a large var)
  867. return array('checkresult' => $res, 'calculatedsignature' => $signature, 'previoushash' => $previoushash, 'keyforsignature'=>$keyforsignature);
  868. }
  869. } else {
  870. unset($keyforsignature);
  871. return $res;
  872. }
  873. }
  874. /**
  875. * Return a string for signature.
  876. * Note: rowid of line not included as it is not a business data and this allow to make backup of a year
  877. * and restore it into another database with different id wihtout comprimising checksums
  878. *
  879. * @return string Key for signature
  880. */
  881. private function buildKeyForSignature()
  882. {
  883. //print_r($this->object_data);
  884. if (((int) $this->object_version) >= 18) {
  885. return $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname.'|'.json_encode($this->object_data, JSON_FORCE_OBJECT);
  886. } else {
  887. return $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname.'|'.print_r($this->object_data, true);
  888. }
  889. }
  890. /**
  891. * Get previous signature/hash in chain
  892. *
  893. * @param int $withlock 1=With a lock
  894. * @param int $beforeid ID of a record
  895. * @return string Hash of previous record (if beforeid is defined) or hash of last record (if beforeid is 0)
  896. */
  897. public function getPreviousHash($withlock = 0, $beforeid = 0)
  898. {
  899. global $conf;
  900. $previoussignature = '';
  901. $sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog";
  902. $sql .= " WHERE entity = ".((int) $conf->entity);
  903. if ($beforeid) {
  904. $sql .= " AND rowid < ".(int) $beforeid;
  905. }
  906. $sql .= " ORDER BY rowid DESC LIMIT 1";
  907. $sql .= ($withlock ? " FOR UPDATE " : "");
  908. $resql = $this->db->query($sql);
  909. if ($resql) {
  910. $obj = $this->db->fetch_object($resql);
  911. if ($obj) {
  912. $previoussignature = $obj->signature;
  913. }
  914. } else {
  915. dol_print_error($this->db);
  916. exit;
  917. }
  918. if (empty($previoussignature)) {
  919. // First signature line (line 0)
  920. $previoussignature = $this->getSignature();
  921. }
  922. return $previoussignature;
  923. }
  924. /**
  925. * Return array of log objects (with criterias)
  926. *
  927. * @param string $element element to search
  928. * @param int $fk_object id of object to search
  929. * @param int $limit max number of element, 0 for all
  930. * @param string $sortfield sort field
  931. * @param string $sortorder sort order
  932. * @param int $search_fk_user id of user(s)
  933. * @param int $search_start start time limit
  934. * @param int $search_end end time limit
  935. * @param string $search_ref search ref
  936. * @param string $search_amount search amount
  937. * @param string $search_code search code
  938. * @return array|int Array of object log or <0 if error
  939. */
  940. public function getLog($element, $fk_object, $limit = 0, $sortfield = '', $sortorder = '', $search_fk_user = -1, $search_start = -1, $search_end = -1, $search_ref = '', $search_amount = '', $search_code = '')
  941. {
  942. global $conf;
  943. //global $cachedlogs;
  944. /* $cachedlogs allow fastest search */
  945. //if (empty($cachedlogs)) $cachedlogs = array();
  946. if ($element == 'all') {
  947. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
  948. WHERE entity=".$conf->entity;
  949. } elseif ($element == 'not_certified') {
  950. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
  951. WHERE entity=".$conf->entity." AND certified = 0";
  952. } elseif ($element == 'just_certified') {
  953. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
  954. WHERE entity=".$conf->entity." AND certified = 1";
  955. } else {
  956. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
  957. WHERE entity=".$conf->entity." AND element = '".$this->db->escape($element)."'";
  958. }
  959. if ($fk_object) {
  960. $sql .= natural_search("rowid", $fk_object, 1);
  961. }
  962. if ($search_fk_user > 0) {
  963. $sql .= natural_search("fk_user", $search_fk_user, 2);
  964. }
  965. if ($search_start > 0) {
  966. $sql .= " AND date_creation >= '".$this->db->idate($search_start)."'";
  967. }
  968. if ($search_end > 0) {
  969. $sql .= " AND date_creation <= '".$this->db->idate($search_end)."'";
  970. }
  971. if ($search_ref != '') {
  972. $sql .= natural_search("ref_object", $search_ref);
  973. }
  974. if ($search_amount != '') {
  975. $sql .= natural_search("amounts", $search_amount, 1);
  976. }
  977. if ($search_code != '' && $search_code != '-1') {
  978. $sql .= natural_search("action", $search_code, 3);
  979. }
  980. $sql .= $this->db->order($sortfield, $sortorder);
  981. $sql .= $this->db->plimit($limit + 1); // We want more, because we will stop into loop later with error if we reach max
  982. $res = $this->db->query($sql);
  983. if ($res) {
  984. $results = array();
  985. $i = 0;
  986. while ($obj = $this->db->fetch_object($res)) {
  987. $i++;
  988. if ($i > $limit) {
  989. // Too many record, we will consume too much memory
  990. return -2;
  991. }
  992. //if (!isset($cachedlogs[$obj->rowid]))
  993. //{
  994. $b = new BlockedLog($this->db);
  995. $b->fetch($obj->rowid);
  996. //$b->loadTrackedEvents();
  997. //$cachedlogs[$obj->rowid] = $b;
  998. //}
  999. //$results[] = $cachedlogs[$obj->rowid];
  1000. $results[] = $b;
  1001. }
  1002. return $results;
  1003. }
  1004. return -1;
  1005. }
  1006. /**
  1007. * Return the signature (hash) of the "genesis-block" (Block 0).
  1008. *
  1009. * @return string Signature of genesis-block for current conf->entity
  1010. */
  1011. public function getSignature()
  1012. {
  1013. global $db, $conf, $mysoc;
  1014. if (!getDolGlobalString('BLOCKEDLOG_ENTITY_FINGERPRINT')) { // creation of a unique fingerprint
  1015. require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
  1016. require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
  1017. require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
  1018. $fingerprint = dol_hash(print_r($mysoc, true).getRandomPassword(1), '5');
  1019. dolibarr_set_const($db, 'BLOCKEDLOG_ENTITY_FINGERPRINT', $fingerprint, 'chaine', 0, 'Numeric Unique Fingerprint', $conf->entity);
  1020. $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT = $fingerprint;
  1021. }
  1022. return $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT;
  1023. }
  1024. /**
  1025. * Check if module was already used or not for at least one recording.
  1026. *
  1027. * @param int $ignoresystem Ignore system events for the test
  1028. * @return bool
  1029. */
  1030. public function alreadyUsed($ignoresystem = 0)
  1031. {
  1032. global $conf;
  1033. $result = false;
  1034. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog";
  1035. $sql .= " WHERE entity = ".$conf->entity;
  1036. if ($ignoresystem) {
  1037. $sql .= " AND action not in ('MODULE_SET','MODULE_RESET')";
  1038. }
  1039. $sql .= $this->db->plimit(1);
  1040. $res = $this->db->query($sql);
  1041. if ($res !== false) {
  1042. $obj = $this->db->fetch_object($res);
  1043. if ($obj) {
  1044. $result = true;
  1045. }
  1046. } else {
  1047. dol_print_error($this->db);
  1048. }
  1049. dol_syslog("Module Blockedlog alreadyUsed with ignoresystem=".$ignoresystem." is ".$result);
  1050. return $result;
  1051. }
  1052. }