dolibarr  19.0.0-dev
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')) {
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='.((int) $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 class="tdoverflowmax150"'.(preg_match('/<a/', $object_link) ? '' : 'title="'.dol_escape_htmltag(dol_string_nohtmltag($object_link)).'"').'>';
554  print '<!-- object_link -->'; // $object_link can be a '<a href' link or a text
555  print $object_link;
556  print '</td>';
557 
558  // Amount
559  print '<td class="right nowraponall">'.price($block->amounts).'</td>';
560 
561  // Details link
562  print '<td align="center"><a href="#" data-blockid="'.$block->id.'" rel="show-info">'.img_info($langs->trans('ShowDetails')).'</a></td>';
563 
564  // Fingerprint
565  print '<td class="nowrap">';
566  $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("Saved").':<br>'.$block->signature;
567  $texttoshow .= '<br><br>'.$langs->trans("Fingerprint").' - Recalculated sha256(previoushash * data):<br>'.$checkdetail[$block->id]['calculatedsignature'];
568  $texttoshow .= '<br><span class="opacitymedium">'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].'</span>';
569  //$texttoshow .= '<br>keyforsignature='.$checkdetail[$block->id]['keyforsignature'];
570  print $form->textwithpicto(dol_trunc($block->signature, '8'), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id);
571  print '</td>';
572 
573  // Status
574  print '<td class="center">';
575  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
576  if ($checkresult[$block->id]) {
577  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidityButChainIsKo').'">OK</span>';
578  } else {
579  print '<span class="badge badge-status8 badge-status" title="'.$langs->trans('KoCheckFingerprintValidity').'">KO</span>';
580  }
581  } else {
582  print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidity').'">OK</span>';
583  }
584  print '</td>';
585 
586  // Note
587  print '<td class="center">';
588  if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
589  if ($checkresult[$block->id]) {
590  print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo'));
591  }
592  }
593 
594  if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
595  print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black'));
596  }
597  print '</td>';
598 
599  print '<td></td>';
600 
601  print '</tr>';
602  }
603  }
604 
605  if ($nbshown == 0) {
606  print '<tr><td colspan="12"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
607  }
608 }
609 
610 print '</table>';
611 
612 print '</div>';
613 
614 print '</form>';
615 
616 // Javascript to manage the showinfo popup
617 print '<script type="text/javascript">
618 
619 jQuery(document).ready(function () {
620  jQuery("#dialogforpopup").dialog(
621  { closeOnEscape: true, classes: { "ui-dialog": "highlight" },
622  maxHeight: window.innerHeight-60, height: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).',
623  modal: true,
624  autoOpen: false }).css("z-index: 5000");
625 
626  $("a[rel=show-info]").click(function() {
627 
628  console.log("We click on tooltip, we open popup and get content using an ajax call");
629 
630  var fk_block = $(this).attr("data-blockid");
631 
632  $.ajax({
633  method: "GET",
634  data: { token: \''.currentToken().'\' },
635  url: "'.DOL_URL_ROOT.'/blockedlog/ajax/block-info.php?id="+fk_block,
636  dataType: "html"
637  }).done(function(data) {
638  jQuery("#dialogforpopup").html(data);
639  });
640 
641  jQuery("#dialogforpopup").dialog("open");
642  });
643 })
644 </script>'."\n";
645 
646 
647 if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) {
648  ?>
649  <script type="text/javascript">
650 
651  $.ajax({
652  method: "GET",
653  data: { token: '<?php echo currentToken() ?>' },
654  url: '<?php echo DOL_URL_ROOT.'/blockedlog/ajax/check_signature.php' ?>',
655  dataType: 'html'
656  }).done(function(data) {
657  if(data == 'hashisok') {
658  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureOK'), 'on') ?>');
659  }
660  else{
661  $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityDidntReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureKO'), 'off') ?>');
662  }
663 
664  });
665 
666  </script>
667  <?php
668 }
669 
670 if (GETPOST('withtab', 'alpha')) {
671  print dol_get_fiche_end();
672 }
673 
674 print '<br><br>';
675 
676 // End of page
677 llxFooter();
678 $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:576
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:595
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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.