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