dolibarr  18.0.6
blockedlog_list.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
3  * Copyright (C) 2017-2018 Laurent Destailleur <eldy@destailleur.fr>
4  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
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 
27 // Load Dolibarr environment
28 require '../../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
30 require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34 
35 // Load translation files required by the page
36 $langs->loadLangs(array('admin', 'bills', 'blockedlog', 'other'));
37 
38 // Access Control
39 if ((!$user->admin && !$user->hasRight('blockedlog', 'read')) || empty($conf->blockedlog->enabled)) {
41 }
42 
43 // Get Parameters
44 $action = GETPOST('action', 'aZ09');
45 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'blockedloglist'; // To manage different context of search
46 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
47 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
48 
49 $search_showonlyerrors = GETPOST('search_showonlyerrors', 'int');
50 if ($search_showonlyerrors < 0) {
51  $search_showonlyerrors = 0;
52 }
53 
54 $search_startyear = GETPOST('search_startyear', 'int');
55 $search_startmonth = GETPOST('search_startmonth', 'int');
56 $search_startday = GETPOST('search_startday', 'int');
57 $search_endyear = GETPOST('search_endyear', 'int');
58 $search_endmonth = GETPOST('search_endmonth', 'int');
59 $search_endday = GETPOST('search_endday', 'int');
60 $search_id = GETPOST('search_id', 'alpha');
61 $search_fk_user = GETPOST('search_fk_user', 'intcomma');
62 $search_start = -1;
63 if ($search_startyear != '') {
64  $search_start = dol_mktime(0, 0, 0, $search_startmonth, $search_startday, $search_startyear);
65 }
66 $search_end = -1;
67 if (GETPOST('search_endyear') != '') {
68  $search_end = dol_mktime(23, 59, 59, GETPOST('search_endmonth'), GETPOST('search_endday'), GETPOST('search_endyear'));
69 }
70 $search_code = GETPOST('search_code', 'alpha');
71 $search_ref = GETPOST('search_ref', 'alpha');
72 $search_amount = GETPOST('search_amount', 'alpha');
73 
74 if (($search_start == -1 || empty($search_start)) && !GETPOSTISSET('search_startmonth') && !GETPOSTISSET('begin')) {
75  $search_start = dol_time_plus_duree(dol_now(), '-1', 'w');
76  $tmparray = dol_getdate($search_start);
77  $search_startday = $tmparray['mday'];
78  $search_startmonth = $tmparray['mon'];
79  $search_startyear = $tmparray['year'];
80 }
81 
82 // Load variable for pagination
83 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
84 $sortfield = GETPOST('sortfield', 'aZ09comma');
85 $sortorder = GETPOST('sortorder', 'aZ09comma');
86 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
87 if (empty($page) || $page == -1) {
88  $page = 0;
89 } // If $page is not defined, or '' or -1
90 $offset = $limit * $page;
91 $pageprev = $page - 1;
92 $pagenext = $page + 1;
93 
94 if (empty($sortfield)) {
95  $sortfield = 'rowid';
96 }
97 if (empty($sortorder)) {
98  $sortorder = 'DESC';
99 }
100 
101 $block_static = new BlockedLog($db);
102 $block_static->loadTrackedEvents();
103 
104 $result = restrictedArea($user, 'blockedlog', 0, '');
105 
106 // Execution Time
107 $max_execution_time_for_importexport = (empty($conf->global->EXPORT_MAX_EXECUTION_TIME) ? 300 : $conf->global->EXPORT_MAX_EXECUTION_TIME); // 5mn if not defined
108 $max_time = @ini_get("max_execution_time");
109 if ($max_time && $max_time < $max_execution_time_for_importexport) {
110  dol_syslog("max_execution_time=".$max_time." is lower than max_execution_time_for_importexport=".$max_execution_time_for_importexport.". We try to increase it dynamically.");
111  @ini_set("max_execution_time", $max_execution_time_for_importexport); // This work only if safe mode is off. also web servers has timeout of 300
112 }
113 
114 
115 /*
116  * Actions
117  */
118 
119 // Purge search criteria
120 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
121  $search_id = '';
122  $search_fk_user = '';
123  $search_start = -1;
124  $search_end = -1;
125  $search_code = '';
126  $search_ref = '';
127  $search_amount = '';
128  $search_showonlyerrors = 0;
129  $search_startyear = '';
130  $search_startmonth = '';
131  $search_startday = '';
132  $search_endyear = '';
133  $search_endmonth = '';
134  $search_endday = '';
135  $toselect = array();
136  $search_array_options = array();
137 }
138 
139 if ($action === 'downloadblockchain') {
140  $auth = new BlockedLogAuthority($db);
141 
142  $bc = $auth->getLocalBlockChain();
143 
144  header('Content-Type: application/octet-stream');
145  header("Content-Transfer-Encoding: Binary");
146  header("Content-disposition: attachment; filename=\"".$auth->signature.".certif\"");
147 
148  echo $bc;
149 
150  exit;
151 } elseif (GETPOST('downloadcsv', 'alpha')) {
152  $error = 0;
153 
154  $previoushash = '';
155  $firstid = '';
156 
157  if (!$error) {
158  // Get ID of first line
159  $sql = "SELECT rowid,date_creation,tms,user_fullname,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user,object_data";
160  $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
161  $sql .= " WHERE entity = ".$conf->entity;
162  if (GETPOST('monthtoexport', 'int') > 0 || GETPOST('yeartoexport', 'int') > 0) {
163  $dates = dol_get_first_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 1);
164  $datee = dol_get_last_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 12);
165  $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
166  }
167  $sql .= " ORDER BY rowid ASC"; // Required so we get the first one
168  $sql .= $db->plimit(1);
169 
170  $res = $db->query($sql);
171  if ($res) {
172  // Make the first fetch to get first line
173  $obj = $db->fetch_object($res);
174  if ($obj) {
175  $previoushash = $block_static->getPreviousHash(0, $obj->rowid);
176  $firstid = $obj->rowid;
177  } else { // If not data found for filter, we do not need previoushash neither firstid
178  $previoushash = 'nodata';
179  $firstid = '';
180  }
181  } else {
182  $error++;
183  setEventMessages($db->lasterror, null, 'errors');
184  }
185  }
186 
187  if (!$error) {
188  // Now restart request with all data = no limit(1) in sql request
189  $sql = "SELECT rowid, date_creation, tms, user_fullname, action, amounts, element, fk_object, date_object, ref_object, signature, fk_user, object_data, object_version";
190  $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
191  $sql .= " WHERE entity = ".((int) $conf->entity);
192  if (GETPOST('monthtoexport', 'int') > 0 || GETPOST('yeartoexport', 'int') > 0) {
193  $dates = dol_get_first_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 1);
194  $datee = dol_get_last_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 12);
195  $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
196  }
197  $sql .= " ORDER BY rowid ASC"; // Required so later we can use the parameter $previoushash of checkSignature()
198 
199  $res = $db->query($sql);
200  if ($res) {
201  header('Content-Type: application/octet-stream');
202  header("Content-Transfer-Encoding: Binary");
203  header("Content-disposition: attachment; filename=\"unalterable-log-archive-".$dolibarr_main_db_name."-".(GETPOST('yeartoexport', 'int') > 0 ? GETPOST('yeartoexport', 'int').(GETPOST('monthtoexport', 'int') > 0 ?sprintf("%02d", GETPOST('monthtoexport', 'int')) : '').'-' : '').$previoushash.".csv\"");
204 
205  print $langs->transnoentities('Id')
206  .';'.$langs->transnoentities('Date')
207  .';'.$langs->transnoentities('User')
208  .';'.$langs->transnoentities('Action')
209  .';'.$langs->transnoentities('Element')
210  .';'.$langs->transnoentities('Amounts')
211  .';'.$langs->transnoentities('ObjectId')
212  .';'.$langs->transnoentities('Date')
213  .';'.$langs->transnoentities('Ref')
214  .';'.$langs->transnoentities('Fingerprint')
215  .';'.$langs->transnoentities('Status')
216  .';'.$langs->transnoentities('Note')
217  .';'.$langs->transnoentities('Version')
218  .';'.$langs->transnoentities('FullData')
219  ."\n";
220 
221  $loweridinerror = 0;
222  $i = 0;
223 
224  while ($obj = $db->fetch_object($res)) {
225  // We set here all data used into signature calculation (see checkSignature method) and more
226  // IMPORTANT: We must have here, the same rule for transformation of data than into the fetch method (db->jdate for date, ...)
227  $block_static->id = $obj->rowid;
228  $block_static->date_creation = $db->jdate($obj->date_creation);
229  $block_static->date_modification = $db->jdate($obj->tms);
230  $block_static->action = $obj->action;
231  $block_static->fk_object = $obj->fk_object;
232  $block_static->element = $obj->element;
233  $block_static->amounts = (double) $obj->amounts;
234  $block_static->ref_object = $obj->ref_object;
235  $block_static->date_object = $db->jdate($obj->date_object);
236  $block_static->user_fullname = $obj->user_fullname;
237  $block_static->fk_user = $obj->fk_user;
238  $block_static->signature = $obj->signature;
239  $block_static->object_data = $block_static->dolDecodeBlockedData($obj->object_data);
240  $block_static->object_version = $obj->object_version;
241 
242  $checksignature = $block_static->checkSignature($previoushash); // If $previoushash is not defined, checkSignature will search it
243 
244  if ($checksignature) {
245  $statusofrecord = 'Valid';
246  if ($loweridinerror > 0) {
247  $statusofrecordnote = 'ValidButFoundAPreviousKO';
248  } else {
249  $statusofrecordnote = '';
250  }
251  } else {
252  $statusofrecord = 'KO';
253  $statusofrecordnote = 'LineCorruptedOrNotMatchingPreviousOne';
254  $loweridinerror = $obj->rowid;
255  }
256 
257  if ($i == 0) {
258  $statusofrecordnote = $langs->trans("PreviousFingerprint").': '.$previoushash.($statusofrecordnote ? ' - '.$statusofrecordnote : '');
259  }
260  print $obj->rowid;
261  print ';'.$obj->date_creation;
262  print ';"'.str_replace('"', '""', $obj->user_fullname).'"';
263  print ';'.$obj->action;
264  print ';'.$obj->element;
265  print ';'.$obj->amounts;
266  print ';'.$obj->fk_object;
267  print ';'.$obj->date_object;
268  print ';"'.str_replace('"', '""', $obj->ref_object).'"';
269  print ';'.$obj->signature;
270  print ';'.$statusofrecord;
271  print ';'.$statusofrecordnote;
272  print ';'.$obj->object_version;
273  print ';"'.str_replace('"', '""', $obj->object_data).'"';
274  print "\n";
275 
276  // Set new previous hash for next fetch
277  $previoushash = $obj->signature;
278 
279  $i++;
280  }
281 
282  exit;
283  } else {
284  setEventMessages($db->lasterror, null, 'errors');
285  }
286  }
287 }
288 
289 
290 /*
291  * View
292  */
293 
294 $form = new Form($db);
295 
296 if (GETPOST('withtab', 'alpha')) {
297  $title = $langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog');
298 } else {
299  $title = $langs->trans("BrowseBlockedLog");
300 }
301 $help_url="EN:Module_Unalterable_Archives_-_Logs|FR:Module_Archives_-_Logs_Inaltérable";
302 
303 llxHeader('', $title, $help_url);
304 
305 $MAXLINES = 10000;
306 
307 $blocks = $block_static->getLog('all', $search_id, $MAXLINES, $sortfield, $sortorder, $search_fk_user, $search_start, $search_end, $search_ref, $search_amount, $search_code);
308 if (!is_array($blocks)) {
309  if ($blocks == -2) {
310  setEventMessages($langs->trans("TooManyRecordToScanRestrictFilters", $MAXLINES), null, 'errors');
311  } else {
312  dol_print_error($block_static->db, $block_static->error, $block_static->errors);
313  exit;
314  }
315 }
316 
317 $linkback = '';
318 if (GETPOST('withtab', 'alpha')) {
319  $linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
320 }
321 
322 print load_fiche_titre($title, $linkback);
323 
324 if (GETPOST('withtab', 'alpha')) {
326  print dol_get_fiche_head($head, 'fingerprints', '', -1);
327 }
328 
329 print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("FingerprintsDesc")."<br></span>\n";
330 
331 print '<br>';
332 
333 $param = '';
334 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
335  $param .= '&contextpage='.urlencode($contextpage);
336 }
337 if ($limit > 0 && $limit != $conf->liste_limit) {
338  $param .= '&limit='.((int) $limit);
339 }
340 if ($search_id != '') {
341  $param .= '&search_id='.urlencode($search_id);
342 }
343 if ($search_fk_user > 0) {
344  $param .= '&search_fk_user='.urlencode($search_fk_user);
345 }
346 if ($search_startyear > 0) {
347  $param .= '&search_startyear='.urlencode($search_startyear);
348 }
349 if ($search_startmonth > 0) {
350  $param .= '&search_startmonth='.urlencode($search_startmonth);
351 }
352 if ($search_startday > 0) {
353  $param .= '&search_startday='.urlencode($search_startday);
354 }
355 if ($search_endyear > 0) {
356  $param .= '&search_endyear='.urlencode($search_endyear);
357 }
358 if ($search_endmonth > 0) {
359  $param .= '&search_endmonth='.urlencode($search_endmonth);
360 }
361 if ($search_endday > 0) {
362  $param .= '&search_endday='.urlencode($search_endday);
363 }
364 if ($search_showonlyerrors > 0) {
365  $param .= '&search_showonlyerrors='.urlencode($search_showonlyerrors);
366 }
367 if ($optioncss != '') {
368  $param .= '&optioncss='.urlencode($optioncss);
369 }
370 if (GETPOST('withtab', 'alpha')) {
371  $param .= '&withtab='.urlencode(GETPOST('withtab', 'alpha'));
372 }
373 
374 // Add $param from extra fields
375 //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
376 
377 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
378 print '<input type="hidden" name="token" value="'.newToken().'">';
379 
380 print '<div class="right">';
381 print $langs->trans("RestrictYearToExport").': ';
382 $smonth = GETPOST('monthtoexport', 'int');
383 // Month
384 $retstring = '';
385 $retstring .= '<select class="flat valignmiddle maxwidth75imp marginrightonly" id="monthtoexport" name="monthtoexport">';
386 $retstring .= '<option value="0" selected>&nbsp;</option>';
387 for ($month = 1; $month <= 12; $month++) {
388  $retstring .= '<option value="'.$month.'"'.($month == $smonth ? ' selected' : '').'>';
389  $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
390  $retstring .= "</option>";
391 }
392 $retstring .= "</select>";
393 print $retstring;
394 print '<input type="text" name="yeartoexport" class="valignmiddle maxwidth50imp" value="'.GETPOST('yeartoexport', 'int').'">';
395 print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
396 print '<input type="submit" name="downloadcsv" class="button" value="'.$langs->trans('DownloadLogCSV').'">';
397 if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) {
398  print ' | <a href="?action=downloadblockchain'.(GETPOST('withtab', 'alpha') ? '&withtab='.GETPOST('withtab', 'alpha') : '').'">'.$langs->trans('DownloadBlockChain').'</a>';
399 }
400 print ' </div><br>';
401 
402 print '</form>';
403 
404 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
405 
406 if ($optioncss != '') {
407  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
408 }
409 print '<input type="hidden" name="token" value="'.newToken().'">';
410 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
411 print '<input type="hidden" name="action" value="list">';
412 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
413 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
414 print '<input type="hidden" name="page" value="'.$page.'">';
415 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
416 print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
417 
418 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
419 print '<table class="noborder centpercent">';
420 
421 // Line of filters
422 print '<tr class="liste_titre_filter">';
423 
424 // Action column
425 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
426  print '<td class="liste_titre center">';
427  $searchpicto = $form->showFilterButtons();
428  print $searchpicto;
429  print '</td>';
430 }
431 
432 print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_id" value="'.dol_escape_htmltag($search_id).'"></td>';
433 
434 print '<td class="liste_titre">';
435 //print $langs->trans("from").': ';
436 print $form->selectDate($search_start, 'search_start');
437 //print '<br>';
438 //print $langs->trans("to").': ';
439 print $form->selectDate($search_end, 'search_end');
440 print '</td>';
441 
442 // User
443 print '<td class="liste_titre">';
444 print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200');
445 
446 print '</td>';
447 
448 // Actions code
449 print '<td class="liste_titre">';
450 print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth200', 1);
451 print '</td>';
452 
453 // Ref
454 print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
455 
456 // Link to ref
457 print '<td class="liste_titre"></td>';
458 
459 // Amount
460 print '<td class="liste_titre right"><input type="text" class="maxwidth50" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
461 
462 // Full data
463 print '<td class="liste_titre"></td>';
464 
465 // Fingerprint
466 print '<td class="liste_titre"></td>';
467 
468 // Status
469 print '<td class="liste_titre">';
470 $array = array("1" => "OnlyNonValid");
471 print $form->selectarray('search_showonlyerrors', $array, $search_showonlyerrors, 1, 0, 0, '', 1, 0, 0, 'ASC', 'search_status maxwidth200 onrightofpage', 1);
472 print '</td>';
473 
474 // Status note
475 print '<td class="liste_titre"></td>';
476 
477 // Action column
478 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
479  print '<td class="liste_titre center">';
480  $searchpicto = $form->showFilterButtons();
481  print $searchpicto;
482  print '</td>';
483 }
484 
485 print '</tr>';
486 
487 print '<tr class="liste_titre">';
488 // Action column
489 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
490  print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
491 }
492 print getTitleFieldOfList($langs->trans('#'), 0, $_SERVER["PHP_SELF"], 'rowid', '', $param, '', $sortfield, $sortorder, 'minwidth50 ')."\n";
493 print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"], 'date_creation', '', $param, '', $sortfield, $sortorder, '')."\n";
494 print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"], 'user_fullname', '', $param, '', $sortfield, $sortorder, '')."\n";
495 print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
496 print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"], 'ref_object', '', $param, '', $sortfield, $sortorder, '')."\n";
497 print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
498 print getTitleFieldOfList($langs->trans('Amount'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ')."\n";
499 print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
500 print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
501 print getTitleFieldOfList($langs->trans('Status'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
502 print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
503 // Action column
504 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
505  print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
506 }
507 print '</tr>';
508 
509 if (!empty($conf->global->BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR)) {
510  // This is version that is faster but require more memory and report errors that are outside the filter range
511 
512  // TODO Make a full scan of table in reverse order of id of $block, so we can use the parameter $previoushash into checkSignature to save requests
513  // to find the $loweridinerror.
514 } else {
515  // This is version that optimize the memory (but will not report errors that are outside the filter range)
516  $loweridinerror = 0;
517  $checkresult = array();
518  $checkdetail = array();
519  if (is_array($blocks)) {
520  foreach ($blocks as &$block) {
521  $tmpcheckresult = $block->checkSignature('', 1); // Note: this make a sql request at each call, we can't avoid this as the sorting order is various
522 
523  $checksignature = $tmpcheckresult['checkresult'];
524 
525  $checkresult[$block->id] = $checksignature; // false if error
526  $checkdetail[$block->id] = $tmpcheckresult;
527 
528  if (!$checksignature) {
529  if (empty($loweridinerror)) {
530  $loweridinerror = $block->id;
531  } else {
532  $loweridinerror = min($loweridinerror, $block->id);
533  }
534  }
535  }
536  }
537 }
538 
539 if (is_array($blocks)) {
540  $nbshown = 0;
541  $MAXFORSHOWLINK = 100;
542  $object_link = '';
543 
544  foreach ($blocks as &$block) {
545  //if (empty($search_showonlyerrors) || ! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror))
546  if (empty($search_showonlyerrors) || !$checkresult[$block->id]) {
547  $nbshown++;
548 
549  if ($nbshown < $MAXFORSHOWLINK) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output
550  $object_link = $block->getObjectLink();
551  } else {
552  $object_link = $block->element.'/'.$block->fk_object;
553  }
554 
555  print '<tr class="oddeven">';
556 
557  // Action column
558  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
559  print '<td class="liste_titre">';
560  print '</td>';
561  }
562 
563  // ID
564  print '<td>'.dol_escape_htmltag($block->id).'</td>';
565 
566  // Date
567  print '<td class="nowraponall">'.dol_print_date($block->date_creation, 'dayhour').'</td>';
568 
569  // User
570  print '<td>';
571  //print $block->getUser()
572  print dol_escape_htmltag($block->user_fullname);
573  print '</td>';
574 
575  // Action
576  print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($langs->trans('log'.$block->action)).'">'.$langs->trans('log'.$block->action).'</td>';
577 
578  // Ref
579  print '<td class="nowraponall">';
580  print $block->ref_object;
581  print '</td>';
582 
583  // Link to source object
584  print '<td class="tdoverflowmax150"'.(preg_match('/<a/', $object_link) ? '' : 'title="'.dol_escape_htmltag(dol_string_nohtmltag($object_link)).'"').'>';
585  print '<!-- object_link -->'; // $object_link can be a '<a href' link or a text
586  print $object_link;
587  print '</td>';
588 
589  // Amount
590  print '<td class="right nowraponall">'.price($block->amounts).'</td>';
591 
592  // Details link
593  print '<td class="center"><a href="#" data-blockid="'.$block->id.'" rel="show-info">'.img_info($langs->trans('ShowDetails')).'</a></td>';
594 
595  // Fingerprint
596  print '<td class="nowrap">';
597  $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("Saved").':<br>'.$block->signature;
598  $texttoshow .= '<br><br>'.$langs->trans("Fingerprint").' - Recalculated sha256(previoushash * data):<br>'.$checkdetail[$block->id]['calculatedsignature'];
599  $texttoshow .= '<br><span class="opacitymedium">'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].'</span>';
600  //$texttoshow .= '<br>keyforsignature='.$checkdetail[$block->id]['keyforsignature'];
601  print $form->textwithpicto(dol_trunc($block->signature, '8'), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id);
602  print '</td>';
603 
604  // Status
605  print '<td class="center">';
606  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
607  if ($checkresult[$block->id]) {
608  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidityButChainIsKo').'">OK</span>';
609  } else {
610  print '<span class="badge badge-status8 badge-status" title="'.$langs->trans('KoCheckFingerprintValidity').'">KO</span>';
611  }
612  } else {
613  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidity').'">OK</span>';
614  }
615  print '</td>';
616 
617  // Note
618  print '<td class="center">';
619  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
620  if ($checkresult[$block->id]) {
621  print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo'));
622  }
623  }
624 
625  if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
626  print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black'));
627  }
628  print '</td>';
629 
630  // Action column
631  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
632  print '<td class="liste_titre">';
633  print '</td>';
634  }
635 
636  print '</tr>';
637  }
638  }
639 
640  if ($nbshown == 0) {
641  print '<tr><td colspan="12"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
642  }
643 }
644 
645 print '</table>';
646 
647 print '</div>';
648 
649 print '</form>';
650 
651 // Javascript to manage the showinfo popup
652 print '<script type="text/javascript">
653 
654 jQuery(document).ready(function () {
655  jQuery("#dialogforpopup").dialog(
656  { closeOnEscape: true, classes: { "ui-dialog": "highlight" },
657  maxHeight: window.innerHeight-60, height: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).',
658  modal: true,
659  autoOpen: false }).css("z-index: 5000");
660 
661  $("a[rel=show-info]").click(function() {
662 
663  console.log("We click on tooltip, we open popup and get content using an ajax call");
664 
665  var fk_block = $(this).attr("data-blockid");
666 
667  $.ajax({
668  method: "GET",
669  data: { token: \''.currentToken().'\' },
670  url: "'.DOL_URL_ROOT.'/blockedlog/ajax/block-info.php?id="+fk_block,
671  dataType: "html"
672  }).done(function(data) {
673  jQuery("#dialogforpopup").html(data);
674  });
675 
676  jQuery("#dialogforpopup").dialog("open");
677  });
678 })
679 </script>'."\n";
680 
681 
682 if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
683  ?>
684  <script type="text/javascript">
685 
686  $.ajax({
687  method: "GET",
688  data: { token: '<?php echo currentToken() ?>' },
689  url: '<?php echo DOL_URL_ROOT.'/blockedlog/ajax/check_signature.php' ?>',
690  dataType: 'html'
691  }).done(function(data) {
692  if(data == 'hashisok') {
693  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureOK'), 'on') ?>');
694  }
695  else{
696  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityDidntReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureKO'), 'off') ?>');
697  }
698 
699  });
700 
701  </script>
702  <?php
703 }
704 
705 if (GETPOST('withtab', 'alpha')) {
706  print dol_get_fiche_end();
707 }
708 
709 print '<br><br>';
710 
711 // End of page
712 llxFooter();
713 $db->close();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
blockedlogadmin_prepare_head()
Define head array for tabs of blockedlog tools setup pages.
Class to manage certif authority.
Class to manage Blocked Log.
Class to manage generation of HTML components Only common components must be here.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition: date.lib.php:577
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:122
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:596
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
currentToken()
Return the value of token currently saved into session with name 'token'.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
img_info($titlealt='default')
Show info logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.