dolibarr  x.y.z
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 && empty($user->rights->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')) {
75  $search_start = dol_time_plus_duree(dol_now(), '-1', 'w');
76 }
77 
78 // Load variable for pagination
79 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
80 $sortfield = GETPOST('sortfield', 'aZ09comma');
81 $sortorder = GETPOST('sortorder', 'aZ09comma');
82 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
83 if (empty($page) || $page == -1) {
84  $page = 0;
85 } // If $page is not defined, or '' or -1
86 $offset = $limit * $page;
87 $pageprev = $page - 1;
88 $pagenext = $page + 1;
89 
90 if (empty($sortfield)) {
91  $sortfield = 'rowid';
92 }
93 if (empty($sortorder)) {
94  $sortorder = 'DESC';
95 }
96 
97 $block_static = new BlockedLog($db);
98 $block_static->loadTrackedEvents();
99 
100 $result = restrictedArea($user, 'blockedlog', 0, '');
101 
102 // Execution Time
103 $max_execution_time_for_importexport = (empty($conf->global->EXPORT_MAX_EXECUTION_TIME) ? 300 : $conf->global->EXPORT_MAX_EXECUTION_TIME); // 5mn if not defined
104 $max_time = @ini_get("max_execution_time");
105 if ($max_time && $max_time < $max_execution_time_for_importexport) {
106  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.");
107  @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
108 }
109 
110 
111 /*
112  * Actions
113  */
114 
115 // Purge search criteria
116 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
117  $search_id = '';
118  $search_fk_user = '';
119  $search_start = -1;
120  $search_end = -1;
121  $search_code = '';
122  $search_ref = '';
123  $search_amount = '';
124  $search_showonlyerrors = 0;
125  $toselect = array();
126  $search_array_options = array();
127 }
128 
129 if ($action === 'downloadblockchain') {
130  $auth = new BlockedLogAuthority($db);
131 
132  $bc = $auth->getLocalBlockChain();
133 
134  header('Content-Type: application/octet-stream');
135  header("Content-Transfer-Encoding: Binary");
136  header("Content-disposition: attachment; filename=\"".$auth->signature.".certif\"");
137 
138  echo $bc;
139 
140  exit;
141 } elseif (GETPOST('downloadcsv', 'alpha')) {
142  $error = 0;
143 
144  $previoushash = '';
145  $firstid = '';
146 
147  if (!$error) {
148  // Get ID of first line
149  $sql = "SELECT rowid,date_creation,tms,user_fullname,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user,object_data";
150  $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
151  $sql .= " WHERE entity = ".$conf->entity;
152  if (GETPOST('monthtoexport', 'int') > 0 || GETPOST('yeartoexport', 'int') > 0) {
153  $dates = dol_get_first_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 1);
154  $datee = dol_get_last_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 12);
155  $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
156  }
157  $sql .= " ORDER BY rowid ASC"; // Required so we get the first one
158  $sql .= $db->plimit(1);
159 
160  $res = $db->query($sql);
161  if ($res) {
162  // Make the first fetch to get first line
163  $obj = $db->fetch_object($res);
164  if ($obj) {
165  $previoushash = $block_static->getPreviousHash(0, $obj->rowid);
166  $firstid = $obj->rowid;
167  } else { // If not data found for filter, we do not need previoushash neither firstid
168  $previoushash = 'nodata';
169  $firstid = '';
170  }
171  } else {
172  $error++;
173  setEventMessages($db->lasterror, null, 'errors');
174  }
175  }
176 
177  if (!$error) {
178  // Now restart request with all data = no limit(1) in sql request
179  $sql = "SELECT rowid, date_creation, tms, user_fullname, action, amounts, element, fk_object, date_object, ref_object, signature, fk_user, object_data, object_version";
180  $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
181  $sql .= " WHERE entity = ".((int) $conf->entity);
182  if (GETPOST('monthtoexport', 'int') > 0 || GETPOST('yeartoexport', 'int') > 0) {
183  $dates = dol_get_first_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 1);
184  $datee = dol_get_last_day(GETPOST('yeartoexport', 'int'), GETPOST('monthtoexport', 'int') ?GETPOST('monthtoexport', 'int') : 12);
185  $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
186  }
187  $sql .= " ORDER BY rowid ASC"; // Required so later we can use the parameter $previoushash of checkSignature()
188 
189  $res = $db->query($sql);
190  if ($res) {
191  header('Content-Type: application/octet-stream');
192  header("Content-Transfer-Encoding: Binary");
193  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\"");
194 
195  print $langs->transnoentities('Id')
196  .';'.$langs->transnoentities('Date')
197  .';'.$langs->transnoentities('User')
198  .';'.$langs->transnoentities('Action')
199  .';'.$langs->transnoentities('Element')
200  .';'.$langs->transnoentities('Amounts')
201  .';'.$langs->transnoentities('ObjectId')
202  .';'.$langs->transnoentities('Date')
203  .';'.$langs->transnoentities('Ref')
204  .';'.$langs->transnoentities('Fingerprint')
205  .';'.$langs->transnoentities('Status')
206  .';'.$langs->transnoentities('Note')
207  .';'.$langs->transnoentities('Version')
208  .';'.$langs->transnoentities('FullData')
209  ."\n";
210 
211  $loweridinerror = 0;
212  $i = 0;
213 
214  while ($obj = $db->fetch_object($res)) {
215  // We set here all data used into signature calculation (see checkSignature method) and more
216  // IMPORTANT: We must have here, the same rule for transformation of data than into the fetch method (db->jdate for date, ...)
217  $block_static->id = $obj->rowid;
218  $block_static->date_creation = $db->jdate($obj->date_creation);
219  $block_static->date_modification = $db->jdate($obj->tms);
220  $block_static->action = $obj->action;
221  $block_static->fk_object = $obj->fk_object;
222  $block_static->element = $obj->element;
223  $block_static->amounts = (double) $obj->amounts;
224  $block_static->ref_object = $obj->ref_object;
225  $block_static->date_object = $db->jdate($obj->date_object);
226  $block_static->user_fullname = $obj->user_fullname;
227  $block_static->fk_user = $obj->fk_user;
228  $block_static->signature = $obj->signature;
229  $block_static->object_data = $block_static->dolDecodeBlockedData($obj->object_data);
230  $block_static->object_version = $obj->object_version;
231 
232  $checksignature = $block_static->checkSignature($previoushash); // If $previoushash is not defined, checkSignature will search it
233 
234  if ($checksignature) {
235  $statusofrecord = 'Valid';
236  if ($loweridinerror > 0) {
237  $statusofrecordnote = 'ValidButFoundAPreviousKO';
238  } else {
239  $statusofrecordnote = '';
240  }
241  } else {
242  $statusofrecord = 'KO';
243  $statusofrecordnote = 'LineCorruptedOrNotMatchingPreviousOne';
244  $loweridinerror = $obj->rowid;
245  }
246 
247  if ($i == 0) {
248  $statusofrecordnote = $langs->trans("PreviousFingerprint").': '.$previoushash.($statusofrecordnote ? ' - '.$statusofrecordnote : '');
249  }
250  print $obj->rowid;
251  print ';'.$obj->date_creation;
252  print ';"'.str_replace('"', '""', $obj->user_fullname).'"';
253  print ';'.$obj->action;
254  print ';'.$obj->element;
255  print ';'.$obj->amounts;
256  print ';'.$obj->fk_object;
257  print ';'.$obj->date_object;
258  print ';"'.str_replace('"', '""', $obj->ref_object).'"';
259  print ';'.$obj->signature;
260  print ';'.$statusofrecord;
261  print ';'.$statusofrecordnote;
262  print ';'.$obj->object_version;
263  print ';"'.str_replace('"', '""', $obj->object_data).'"';
264  print "\n";
265 
266  // Set new previous hash for next fetch
267  $previoushash = $obj->signature;
268 
269  $i++;
270  }
271 
272  exit;
273  } else {
274  setEventMessages($db->lasterror, null, 'errors');
275  }
276  }
277 }
278 
279 
280 /*
281  * View
282  */
283 
284 $form = new Form($db);
285 
286 if (GETPOST('withtab', 'alpha')) {
287  $title = $langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog');
288 } else {
289  $title = $langs->trans("BrowseBlockedLog");
290 }
291 $help_url="EN:Module_Unalterable_Archives_-_Logs|FR:Module_Archives_-_Logs_Inaltérable";
292 
293 llxHeader('', $title, $help_url);
294 
295 $MAXLINES = 10000;
296 
297 $blocks = $block_static->getLog('all', $search_id, $MAXLINES, $sortfield, $sortorder, $search_fk_user, $search_start, $search_end, $search_ref, $search_amount, $search_code);
298 if (!is_array($blocks)) {
299  if ($blocks == -2) {
300  setEventMessages($langs->trans("TooManyRecordToScanRestrictFilters", $MAXLINES), null, 'errors');
301  } else {
302  dol_print_error($block_static->db, $block_static->error, $block_static->errors);
303  exit;
304  }
305 }
306 
307 $linkback = '';
308 if (GETPOST('withtab', 'alpha')) {
309  $linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
310 }
311 
312 print load_fiche_titre($title, $linkback);
313 
314 if (GETPOST('withtab', 'alpha')) {
316  print dol_get_fiche_head($head, 'fingerprints', '', -1);
317 }
318 
319 print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("FingerprintsDesc")."<br></span>\n";
320 
321 print '<br>';
322 
323 $param = '';
324 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
325  $param .= '&contextpage='.urlencode($contextpage);
326 }
327 if ($limit > 0 && $limit != $conf->liste_limit) {
328  $param .= '&limit='.urlencode($limit);
329 }
330 if ($search_id != '') {
331  $param .= '&search_id='.urlencode($search_id);
332 }
333 if ($search_fk_user > 0) {
334  $param .= '&search_fk_user='.urlencode($search_fk_user);
335 }
336 if ($search_startyear > 0) {
337  $param .= '&search_startyear='.urlencode($search_startyear);
338 }
339 if ($search_startmonth > 0) {
340  $param .= '&search_startmonth='.urlencode($search_startmonth);
341 }
342 if ($search_startday > 0) {
343  $param .= '&search_startday='.urlencode($search_startday);
344 }
345 if ($search_endyear > 0) {
346  $param .= '&search_endyear='.urlencode($search_endyear);
347 }
348 if ($search_endmonth > 0) {
349  $param .= '&search_endmonth='.urlencode($search_endmonth);
350 }
351 if ($search_endday > 0) {
352  $param .= '&search_endday='.urlencode($search_endday);
353 }
354 if ($search_showonlyerrors > 0) {
355  $param .= '&search_showonlyerrors='.urlencode($search_showonlyerrors);
356 }
357 if ($optioncss != '') {
358  $param .= '&optioncss='.urlencode($optioncss);
359 }
360 if (GETPOST('withtab', 'alpha')) {
361  $param .= '&withtab='.urlencode(GETPOST('withtab', 'alpha'));
362 }
363 
364 // Add $param from extra fields
365 //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
366 
367 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
368 print '<input type="hidden" name="token" value="'.newToken().'">';
369 
370 print '<div class="right">';
371 print $langs->trans("RestrictYearToExport").': ';
372 $smonth = GETPOST('monthtoexport', 'int');
373 // Month
374 $retstring = '';
375 $retstring .= '<select class="flat valignmiddle maxwidth75imp marginrightonly" id="monthtoexport" name="monthtoexport">';
376 $retstring .= '<option value="0" selected>&nbsp;</option>';
377 for ($month = 1; $month <= 12; $month++) {
378  $retstring .= '<option value="'.$month.'"'.($month == $smonth ? ' selected' : '').'>';
379  $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
380  $retstring .= "</option>";
381 }
382 $retstring .= "</select>";
383 print $retstring;
384 print '<input type="text" name="yeartoexport" class="valignmiddle maxwidth50imp" value="'.GETPOST('yeartoexport', 'int').'">';
385 print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
386 print '<input type="submit" name="downloadcsv" class="button" value="'.$langs->trans('DownloadLogCSV').'">';
387 if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) {
388  print ' | <a href="?action=downloadblockchain'.(GETPOST('withtab', 'alpha') ? '&withtab='.GETPOST('withtab', 'alpha') : '').'">'.$langs->trans('DownloadBlockChain').'</a>';
389 }
390 print ' </div><br>';
391 
392 print '</form>';
393 
394 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
395 
396 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
397 
398 if ($optioncss != '') {
399  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
400 }
401 print '<input type="hidden" name="token" value="'.newToken().'">';
402 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
403 print '<input type="hidden" name="action" value="list">';
404 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
405 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
406 print '<input type="hidden" name="page" value="'.$page.'">';
407 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
408 print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
409 
410 print '<table class="noborder centpercent">';
411 
412 // Line of filters
413 print '<tr class="liste_titre_filter">';
414 
415 print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_id" value="'.dol_escape_htmltag($search_id).'"></td>';
416 
417 print '<td class="liste_titre">';
418 //print $langs->trans("from").': ';
419 print $form->selectDate($search_start, 'search_start');
420 //print '<br>';
421 //print $langs->trans("to").': ';
422 print $form->selectDate($search_end, 'search_end');
423 print '</td>';
424 
425 // User
426 print '<td class="liste_titre">';
427 print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200');
428 
429 print '</td>';
430 
431 // Actions code
432 $langs->load("blockedlog");
433 print '<td class="liste_titre">';
434 print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth200', 1);
435 print '</td>';
436 
437 // Ref
438 print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
439 
440 // Link to ref
441 print '<td class="liste_titre"></td>';
442 
443 // Amount
444 print '<td class="liste_titre right"><input type="text" class="maxwidth50" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
445 
446 // Full data
447 print '<td class="liste_titre"></td>';
448 
449 // Fingerprint
450 print '<td class="liste_titre"></td>';
451 
452 // Status
453 print '<td class="liste_titre">';
454 $array = array("1" => "OnlyNonValid");
455 print $form->selectarray('search_showonlyerrors', $array, $search_showonlyerrors, 1, 0, 0, '', 1, 0, 0, 'ASC', 'search_status maxwidth200 onrightofpage', 1);
456 print '</td>';
457 
458 // Status note
459 print '<td class="liste_titre"></td>';
460 
461 // Action column
462 print '<td class="liste_titre" align="middle">';
463 $searchpicto = $form->showFilterButtons();
464 print $searchpicto;
465 print '</td>';
466 
467 print '</tr>';
468 
469 print '<tr class="liste_titre">';
470 print getTitleFieldOfList($langs->trans('#'), 0, $_SERVER["PHP_SELF"], 'rowid', '', $param, '', $sortfield, $sortorder, 'minwidth50 ')."\n";
471 print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"], 'date_creation', '', $param, '', $sortfield, $sortorder, '')."\n";
472 print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"], 'user_fullname', '', $param, '', $sortfield, $sortorder, '')."\n";
473 print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
474 print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"], 'ref_object', '', $param, '', $sortfield, $sortorder, '')."\n";
475 print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
476 print getTitleFieldOfList($langs->trans('Amount'), 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder, '')."\n";
477 print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"], '', '', $param, 'align="center"', $sortfield, $sortorder, '')."\n";
478 print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
479 print getTitleFieldOfList($langs->trans('Status'), 0, $_SERVER["PHP_SELF"], '', '', $param, 'align="center"', $sortfield, $sortorder, '')."\n";
480 print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, 'align="center"', $sortfield, $sortorder, '')."\n";
481 print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'align="center"', $sortfield, $sortorder, '')."\n";
482 print '</tr>';
483 
484 if (!empty($conf->global->BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR)) {
485  // This is version that is faster but require more memory and report errors that are outside the filter range
486 
487  // 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
488  // to find the $loweridinerror.
489 } else {
490  // This is version that optimize the memory (but will not report errors that are outside the filter range)
491  $loweridinerror = 0;
492  $checkresult = array();
493  $checkdetail = array();
494  if (is_array($blocks)) {
495  foreach ($blocks as &$block) {
496  $tmpcheckresult = $block->checkSignature('', 1); // Note: this make a sql request at each call, we can't avoid this as the sorting order is various
497 
498  $checksignature = $tmpcheckresult['checkresult'];
499 
500  $checkresult[$block->id] = $checksignature; // false if error
501  $checkdetail[$block->id] = $tmpcheckresult;
502 
503  if (!$checksignature) {
504  if (empty($loweridinerror)) {
505  $loweridinerror = $block->id;
506  } else {
507  $loweridinerror = min($loweridinerror, $block->id);
508  }
509  }
510  }
511  }
512 }
513 
514 if (is_array($blocks)) {
515  $nbshown = 0;
516  $MAXFORSHOWLINK = 100;
517  $object_link = '';
518 
519  foreach ($blocks as &$block) {
520  //if (empty($search_showonlyerrors) || ! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror))
521  if (empty($search_showonlyerrors) || !$checkresult[$block->id]) {
522  $nbshown++;
523 
524  if ($nbshown < $MAXFORSHOWLINK) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output
525  $object_link = $block->getObjectLink();
526  } else {
527  $object_link = $block->element.'/'.$block->fk_object;
528  }
529 
530  print '<tr class="oddeven">';
531 
532  // ID
533  print '<td>'.dol_escape_htmltag($block->id).'</td>';
534 
535  // Date
536  print '<td class="nowraponall">'.dol_print_date($block->date_creation, 'dayhour').'</td>';
537 
538  // User
539  print '<td>';
540  //print $block->getUser()
541  print dol_escape_htmltag($block->user_fullname);
542  print '</td>';
543 
544  // Action
545  print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($langs->trans('log'.$block->action)).'">'.$langs->trans('log'.$block->action).'</td>';
546 
547  // Ref
548  print '<td class="nowraponall">';
549  print $block->ref_object;
550  print '</td>';
551 
552  // Link to source object
553  print '<td'.(preg_match('/<a/', $object_link) ? ' class="nowrap"' : '').'><!-- object_link -->'.$object_link.'</td>';
554 
555  // Amount
556  print '<td class="right nowraponall">'.price($block->amounts).'</td>';
557 
558  // Details link
559  print '<td align="center"><a href="#" data-blockid="'.$block->id.'" rel="show-info">'.img_info($langs->trans('ShowDetails')).'</a></td>';
560 
561  // Fingerprint
562  print '<td class="nowrap">';
563  $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("Saved").':<br>'.$block->signature;
564  $texttoshow .= '<br><br>'.$langs->trans("Fingerprint").' - Recalculated sha256(previoushash * data):<br>'.$checkdetail[$block->id]['calculatedsignature'];
565  $texttoshow .= '<br><span class="opacitymedium">'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].'</span>';
566  //$texttoshow .= '<br>keyforsignature='.$checkdetail[$block->id]['keyforsignature'];
567  print $form->textwithpicto(dol_trunc($block->signature, '8'), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id);
568  print '</td>';
569 
570  // Status
571  print '<td class="center">';
572  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
573  if ($checkresult[$block->id]) {
574  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidityButChainIsKo').'">OK</span>';
575  } else {
576  print '<span class="badge badge-status8 badge-status" title="'.$langs->trans('KoCheckFingerprintValidity').'">KO</span>';
577  }
578  } else {
579  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidity').'">OK</span>';
580  }
581  print '</td>';
582 
583  // Note
584  print '<td class="center">';
585  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
586  if ($checkresult[$block->id]) {
587  print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo'));
588  }
589  }
590 
591  if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
592  print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black'));
593  }
594  print '</td>';
595 
596  print '<td></td>';
597 
598  print '</tr>';
599  }
600  }
601 
602  if ($nbshown == 0) {
603  print '<tr><td colspan="12"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
604  }
605 }
606 
607 print '</table>';
608 
609 print '</div>';
610 
611 print '</form>';
612 
613 // Javascript to manage the showinfo popup
614 print '<script type="text/javascript">
615 
616 jQuery(document).ready(function () {
617  jQuery("#dialogforpopup").dialog(
618  { closeOnEscape: true, classes: { "ui-dialog": "highlight" },
619  maxHeight: window.innerHeight-60, height: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).',
620  modal: true,
621  autoOpen: false }).css("z-index: 5000");
622 
623  $("a[rel=show-info]").click(function() {
624 
625  console.log("We click on tooltip, we open popup and get content using an ajax call");
626 
627  var fk_block = $(this).attr("data-blockid");
628 
629  $.ajax({
630  method: "GET",
631  data: { token: \''.currentToken().'\' },
632  url: "'.DOL_URL_ROOT.'/blockedlog/ajax/block-info.php?id="+fk_block,
633  dataType: "html"
634  }).done(function(data) {
635  jQuery("#dialogforpopup").html(data);
636  });
637 
638  jQuery("#dialogforpopup").dialog("open");
639  });
640 })
641 </script>'."\n";
642 
643 
644 if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
645  ?>
646  <script type="text/javascript">
647 
648  $.ajax({
649  method: "GET",
650  data: { token: '<?php echo currentToken() ?>' },
651  url: '<?php echo DOL_URL_ROOT.'/blockedlog/ajax/check_signature.php' ?>',
652  dataType: 'html'
653  }).done(function(data) {
654  if(data == 'hashisok') {
655  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureOK'), 'on') ?>');
656  }
657  else{
658  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityDidntReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureKO'), 'off') ?>');
659  }
660 
661  });
662 
663  </script>
664  <?php
665 }
666 
667 if (GETPOST('withtab', 'alpha')) {
668  print dol_get_fiche_end();
669 }
670 
671 print '<br><br>';
672 
673 // End of page
674 llxFooter();
675 $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($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:575
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:121
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:594
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='')
Show tabs of a record.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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'.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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.
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
img_info($titlealt='default')
Show info logo.
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.