From f826696aa1739a20075e7f7a5d5cb04056b34c2a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 5 Jan 2018 13:40:56 +0100 Subject: [PATCH] Add the status of record into blockedlog export --- htdocs/blockedlog/admin/blockedlog.php | 3 +- htdocs/blockedlog/admin/blockedlog_list.php | 81 ++++++++++++++++---- htdocs/blockedlog/class/blockedlog.class.php | 30 ++++---- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php index 2da83de5da2..e4b38a9568f 100644 --- a/htdocs/blockedlog/admin/blockedlog.php +++ b/htdocs/blockedlog/admin/blockedlog.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017-2018 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 54b8a05a19d..8c9e9bbd287 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017-2018 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -103,9 +104,9 @@ else if($action === 'downloadcsv') { $sql = "SELECT rowid,date_creation,tms,user_fullname,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user,object_data"; $sql.= " FROM ".MAIN_DB_PREFIX."blockedlog"; $sql.= " WHERE entity = ".$conf->entity; - $sql.= " ORDER BY rowid ASC"; - $res = $db->query($sql); + $sql.= " ORDER BY rowid ASC"; // Required so later we can use the parameter $previoushash of checkSignature() + $res = $db->query($sql); if($res) { $signature = $block_static->getSignature(); @@ -124,10 +125,43 @@ else if($action === 'downloadcsv') { .';'.$langs->transnoentities('Date') .';'.$langs->transnoentities('Ref') .';'.$langs->transnoentities('Fingerprint') + .';'.$langs->transnoentities('Status') .';'.$langs->transnoentities('FullData') ."\n"; - while($obj = $db->fetch_object($res)) { + $previoushash = ''; + $loweridinerror = 0; + + while ($obj = $db->fetch_object($res)) + { + // We set here all data used into signature calculation (see checkSignature method) and more + // IMPORTANT: We must have here, the same rule for transformation of data than into the fetch method (db->jdate for date, ...) + $block_static->id = $obj->rowid; + $block_static->date_creation = $db->jdate($obj->date_creation); + $block_static->date_modification = $db->jdate($obj->tms); + $block_static->action = $obj->action; + $block_static->fk_object = $obj->fk_object; + $block_static->element = $obj->element; + $block_static->amounts = (double) $obj->amounts; + $block_static->ref_object = $obj->ref_object; + $block_static->date_object = $db->jdate($obj->date_object); + $block_static->user_fullname = $obj->user_fullname; + $block_static->fk_user = $obj->fk_user; + $block_static->signature = $obj->signature; + $block_static->object_data = unserialize($obj->object_data); + + $checksignature = $block_static->checkSignature($previoushash); // If $previoushash is not defined, checkSignature will search it + + if ($checksignature) + { + if ($loweridinerror > 0) $statusofrecord = 'ValidButFoundAPreviousKO'; + else $statusofrecord = 'Valid'; + } + else + { + $statusofrecord = 'KO'; + $loweridinerror = $obj->rowid; + } print $obj->rowid .';'.$obj->date_creation @@ -139,16 +173,20 @@ else if($action === 'downloadcsv') { .';'.$obj->date_object .';"'.$obj->ref_object.'"' .';'.$obj->signature + .';'.$statusofrecord .';"'.str_replace('"','""',$obj->object_data).'"' ."\n"; + + // Set new previous hash for next fetch + $previoushash = $obj->signature; } exit; } - else{ + else + { setEventMessage($db->lasterror, 'errors'); } - } @@ -286,17 +324,28 @@ print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder,'')."\n"; print ''; -$loweridinerror=0; -$checkresult=array(); -foreach($blocks as &$block) { - $checksignature = $block->checkSignature(); - $checkresult[$block->id]=$checksignature; // false if error - if (! $checksignature) - { - if (empty($loweridinerror)) $loweridinerror=$block->id; - else $loweridinerror = min($loweridinerror, $block->id); - } +if (! empty($conf->global->BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR)) +{ + // This is version that is faster memory but require more memory and report errors that are outside the filter range + // 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 + // to find the $loweridinerror. + +} +else +{ + // This is version that optimize memory (but will not report error that are outside the filter range) + $loweridinerror=0; + $checkresult=array(); + foreach($blocks as &$block) { + $checksignature = $block->checkSignature(); // Note: this make a sql request at each call, we can't avoid this as the sorting order is various + $checkresult[$block->id]=$checksignature; // false if error + if (! $checksignature) + { + if (empty($loweridinerror)) $loweridinerror=$block->id; + else $loweridinerror = min($loweridinerror, $block->id); + } + } } foreach($blocks as &$block) { diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index ad2e6bb110a..ed3749acdda 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017 ATM Consulting * Copyright (C) 2017 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -82,6 +82,9 @@ class BlockedLog */ public $fk_user = 0; + public $date_creation; + public $date_modification; + public $date_object = 0; public $ref_object = ''; @@ -607,7 +610,7 @@ class BlockedLog $this->db->begin(); - $previoushash = $this->getPreviousHash(1); // This get last record and lock database until insert is done + $previoushash = $this->getPreviousHash(1, 0); // This get last record and lock database until insert is done $keyforsignature = $this->buildKeyForSignature(); @@ -678,19 +681,20 @@ class BlockedLog } /** - * Check if current signature still correct compare to the chain + * Check if current signature still correct compared to the value in chain * - * @return boolean True if OK, False if KO + * @param string $previoushash If previous signature hash is known, we can provide it to avoid to make a search of it in database. + * @return boolean True if OK, False if KO */ - public function checkSignature() + public function checkSignature($previoushash='') { - - //$oldblockedlog = new BlockedLog($this->db); - //$previousrecord = $oldblockedlog->fetch($this->id - 1); - $previoushash = $this->getPreviousHash(0, $this->id); - + if (empty($previoushash)) + { + $previoushash = $this->getPreviousHash(0, $this->id); + } // Recalculate hash $keyforsignature = $this->buildKeyForSignature(); + $signature_line = dol_hash($keyforsignature, '5'); // Not really usefull $signature = dol_hash($previoushash . $keyforsignature, '5'); //var_dump($previoushash); var_dump($keyforsignature); var_dump($signature_line); var_dump($signature); @@ -720,10 +724,10 @@ class BlockedLog * Get previous signature/hash in chain * * @param int $withlock 1=With a lock - * @param int $beforeid Before id - * @return string Hash of last record + * @param int $beforeid ID of a record + * @return string Hash of previous record (if beforeid is defined) or hash of last record (if beforeid is 0) */ - private function getPreviousHash($withlock=0, $beforeid=0) + public function getPreviousHash($withlock=0, $beforeid=0) { global $conf;