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