dolibarr 21.0.0-beta
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-2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
29// Load Dolibarr environment
30require '../../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
33require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
37
48// Load translation files required by the page
49$langs->loadLangs(array('admin', 'bills', 'blockedlog', 'other'));
50
51// Access Control
52if ((!$user->admin && !$user->hasRight('blockedlog', 'read')) || empty($conf->blockedlog->enabled)) {
54}
55
56// Get Parameters
57$action = GETPOST('action', 'aZ09');
58$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'blockedloglist'; // To manage different context of search
59$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
60$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
61
62$search_showonlyerrors = GETPOSTINT('search_showonlyerrors');
63if ($search_showonlyerrors < 0) {
64 $search_showonlyerrors = 0;
65}
66
67$search_startyear = GETPOSTINT('search_startyear');
68$search_startmonth = GETPOSTINT('search_startmonth');
69$search_startday = GETPOSTINT('search_startday');
70$search_endyear = GETPOSTINT('search_endyear');
71$search_endmonth = GETPOSTINT('search_endmonth');
72$search_endday = GETPOSTINT('search_endday');
73$search_id = GETPOST('search_id', 'alpha');
74$search_fk_user = GETPOST('search_fk_user', 'intcomma');
75$search_start = -1;
76if (GETPOST('search_startyear') != '') {
77 $search_start = dol_mktime(0, 0, 0, $search_startmonth, $search_startday, $search_startyear);
78}
79$search_end = -1;
80if (GETPOST('search_endyear') != '') {
81 $search_end = dol_mktime(23, 59, 59, $search_endmonth, $search_endday, $search_endyear);
82}
83$search_code = GETPOST('search_code', 'array:alpha');
84$search_ref = GETPOST('search_ref', 'alpha');
85$search_amount = GETPOST('search_amount', 'alpha');
86
87if (($search_start == -1 || empty($search_start)) && !GETPOSTISSET('search_startmonth') && !GETPOSTISSET('begin')) {
88 $search_start = dol_time_plus_duree(dol_now(), -1, 'w');
89 $tmparray = dol_getdate($search_start);
90 $search_startday = $tmparray['mday'];
91 $search_startmonth = $tmparray['mon'];
92 $search_startyear = $tmparray['year'];
93}
94
95// Load variable for pagination
96$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
97$sortfield = GETPOST('sortfield', 'aZ09comma');
98$sortorder = GETPOST('sortorder', 'aZ09comma');
99$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
100if (empty($page) || $page == -1) {
101 $page = 0;
102} // If $page is not defined, or '' or -1
103$offset = $limit * $page;
104$pageprev = $page - 1;
105$pagenext = $page + 1;
106
107if (empty($sortfield)) {
108 $sortfield = 'rowid';
109}
110if (empty($sortorder)) {
111 $sortorder = 'DESC';
112}
113
114$block_static = new BlockedLog($db);
115$block_static->loadTrackedEvents();
116
117$result = restrictedArea($user, 'blockedlog', 0, '');
118
119// Execution Time
120$max_execution_time_for_importexport = getDolGlobalInt('EXPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
121$max_time = @ini_get("max_execution_time");
122if ($max_time && $max_time < $max_execution_time_for_importexport) {
123 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.");
124 @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
125}
126
127$MAXLINES = getDolGlobalInt('BLOCKEDLOG_MAX_LINES', 10000);
128$MAXFORSHOWNLINKS = getDolGlobalInt('BLOCKEDLOG_MAX_FOR_SHOWN_LINKS', 100);
129
130
131/*
132 * Actions
133 */
134
135// Purge search criteria
136if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
137 $search_id = '';
138 $search_fk_user = '';
139 $search_start = -1;
140 $search_end = -1;
141 $search_code = array();
142 $search_ref = '';
143 $search_amount = '';
144 $search_showonlyerrors = 0;
145 $search_startyear = '';
146 $search_startmonth = '';
147 $search_startday = '';
148 $search_endyear = '';
149 $search_endmonth = '';
150 $search_endday = '';
151 $toselect = array();
152 $search_array_options = array();
153}
154
155if ($action === 'downloadblockchain') {
156 $auth = new BlockedLogAuthority($db);
157
158 $bc = $auth->getLocalBlockChain();
159
160 header('Content-Type: application/octet-stream');
161 header("Content-Transfer-Encoding: Binary");
162 header("Content-disposition: attachment; filename=\"".$auth->signature.".certif\"");
163
164 echo $bc;
165
166 exit;
167} elseif (GETPOST('downloadcsv', 'alpha')) {
168 $error = 0;
169
170 $previoushash = '';
171 $firstid = '';
172
173 if (! (GETPOSTINT('yeartoexport') > 0)) {
174 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Year")), null, "errors");
175 $error++;
176 } else {
177 // Get the ID of the first line qualified
178 $sql = "SELECT rowid,date_creation,tms,user_fullname,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user,object_data";
179 $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
180 $sql .= " WHERE entity = ".$conf->entity;
181 if (GETPOSTINT('monthtoexport') > 0 || GETPOSTINT('yeartoexport') > 0) {
182 $dates = dol_get_first_day(GETPOSTINT('yeartoexport'), GETPOSTINT('monthtoexport') ? GETPOSTINT('monthtoexport') : 1);
183 $datee = dol_get_last_day(GETPOSTINT('yeartoexport'), GETPOSTINT('monthtoexport') ? GETPOSTINT('monthtoexport') : 12);
184 $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
185 }
186 $sql .= " ORDER BY rowid ASC"; // Required so we get the first one
187 $sql .= $db->plimit(1);
188
189 $res = $db->query($sql);
190 if ($res) {
191 // Make the first fetch to get first line
192 $obj = $db->fetch_object($res);
193 if ($obj) {
194 $previoushash = $block_static->getPreviousHash(0, $obj->rowid);
195 $firstid = $obj->rowid;
196 } else { // If not data found for filter, we do not need previoushash neither firstid
197 $previoushash = 'nodata';
198 $firstid = '';
199 }
200 } else {
201 $error++;
202 setEventMessages($db->lasterror, null, 'errors');
203 }
204 }
205
206 if (! $error) {
207 // We record the export as a new line into the unalterable logs
208 require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
209 $b = new BlockedLog($db);
210
211 $object = new stdClass();
212 $object->id = 0;
213 $object->element = 'module';
214 $object->ref = 'systemevent';
215 $object->entity = $conf->entity;
216 $object->date = dol_now();
217
218 $object->label = 'Export unalterable logs - Period: year='.GETPOSTINT('yeartoexport').(GETPOSTINT('monthtoexport') ? ' month='.GETPOSTINT('monthtoexport') : '');
219
220 $action = 'BLOCKEDLOG_EXPORT';
221 $result = $b->setObjectData($object, $action, 0, $user);
222 //var_dump($b); exit;
223
224 if ($result < 0) {
225 setEventMessages('Failed to insert the export int the unalterable log', null, 'errors');
226 $error++;
227 }
228
229 $res = $b->create($user);
230
231 if ($res < 0) {
232 setEventMessages('Failed to insert the export int the unalterable log', null, 'errors');
233 $error++;
234 }
235 }
236
237 if (!$error) {
238 // Now restart request with all data = no limit(1) in sql request
239 $sql = "SELECT rowid, date_creation, tms, user_fullname, action, amounts, element, fk_object, date_object, ref_object, signature, fk_user, object_data, object_version";
240 $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
241 $sql .= " WHERE entity = ".((int) $conf->entity);
242 if (GETPOSTINT('monthtoexport') > 0 || GETPOSTINT('yeartoexport') > 0) {
243 $dates = dol_get_first_day(GETPOSTINT('yeartoexport'), GETPOSTINT('monthtoexport') ? GETPOSTINT('monthtoexport') : 1);
244 $datee = dol_get_last_day(GETPOSTINT('yeartoexport'), GETPOSTINT('monthtoexport') ? GETPOSTINT('monthtoexport') : 12);
245 $sql .= " AND date_creation BETWEEN '".$db->idate($dates)."' AND '".$db->idate($datee)."'";
246 }
247 $sql .= " ORDER BY rowid ASC"; // Required so later we can use the parameter $previoushash of checkSignature()
248
249 $res = $db->query($sql);
250 if ($res) {
251 header('Content-Type: application/octet-stream');
252 header("Content-Transfer-Encoding: Binary");
253 header("Content-disposition: attachment; filename=\"unalterable-log-archive-".$dolibarr_main_db_name."-".(GETPOSTINT('yeartoexport') > 0 ? GETPOSTINT('yeartoexport').(GETPOSTINT('monthtoexport') > 0 ? sprintf("%02d", GETPOSTINT('monthtoexport')) : '').'-' : '').$previoushash.".csv\"");
254
255 print $langs->transnoentities('Id')
256 .';'.$langs->transnoentities('Date')
257 .';'.$langs->transnoentities('User')
258 .';'.$langs->transnoentities('Action')
259 .';'.$langs->transnoentities('Element')
260 .';'.$langs->transnoentities('Amounts')
261 .';'.$langs->transnoentities('ObjectId')
262 .';'.$langs->transnoentities('Date')
263 .';'.$langs->transnoentities('Ref')
264 .';'.$langs->transnoentities('Fingerprint')
265 .';'.$langs->transnoentities('Status')
266 .';'.$langs->transnoentities('Note')
267 .';'.$langs->transnoentities('Version')
268 .';'.$langs->transnoentities('FullData')
269 ."\n";
270
271 $loweridinerror = 0;
272 $i = 0;
273
274 while ($obj = $db->fetch_object($res)) {
275 // We set here all data used into signature calculation (see checkSignature method) and more
276 // IMPORTANT: We must have here, the same rule for transformation of data than into the fetch method (db->jdate for date, ...)
277 $block_static->id = $obj->rowid;
278 $block_static->date_creation = $db->jdate($obj->date_creation);
279 $block_static->date_modification = $db->jdate($obj->tms);
280 $block_static->action = $obj->action;
281 $block_static->fk_object = $obj->fk_object;
282 $block_static->element = $obj->element;
283 $block_static->amounts = (float) $obj->amounts;
284 $block_static->ref_object = $obj->ref_object;
285 $block_static->date_object = $db->jdate($obj->date_object);
286 $block_static->user_fullname = $obj->user_fullname;
287 $block_static->fk_user = $obj->fk_user;
288 $block_static->signature = $obj->signature;
289 $block_static->object_data = $block_static->dolDecodeBlockedData($obj->object_data);
290 $block_static->object_version = $obj->object_version;
291
292 $checksignature = $block_static->checkSignature($previoushash); // If $previoushash is not defined, checkSignature will search it
293
294 if ($checksignature) {
295 $statusofrecord = 'Valid';
296 if ($loweridinerror > 0) {
297 $statusofrecordnote = 'ValidButFoundAPreviousKO';
298 } else {
299 $statusofrecordnote = '';
300 }
301 } else {
302 $statusofrecord = 'KO';
303 $statusofrecordnote = 'LineCorruptedOrNotMatchingPreviousOne';
304 $loweridinerror = $obj->rowid;
305 }
306
307 if ($i == 0) {
308 $statusofrecordnote = $langs->trans("PreviousFingerprint").': '.$previoushash.($statusofrecordnote ? ' - '.$statusofrecordnote : '');
309 }
310 print $obj->rowid;
311 print ';'.$obj->date_creation;
312 print ';"'.str_replace('"', '""', $obj->user_fullname).'"';
313 print ';'.$obj->action;
314 print ';'.$obj->element;
315 print ';'.$obj->amounts;
316 print ';'.$obj->fk_object;
317 print ';'.$obj->date_object;
318 print ';"'.str_replace('"', '""', $obj->ref_object).'"';
319 print ';'.$obj->signature;
320 print ';'.$statusofrecord;
321 print ';'.$statusofrecordnote;
322 print ';'.$obj->object_version;
323 print ';"'.str_replace('"', '""', $obj->object_data).'"';
324 print "\n";
325
326 // Set new previous hash for next fetch
327 $previoushash = $obj->signature;
328
329 $i++;
330 }
331
332 exit;
333 } else {
334 setEventMessages($db->lasterror, null, 'errors');
335 }
336 }
337}
338
339
340/*
341 * View
342 */
343
344$form = new Form($db);
345$formother = new FormOther($db);
346
347if (GETPOST('withtab', 'alpha')) {
348 $title = $langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog');
349} else {
350 $title = $langs->trans("BrowseBlockedLog");
351}
352$help_url = "EN:Module_Unalterable_Archives_-_Logs|FR:Module_Archives_-_Logs_Inaltérable";
353
354llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-blockedlog page-admin_blockedlog_list');
355
356$blocks = $block_static->getLog('all', $search_id, $MAXLINES, $sortfield, $sortorder, $search_fk_user, $search_start, $search_end, $search_ref, $search_amount, $search_code);
357if (!is_array($blocks)) {
358 if ($blocks == -2) {
359 setEventMessages($langs->trans("TooManyRecordToScanRestrictFilters", $MAXLINES), null, 'errors');
360 } else {
361 dol_print_error($block_static->db, $block_static->error, $block_static->errors);
362 exit;
363 }
364}
365
366$linkback = '';
367if (GETPOST('withtab', 'alpha')) {
368 $linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
369}
370
371print load_fiche_titre($title, $linkback);
372
373if (GETPOST('withtab', 'alpha')) {
375 print dol_get_fiche_head($head, 'fingerprints', '', -1);
376}
377
378print '<div class="opacitymedium hideonsmartphone justify">';
379
380print $langs->trans("FingerprintsDesc")."<br>";
381
382print '<br>';
383
384$s = $langs->trans("FilesIntegrityDesc", '{s}');
385$s = str_replace('{s}', DOL_URL_ROOT.'/admin/system/filecheck.php', $s);
386print $s;
387print "<br>\n";
388
389print "</div>\n";
390
391print '<br>';
392
393$param = '';
394if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
395 $param .= '&contextpage='.urlencode($contextpage);
396}
397if ($limit > 0 && $limit != $conf->liste_limit) {
398 $param .= '&limit='.((int) $limit);
399}
400if ($search_id != '') {
401 $param .= '&search_id='.urlencode($search_id);
402}
403if ($search_fk_user > 0) {
404 $param .= '&search_fk_user='.urlencode($search_fk_user);
405}
406if ($search_startyear > 0) {
407 $param .= '&search_startyear='.((int) $search_startyear);
408}
409if ($search_startmonth > 0) {
410 $param .= '&search_startmonth='.((int) $search_startmonth);
411}
412if ($search_startday > 0) {
413 $param .= '&search_startday='.((int) $search_startday);
414}
415if ($search_endyear > 0) {
416 $param .= '&search_endyear='.((int) $search_endyear);
417}
418if ($search_endmonth > 0) {
419 $param .= '&search_endmonth='.((int) $search_endmonth);
420}
421if ($search_endday > 0) {
422 $param .= '&search_endday='.((int) $search_endday);
423}
424if ($search_showonlyerrors > 0) {
425 $param .= '&search_showonlyerrors='.((int) $search_showonlyerrors);
426}
427if ($optioncss != '') {
428 $param .= '&optioncss='.urlencode($optioncss);
429}
430if (GETPOST('withtab', 'alpha')) {
431 $param .= '&withtab='.urlencode(GETPOST('withtab', 'alpha'));
432}
433
434// Add $param from extra fields
435//include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
436
437print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'?output=file">';
438print '<input type="hidden" name="token" value="'.newToken().'">';
439
440print '<div class="right">';
441print $langs->trans("RestrictYearToExport").': ';
442// Month
443print $formother->select_month(GETPOSTINT('monthtoexport'), 'monthtoexport', 1, 0, 'minwidth50 maxwidth75imp valignmiddle', true);
444print '<input type="text" name="yeartoexport" class="valignmiddle maxwidth50imp" value="'.GETPOST('yeartoexport').'" placeholder="'.$langs->trans("Year").'">';
445print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
446print '<input type="submit" name="downloadcsv" class="button" value="'.$langs->trans('DownloadLogCSV').'">';
447if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY')) {
448 print ' | <a href="?action=downloadblockchain'.(GETPOST('withtab', 'alpha') ? '&withtab='.GETPOST('withtab', 'alpha') : '').'">'.$langs->trans('DownloadBlockChain').'</a>';
449}
450print ' </div><br>';
451
452print '</form>';
453
454print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
455
456if ($optioncss != '') {
457 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
458}
459print '<input type="hidden" name="token" value="'.newToken().'">';
460print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
461print '<input type="hidden" name="action" value="list">';
462print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
463print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
464print '<input type="hidden" name="page" value="'.$page.'">';
465print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
466print '<input type="hidden" name="withtab" value="'.GETPOST('withtab', 'alpha').'">';
467
468print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
469print '<table class="noborder centpercent liste">';
470
471// Line of filters
472print '<tr class="liste_titre_filter">';
473
474// Action column
475if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
476 print '<td class="liste_titre center">';
477 $searchpicto = $form->showFilterButtons();
478 print $searchpicto;
479 print '</td>';
480}
481
482print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_id" value="'.dol_escape_htmltag($search_id).'"></td>';
483
484print '<td class="liste_titre">';
485//print $langs->trans("from").': ';
486print $form->selectDate($search_start, 'search_start');
487//print '<br>';
488//print $langs->trans("to").': ';
489print $form->selectDate($search_end, 'search_end');
490print '</td>';
491
492// User
493print '<td class="liste_titre">';
494print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth150');
495print '</td>';
496
497// Actions code
498print '<td class="liste_titre">';
499//print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth150', 1);
500print $form->multiselectarray('search_code', $block_static->trackedevents, $search_code, 0, 0, 'maxwidth150', 1);
501print '</td>';
502
503// Ref
504print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
505
506// Amount
507print '<td class="liste_titre right"><input type="text" class="maxwidth50" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
508
509// Full data
510print '<td class="liste_titre"></td>';
511
512// Fingerprint
513print '<td class="liste_titre"></td>';
514
515// Status
516print '<td class="liste_titre center minwidth75imp parentonrightofpage">';
517$array = array("1" => "OnlyNonValid");
518print $form->selectarray('search_showonlyerrors', $array, $search_showonlyerrors, 1, 0, 0, '', 1, 0, 0, 'ASC', 'search_status width100 onrightofpage', 1);
519print '</td>';
520
521// Status note
522//print '<td class="liste_titre"></td>';
523
524// Link to original ref into business software
525print '<td class="liste_titre"></td>';
526
527// Action column
528if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
529 print '<td class="liste_titre center">';
530 $searchpicto = $form->showFilterButtons();
531 print $searchpicto;
532 print '</td>';
533}
534
535print '</tr>';
536
537print '<tr class="liste_titre">';
538// Action column
539if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
540 print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
541}
542print getTitleFieldOfList($langs->trans('#'), 0, $_SERVER["PHP_SELF"], 'rowid', '', $param, '', $sortfield, $sortorder, 'minwidth50 ')."\n";
543print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"], 'date_creation', '', $param, '', $sortfield, $sortorder, '')."\n";
544print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"], 'user_fullname', '', $param, '', $sortfield, $sortorder, '')."\n";
545print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
546print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"], 'ref_object', '', $param, '', $sortfield, $sortorder, '')."\n";
547print getTitleFieldOfList($langs->trans('Amount'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ')."\n";
548print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ', 0, $langs->trans('DataOfArchivedEventHelp'), 1)."\n";
549print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
550print getTitleFieldOfList($form->textwithpicto($langs->trans('Status'), $langs->trans('DataOfArchivedEventHelp2')), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
551//print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
552print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
553// Action column
554if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
555 print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
556}
557print '</tr>';
558
559$checkresult = array();
560$checkdetail = array();
561$loweridinerror = 0;
562
563if (getDolGlobalString('BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR')) {
564 // This is version that is faster but require more memory and report errors that are outside the filter range
565
566 // 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
567 // to find the $loweridinerror.
568} else {
569 // This is version that optimize the memory (but will not report errors that are outside the filter range)
570 if (is_array($blocks)) {
571 foreach ($blocks as &$block) {
572 $tmpcheckresult = $block->checkSignature('', 1); // Note: this make a sql request at each call, we can't avoid this as the sorting order is various
573
574 $checksignature = $tmpcheckresult['checkresult'];
575
576 $checkresult[$block->id] = $checksignature; // false if error
577 $checkdetail[$block->id] = $tmpcheckresult;
578
579 if (!$checksignature) {
580 if (empty($loweridinerror)) {
581 $loweridinerror = $block->id;
582 } else {
583 $loweridinerror = min($loweridinerror, $block->id);
584 }
585 }
586 }
587 }
588}
589
590if (is_array($blocks)) {
591 $nbshown = 0;
592 $object_link = '';
593 $object_link_title = '';
594
595 foreach ($blocks as &$block) {
596 //if (empty($search_showonlyerrors) || ! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror))
597 if (empty($search_showonlyerrors) || !$checkresult[$block->id]) {
598 $nbshown++;
599
600 if ($nbshown < $MAXFORSHOWNLINKS) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output
601 $object_link = $block->getObjectLink();
602 $object_link_title = '';
603 } else {
604 $object_link = $block->element.'/'.$block->fk_object;
605 $object_link_title = $langs->trans('LinkHasBeenDisabledForPerformancePurpose');
606 }
607
608 print '<tr class="oddeven">';
609
610 // Action column
611 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
612 print '<td class="liste_titre">';
613 print '</td>';
614 }
615
616 // ID
617 print '<td>'.dol_escape_htmltag((string) $block->id).'</td>';
618
619 // Date
620 print '<td class="nowraponall">'.dol_print_date($block->date_creation, 'dayhour').'</td>';
621
622 // User
623 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($block->user_fullname).'">';
624 //print $block->getUser()
625 print dol_escape_htmltag($block->user_fullname);
626 print '</td>';
627
628 // Action
629 $labelofaction = $langs->transnoentitiesnoconv('log'.$block->action);
630 print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($labelofaction).'">'.dolPrintHTML($labelofaction).'</td>';
631
632 // Ref
633 print '<td class="nowraponall">';
634 print dol_escape_htmltag($block->ref_object);
635 print '</td>';
636
637 // Amount
638 print '<td class="right nowraponall">'.price($block->amounts).'</td>';
639
640 // Details link
641 print '<td class="center"><a href="#" data-blockid="'.$block->id.'" rel="show-info">'.img_info($langs->trans('ShowDetails')).'</a></td>';
642
643 // Fingerprint
644 print '<td class="nowraponall">';
645 // Note: the previous line id is not necessarily id-1, so in texttoshow we say "on previous line" without giving id to avoid a search/fetch to get previous id.
646 $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("SavedOnLine").' =<br>'.$block->signature;
647 $texttoshow .= '<br><br>'.$langs->trans("Fingerprint").' - Recalculated sha256('.$langs->trans("PreviousHash").' on previous line + data) =<br>'.$checkdetail[$block->id]['calculatedsignature'];
648 $texttoshow .= '<br><span class="opacitymedium">'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].'</span>';
649 //$texttoshow .= '<br>keyforsignature='.$checkdetail[$block->id]['keyforsignature'];
650 print $form->textwithpicto(dol_trunc($block->signature, 8), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id);
651 print '</td>';
652
653 // Status
654 print '<td class="center">';
655 if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
656 if ($checkresult[$block->id]) {
657 print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidityButChainIsKo').'">OK</span>';
658 } else {
659 print '<span class="badge badge-status8 badge-status" title="'.$langs->trans('KoCheckFingerprintValidity').'">KO</span>';
660 }
661 } else {
662 print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidity').'">OK</span>';
663 }
664 //print '</td>';
665
666 // Note
667 //print '<td class="center">';
668 if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
669 if ($checkresult[$block->id]) {
670 print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo'));
671 } else {
672 //print $form->textwithpicto('', $langs->trans('KoCheckFingerprintValidity'));
673 }
674 } else {
675 //print $form->textwithpicto('', $langs->trans('DataOfArchivedEventHelp2'));
676 }
677
678 if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY') && getDolGlobalString('BLOCKEDLOG_AUTHORITY_URL')) {
679 print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black'));
680 }
681 print '</td>';
682
683 // Link to source object
684 print '<td class="tdoverflowmax150"'.(preg_match('/<a/', $object_link) ? '' : 'title="'.dol_escape_htmltag(dol_string_nohtmltag($object_link.($object_link_title ? ' - '.$object_link_title : ''))).'"').'>';
685 print '<!-- object_link -->'; // $object_link can be a '<a href' link or a text
686 print $object_link;
687 print '</td>';
688
689 // Action column
690 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
691 print '<td class="liste_titre">';
692 print '</td>';
693 }
694
695 print '</tr>';
696 }
697 }
698
699 if ($nbshown == 0) {
700 print '<tr><td colspan="12"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
701 }
702}
703
704print '</table>';
705
706print '</div>';
707
708print '</form>';
709
710// Javascript to manage the showinfo popup
711print '<script type="text/javascript">
712
713jQuery(document).ready(function () {
714 jQuery("#dialogforpopup").dialog(
715 { closeOnEscape: true, classes: { "ui-dialog": "highlight" },
716 maxHeight: window.innerHeight-60, height: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).',
717 modal: true,
718 autoOpen: false }).css("z-index: 5000");
719
720 $("a[rel=show-info]").click(function() {
721
722 console.log("We click on tooltip, we open popup and get content using an ajax call");
723
724 var fk_block = $(this).attr("data-blockid");
725
726 $.ajax({
727 method: "GET",
728 data: { token: \''.currentToken().'\' },
729 url: "'.DOL_URL_ROOT.'/blockedlog/ajax/block-info.php?id="+fk_block,
730 dataType: "html"
731 }).done(function(data) {
732 jQuery("#dialogforpopup").html(data);
733 });
734
735 jQuery("#dialogforpopup").dialog("open");
736 });
737})
738</script>'."\n";
739
740
741if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY') && getDolGlobalString('BLOCKEDLOG_AUTHORITY_URL')) {
742 ?>
743 <script type="text/javascript">
744
745 $.ajax({
746 method: "GET",
747 data: { token: '<?php echo currentToken() ?>' },
748 url: '<?php echo DOL_URL_ROOT.'/blockedlog/ajax/check_signature.php' ?>',
749 dataType: 'html'
750 }).done(function(data) {
751 if(data == 'hashisok') {
752 $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureOK'), 'on') ?>');
753 }
754 else{
755 $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityDidntReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureKO'), 'off') ?>');
756 }
757
758 });
759
760 </script>
761 <?php
762}
763
764if (GETPOST('withtab', 'alpha')) {
765 print dol_get_fiche_end();
766}
767
768print '<br><br>';
769
770// End of page
771llxFooter();
772$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
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.
Class permettant la generation de composants html autre Only common components are here.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:600
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:619
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
currentToken()
Return the value of token currently saved into session with name 'token'.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
getDolGlobalString($key, $default='')
Return a 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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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.