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', '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 = '';
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">';
499print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth150', 1);
500print '</td>';
501
502// Ref
503print '<td class="liste_titre"><input type="text" class="maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
504
505// Link to ref
506print '<td class="liste_titre"></td>';
507
508// Amount
509print '<td class="liste_titre right"><input type="text" class="maxwidth50" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
510
511// Full data
512print '<td class="liste_titre"></td>';
513
514// Fingerprint
515print '<td class="liste_titre"></td>';
516
517// Status
518print '<td class="liste_titre center minwidth75imp parentonrightofpage">';
519$array = array("1" => "OnlyNonValid");
520print $form->selectarray('search_showonlyerrors', $array, $search_showonlyerrors, 1, 0, 0, '', 1, 0, 0, 'ASC', 'search_status width100 onrightofpage', 1);
521print '</td>';
522
523// Status note
524print '<td class="liste_titre"></td>';
525
526// Action column
527if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
528 print '<td class="liste_titre center">';
529 $searchpicto = $form->showFilterButtons();
530 print $searchpicto;
531 print '</td>';
532}
533
534print '</tr>';
535
536print '<tr class="liste_titre">';
537// Action column
538if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
539 print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
540}
541print getTitleFieldOfList($langs->trans('#'), 0, $_SERVER["PHP_SELF"], 'rowid', '', $param, '', $sortfield, $sortorder, 'minwidth50 ')."\n";
542print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"], 'date_creation', '', $param, '', $sortfield, $sortorder, '')."\n";
543print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"], 'user_fullname', '', $param, '', $sortfield, $sortorder, '')."\n";
544print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
545print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"], 'ref_object', '', $param, '', $sortfield, $sortorder, '')."\n";
546print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $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').'<br>'.$langs->trans('DataOfArchivedEventHelp2'), 1)."\n";
549print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n";
550print getTitleFieldOfList($langs->trans('Status'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
551print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
552// Action column
553if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
554 print getTitleFieldOfList('<span id="blockchainstatus"></span>', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n";
555}
556print '</tr>';
557
558$checkresult = array();
559$checkdetail = array();
560$loweridinerror = 0;
561
562if (getDolGlobalString('BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR')) {
563 // This is version that is faster but require more memory and report errors that are outside the filter range
564
565 // 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
566 // to find the $loweridinerror.
567} else {
568 // This is version that optimize the memory (but will not report errors that are outside the filter range)
569 if (is_array($blocks)) {
570 foreach ($blocks as &$block) {
571 $tmpcheckresult = $block->checkSignature('', 1); // Note: this make a sql request at each call, we can't avoid this as the sorting order is various
572
573 $checksignature = $tmpcheckresult['checkresult'];
574
575 $checkresult[$block->id] = $checksignature; // false if error
576 $checkdetail[$block->id] = $tmpcheckresult;
577
578 if (!$checksignature) {
579 if (empty($loweridinerror)) {
580 $loweridinerror = $block->id;
581 } else {
582 $loweridinerror = min($loweridinerror, $block->id);
583 }
584 }
585 }
586 }
587}
588
589if (is_array($blocks)) {
590 $nbshown = 0;
591 $object_link = '';
592 $object_link_title = '';
593
594 foreach ($blocks as &$block) {
595 //if (empty($search_showonlyerrors) || ! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror))
596 if (empty($search_showonlyerrors) || !$checkresult[$block->id]) {
597 $nbshown++;
598
599 if ($nbshown < $MAXFORSHOWNLINKS) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output
600 $object_link = $block->getObjectLink();
601 $object_link_title = '';
602 } else {
603 $object_link = $block->element.'/'.$block->fk_object;
604 $object_link_title = $langs->trans('LinkHasBeenDisabledForPerformancePurpose');
605 }
606
607 print '<tr class="oddeven">';
608
609 // Action column
610 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
611 print '<td class="liste_titre">';
612 print '</td>';
613 }
614
615 // ID
616 print '<td>'.dol_escape_htmltag((string) $block->id).'</td>';
617
618 // Date
619 print '<td class="nowraponall">'.dol_print_date($block->date_creation, 'dayhour').'</td>';
620
621 // User
622 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($block->user_fullname).'">';
623 //print $block->getUser()
624 print dol_escape_htmltag($block->user_fullname);
625 print '</td>';
626
627 // Action
628 $labelofaction = $langs->transnoentitiesnoconv('log'.$block->action);
629 print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($labelofaction).'">'.dolPrintHTML($labelofaction).'</td>';
630
631 // Ref
632 print '<td class="nowraponall">';
633 print dol_escape_htmltag($block->ref_object);
634 print '</td>';
635
636 // Link to source object
637 print '<td class="tdoverflowmax150"'.(preg_match('/<a/', $object_link) ? '' : 'title="'.dol_escape_htmltag(dol_string_nohtmltag($object_link.($object_link_title ? ' - '.$object_link_title : ''))).'"').'>';
638 print '<!-- object_link -->'; // $object_link can be a '<a href' link or a text
639 print $object_link;
640 print '</td>';
641
642 // Amount
643 print '<td class="right nowraponall">'.price($block->amounts).'</td>';
644
645 // Details link
646 print '<td class="center"><a href="#" data-blockid="'.$block->id.'" rel="show-info">'.img_info($langs->trans('ShowDetails')).'</a></td>';
647
648 // Fingerprint
649 print '<td class="nowraponall">';
650 // 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.
651 $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("SavedOnLine").' =<br>'.$block->signature;
652 $texttoshow .= '<br><br>'.$langs->trans("Fingerprint").' - Recalculated sha256('.$langs->trans("PreviousHash").' on previous line + data) =<br>'.$checkdetail[$block->id]['calculatedsignature'];
653 $texttoshow .= '<br><span class="opacitymedium">'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].'</span>';
654 //$texttoshow .= '<br>keyforsignature='.$checkdetail[$block->id]['keyforsignature'];
655 print $form->textwithpicto(dol_trunc($block->signature, 8), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id);
656 print '</td>';
657
658 // Status
659 print '<td class="center">';
660 if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
661 if ($checkresult[$block->id]) {
662 print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidityButChainIsKo').'">OK</span>';
663 } else {
664 print '<span class="badge badge-status8 badge-status" title="'.$langs->trans('KoCheckFingerprintValidity').'">KO</span>';
665 }
666 } else {
667 print '<span class="badge badge-status4 badge-status" title="'.$langs->trans('OkCheckFingerprintValidity').'">OK</span>';
668 }
669 print '</td>';
670
671 // Note
672 print '<td class="center">';
673 if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error
674 if ($checkresult[$block->id]) {
675 print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo'));
676 }
677 }
678
679 if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY') && getDolGlobalString('BLOCKEDLOG_AUTHORITY_URL')) {
680 print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black'));
681 }
682 print '</td>';
683
684 // Action column
685 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
686 print '<td class="liste_titre">';
687 print '</td>';
688 }
689
690 print '</tr>';
691 }
692 }
693
694 if ($nbshown == 0) {
695 print '<tr><td colspan="12"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
696 }
697}
698
699print '</table>';
700
701print '</div>';
702
703print '</form>';
704
705// Javascript to manage the showinfo popup
706print '<script type="text/javascript">
707
708jQuery(document).ready(function () {
709 jQuery("#dialogforpopup").dialog(
710 { closeOnEscape: true, classes: { "ui-dialog": "highlight" },
711 maxHeight: window.innerHeight-60, height: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).',
712 modal: true,
713 autoOpen: false }).css("z-index: 5000");
714
715 $("a[rel=show-info]").click(function() {
716
717 console.log("We click on tooltip, we open popup and get content using an ajax call");
718
719 var fk_block = $(this).attr("data-blockid");
720
721 $.ajax({
722 method: "GET",
723 data: { token: \''.currentToken().'\' },
724 url: "'.DOL_URL_ROOT.'/blockedlog/ajax/block-info.php?id="+fk_block,
725 dataType: "html"
726 }).done(function(data) {
727 jQuery("#dialogforpopup").html(data);
728 });
729
730 jQuery("#dialogforpopup").dialog("open");
731 });
732})
733</script>'."\n";
734
735
736if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY') && getDolGlobalString('BLOCKEDLOG_AUTHORITY_URL')) {
737 ?>
738 <script type="text/javascript">
739
740 $.ajax({
741 method: "GET",
742 data: { token: '<?php echo currentToken() ?>' },
743 url: '<?php echo DOL_URL_ROOT.'/blockedlog/ajax/check_signature.php' ?>',
744 dataType: 'html'
745 }).done(function(data) {
746 if(data == 'hashisok') {
747 $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureOK'), 'on') ?>');
748 }
749 else{
750 $('#blockchainstatus').html('<?php echo $langs->trans('AuthorityDidntReconizeFingerprintConformity').' '.img_picto($langs->trans('SignatureKO'), 'off') ?>');
751 }
752
753 });
754
755 </script>
756 <?php
757}
758
759if (GETPOST('withtab', 'alpha')) {
760 print dol_get_fiche_end();
761}
762
763print '<br><br>';
764
765// End of page
766llxFooter();
767$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.