From 2c3d6fa66a5bf6ec4b7bdf113bf20e475e8fc51c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 10:53:08 +0100 Subject: [PATCH 1/7] Reduce limit for list --- htdocs/blockedlog/admin/blockedlog_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index b89e047492f7b..5cb5d47b1b35d 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -350,7 +350,7 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-blockedlog page-admin_blockedlog_list'); -$MAXLINES = 10000; +$MAXLINES = getDolGlobalInt('BLOCKEDLOG_MAX_LINES', 1000); $blocks = $block_static->getLog('all', $search_id, $MAXLINES, $sortfield, $sortorder, $search_fk_user, $search_start, $search_end, $search_ref, $search_amount, $search_code); if (!is_array($blocks)) { From bd170e0474929002a768894659ee24f43640f869 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 11:33:31 +0100 Subject: [PATCH 2/7] Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop --- htdocs/blockedlog/class/blockedlog.class.php | 50 ++++++++++++++----- htdocs/core/db/DoliDB.class.php | 3 +- htdocs/core/db/mysqli.class.php | 5 +- .../install/mysql/migration/20.0.0-21.0.0.sql | 3 ++ .../mysql/tables/llx_blockedlog.key.sql | 23 ++++++++- 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 46820f95ea37a..ef209ae6b8549 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1088,23 +1088,47 @@ public function getPreviousHash($withlock = 0, $beforeid = 0) $previoussignature = ''; - $sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog"; - $sql .= " WHERE entity = ".((int) $conf->entity); + // Fast search of previous record by searching with beforeid - 1. This is very fast and will work 99% of time. if ($beforeid) { - $sql .= " AND rowid < ".(int) $beforeid; + $sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog"; + $sql .= " WHERE entity = ".((int) $conf->entity); + $sql .= " AND rowid = ".((int) $beforeid - 1); + $sql .= ($withlock ? " FOR UPDATE " : ""); + + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $previoussignature = $obj->signature; + } + } else { + dol_print_error($this->db); + exit; + } } - $sql .= " ORDER BY rowid DESC LIMIT 1"; - $sql .= ($withlock ? " FOR UPDATE " : ""); - $resql = $this->db->query($sql); - if ($resql) { - $obj = $this->db->fetch_object($resql); - if ($obj) { - $previoussignature = $obj->signature; + if (empty($previoussignature)) { + $sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog"; + if ($beforeid) { + $sql.= $this->db->hintindex('entity_rowid', 1); + } + $sql .= " WHERE entity = ".((int) $conf->entity); + if ($beforeid) { + $sql .= " AND rowid < ".(int) $beforeid; + } + $sql .= " ORDER BY rowid DESC LIMIT 1"; + $sql .= ($withlock ? " FOR UPDATE " : ""); + + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $previoussignature = $obj->signature; + } + } else { + dol_print_error($this->db); + exit; } - } else { - dol_print_error($this->db); - exit; } if (empty($previoussignature)) { diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index a73b664965445..1a898e9c61800 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -122,9 +122,10 @@ public function stddevpop($nameoffield) * Return SQL string to force an index * * @param string $nameofindex Name of index + * @param int $mode 0=Use, 1=Force * @return string SQL string */ - public function hintindex($nameofindex) + public function hintindex($nameofindex, $mode = 1) { return ''; } diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 7a20d8027a6f7..6fd6a86061c77 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -200,11 +200,12 @@ public function __construct($type, $host, $user, $pass, $name = '', $port = 0) * Return SQL string to force an index * * @param string $nameofindex Name of index + * @param int $mode 0=Use, 1=Force * @return string SQL string */ - public function hintindex($nameofindex) + public function hintindex($nameofindex, $mode = 1) { - return " FORCE INDEX(".preg_replace('/[^a-z0-9_]/', '', $nameofindex).")"; + return " ".($mode == 1 ? 'FORCE' : 'USE')." INDEX(".preg_replace('/[^a-z0-9_]/', '', $nameofindex).")"; } diff --git a/htdocs/install/mysql/migration/20.0.0-21.0.0.sql b/htdocs/install/mysql/migration/20.0.0-21.0.0.sql index d4d36ba7da46e..5281bc760f1a1 100644 --- a/htdocs/install/mysql/migration/20.0.0-21.0.0.sql +++ b/htdocs/install/mysql/migration/20.0.0-21.0.0.sql @@ -51,6 +51,9 @@ ALTER TABLE llx_hrm_evaluation MODIFY COLUMN modelpdf varchar(255) DEFAULT NULL; -- V21 migration +ALTER TABLE llx_blockedlog DROP INDEX entity_action; +ALTER TABLE llx_blockedlog ADD INDEX entity_rowid (entity, rowid); + ALTER TABLE llx_ecm_files MODIFY COLUMN description varchar(255); ALTER TABLE llx_ecm_files MODIFY COLUMN cover varchar(32); ALTER TABLE llx_ecm_files ADD COLUMN content text; diff --git a/htdocs/install/mysql/tables/llx_blockedlog.key.sql b/htdocs/install/mysql/tables/llx_blockedlog.key.sql index 4312a056894a4..065be82aba1a9 100644 --- a/htdocs/install/mysql/tables/llx_blockedlog.key.sql +++ b/htdocs/install/mysql/tables/llx_blockedlog.key.sql @@ -1,6 +1,25 @@ +-- =================================================================== +-- Copyright (C) 2024 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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- =================================================================== + ALTER TABLE llx_blockedlog ADD INDEX signature (signature); ALTER TABLE llx_blockedlog ADD INDEX fk_object_element (fk_object,element); ALTER TABLE llx_blockedlog ADD INDEX entity (entity); -ALTER TABLE llx_blockedlog ADD INDEX fk_user (fk_user); -ALTER TABLE llx_blockedlog ADD INDEX entity_action (entity,action); +ALTER TABLE llx_blockedlog ADD INDEX fk_user (fk_user); ALTER TABLE llx_blockedlog ADD INDEX entity_action_certified (entity,action,certified); + +ALTER TABLE llx_blockedlog ADD INDEX entity_rowid (entity, rowid); -- for the "SELECT rowid, signature FROM llx_blockedlog FORCE INDEX entity_rowid WHERE entity = x AND rowid < z ORDER BY rowid DESC" From 487f910aa79da2e7b01b5caa29bd96e4ec6a12da Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 11:41:00 +0100 Subject: [PATCH 3/7] Fix bad value --- htdocs/blockedlog/admin/blockedlog_list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 5cb5d47b1b35d..eb831fb06b815 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -647,8 +647,9 @@ // Fingerprint print ''; + // 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. $texttoshow = $langs->trans("Fingerprint").' - '.$langs->trans("SavedOnLine").' =
'.$block->signature; - $texttoshow .= '

'.$langs->trans("Fingerprint").' - Recalculated sha256('.$langs->trans("PreviousHash").' on line '.($block->id - 1).' + data) =
'.$checkdetail[$block->id]['calculatedsignature']; + $texttoshow .= '

'.$langs->trans("Fingerprint").' - Recalculated sha256('.$langs->trans("PreviousHash").' on previous line + data) =
'.$checkdetail[$block->id]['calculatedsignature']; $texttoshow .= '
'.$langs->trans("PreviousHash").'='.$checkdetail[$block->id]['previoushash'].''; //$texttoshow .= '
keyforsignature='.$checkdetail[$block->id]['keyforsignature']; print $form->textwithpicto(dol_trunc($block->signature, 8), $texttoshow, 1, 'help', '', 0, 2, 'fingerprint'.$block->id); From 4c556babaf032597231e37de8c85bdb576e9b0f4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 11:51:14 +0100 Subject: [PATCH 4/7] Clean code --- htdocs/blockedlog/admin/blockedlog_list.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index eb831fb06b815..95da9f8f9eeab 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -117,13 +117,16 @@ $result = restrictedArea($user, 'blockedlog', 0, ''); // Execution Time -$max_execution_time_for_importexport = (!getDolGlobalString('EXPORT_MAX_EXECUTION_TIME') ? 300 : $conf->global->EXPORT_MAX_EXECUTION_TIME); // 5mn if not defined +$max_execution_time_for_importexport = getDolGlobalInt('EXPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined $max_time = @ini_get("max_execution_time"); if ($max_time && $max_time < $max_execution_time_for_importexport) { 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."); @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 } +$MAXLINES = getDolGlobalInt('BLOCKEDLOG_MAX_LINES', 10000); +$MAXFORSHOWNLINKS = getDolGlobalInt('BLOCKEDLOG_MAX_FOR_SHOWN_LINKS', 100); + /* * Actions @@ -350,8 +353,6 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-blockedlog page-admin_blockedlog_list'); -$MAXLINES = getDolGlobalInt('BLOCKEDLOG_MAX_LINES', 1000); - $blocks = $block_static->getLog('all', $search_id, $MAXLINES, $sortfield, $sortorder, $search_fk_user, $search_start, $search_end, $search_ref, $search_amount, $search_code); if (!is_array($blocks)) { if ($blocks == -2) { @@ -587,7 +588,6 @@ if (is_array($blocks)) { $nbshown = 0; - $MAXFORSHOWLINK = 100; $object_link = ''; $object_link_title = ''; @@ -596,7 +596,7 @@ if (empty($search_showonlyerrors) || !$checkresult[$block->id]) { $nbshown++; - if ($nbshown < $MAXFORSHOWLINK) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output + if ($nbshown < $MAXFORSHOWNLINKS) { // For performance and memory purpose, we get/show the link of objects only for the 100 first output $object_link = $block->getObjectLink(); $object_link_title = ''; } else { From b86a48106bd73a14ecd1856550e21214f2b93e47 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 12:43:50 +0100 Subject: [PATCH 5/7] Fix phan --- htdocs/product/class/product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index eb4e784b8e67f..b06e7c98c5732 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -356,14 +356,14 @@ class Product extends CommonObject /** * Stock real (denormalized data) * - * @var int + * @var float */ public $stock_reel = 0; /** * Stock virtual * - * @var int + * @var float */ public $stock_theorique; From a64de4d24d7d93b0b5f6ed91fae1df7d58b9fa51 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 12:57:08 +0100 Subject: [PATCH 6/7] Clean code --- htdocs/barcode/printsheet.php | 6 ++--- htdocs/core/class/commonobject.class.php | 32 ++++++++++++++++-------- htdocs/core/class/html.form.class.php | 4 +-- htdocs/product/card.php | 6 ++--- htdocs/product/price_suppliers.php | 2 +- 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index ba3c994fcf7ce..3415162c2604e 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -157,7 +157,7 @@ // Get encoder (barcode_type_coder) from barcode type id (barcode_type) $stdobject = new GenericObject($db); $stdobject->barcode_type = $fk_barcode_type; - $result = $stdobject->fetch_barcode(); + $result = $stdobject->fetchBarCode(); if ($result <= 0) { $error++; setEventMessages('Failed to get bar code type information '.$stdobject->error, $stdobject->errors, 'errors'); @@ -171,8 +171,8 @@ if (!$error && $stdobject !== null) { $code = $forbarcode; - $generator = $stdobject->barcode_type_coder; // coder (loaded by fetch_barcode). Engine. - $encoding = strtoupper($stdobject->barcode_type_code); // code (loaded by fetch_barcode). Example 'ean', 'isbn', ... + $generator = $stdobject->barcode_type_coder; // coder (loaded by fetchBarCode). Engine. + $encoding = strtoupper($stdobject->barcode_type_code); // code (loaded by fetchBarCode). Example 'ean', 'isbn', ... $diroutput = $conf->barcode->dir_temp; dol_mkdir($diroutput); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 620dbb57c6103..b37acf4b7f286 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -425,25 +425,25 @@ abstract class CommonObject /** * @var int Barcode type - * @see fetch_barcode() + * @see fetchBarCode() */ public $barcode_type; /** * @var string Code of the barcode type - * @see fetch_barcode(), barcode_type + * @see fetchBarCode(), barcode_type */ public $barcode_type_code; /** * @var string Label of the barcode type - * @see fetch_barcode(), barcode_type + * @see fetchBarCode(), barcode_type */ public $barcode_type_label; /** * @var string - * @see fetch_barcode(), barcode_type + * @see fetchBarCode(), barcode_type */ public $barcode_type_coder; @@ -1702,7 +1702,7 @@ public function liste_type_contact($source = 'internal', $order = 'position', $o */ public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '', $excludeelement = '') { - global $langs, $conf; + global $langs; $langs->loadLangs(array('bills', 'contracts', 'interventions', 'orders', 'projects', 'propal', 'ticket', 'agenda')); @@ -1784,8 +1784,6 @@ public function listeTypeContacts($source = 'internal', $option = 0, $activeonly */ public function getIdContact($source, $code, $status = 0) { - global $conf; - $result = array(); $i = 0; // Particular case for shipping @@ -1952,13 +1950,24 @@ public function fetchOneLike($ref) * if it is not defined, ->element must be defined to know default barcode type. * * @return int<-1,1> Return integer <0 if KO, 0 if can't guess type of barcode (ISBN, EAN13...), >0 if OK (all barcode properties loaded) + * @deprecated Use fetchBarCode() */ public function fetch_barcode() { // phpcs:enable - global $conf; + return fetchBarCode(); + } - dol_syslog(get_class($this).'::fetch_barcode this->element='.$this->element.' this->barcode_type='.$this->barcode_type); + /** + * Load data for barcode into properties ->barcode_type* + * Properties ->barcode_type that is id of barcode. Type is used to find other properties, but + * if it is not defined, ->element must be defined to know default barcode type. + * + * @return int<-1,1> Return integer <0 if KO, 0 if can't guess type of barcode (ISBN, EAN13...), >0 if OK (all barcode properties loaded) + */ + public function fetchBarCode() + { + dol_syslog(get_class($this).'::fetchBarCode this->element='.$this->element.' this->barcode_type='.$this->barcode_type); $idtype = $this->barcode_type; if (empty($idtype) && $idtype != '0') { // If type of barcode no set, we try to guess. If set to '0' it means we forced to have type remain not defined @@ -1967,7 +1976,7 @@ public function fetch_barcode() } elseif ($this->element == 'societe') { $idtype = getDolGlobalString('GENBARCODE_BARCODETYPE_THIRDPARTY'); } else { - dol_syslog('Call fetch_barcode with barcode_type not defined and cannot be guessed', LOG_WARNING); + dol_syslog('Call fetchBarCode with barcode_type not defined and cannot be guessed', LOG_WARNING); } } @@ -1976,10 +1985,11 @@ public function fetch_barcode() $sql = "SELECT rowid, code, libelle as label, coder"; $sql .= " FROM ".$this->db->prefix()."c_barcode_type"; $sql .= " WHERE rowid = ".((int) $idtype); - dol_syslog(get_class($this).'::fetch_barcode', LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); + $this->barcode_type = $obj->rowid; $this->barcode_type_code = $obj->code; $this->barcode_type_label = $obj->label; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index be5c3028b4e86..ab6f9fdf462c2 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -10290,8 +10290,8 @@ public function showbarcode(&$object, $width = 100, $morecss = '') // Complete object if not complete if (empty($object->barcode_type_code) || empty($object->barcode_type_coder)) { // @phan-suppress-next-line PhanPluginUnknownObjectMethodCall - $result = $object->fetch_barcode(); - //Check if fetch_barcode() failed + $result = $object->fetchBarCode(); + //Check if fetchBarCode() failed if ($result < 1) { return ''; } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index b7e8cd562dfe4..6e9ebf57447ed 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -590,7 +590,7 @@ $stdobject = new GenericObject($db); $stdobject->element = 'product'; $stdobject->barcode_type = GETPOSTINT('fk_barcode_type'); - $result = $stdobject->fetch_barcode(); + $result = $stdobject->fetchBarCode(); if ($result < 0) { $error++; $mesg = 'Failed to get bar code type information '; @@ -835,7 +835,7 @@ $stdobject = new GenericObject($db); $stdobject->element = 'product'; $stdobject->barcode_type = GETPOSTINT('fk_barcode_type'); - $result = $stdobject->fetch_barcode(); + $result = $stdobject->fetchBarCode(); if ($result < 0) { $error++; $mesg = 'Failed to get bar code type information '; @@ -2555,7 +2555,7 @@ print $formbarcode->formBarcodeType($_SERVER['PHP_SELF'].'?id='.$object->id, $object->barcode_type, 'fk_barcode_type'); $fk_barcode_type = $object->barcode_type; } else { - $object->fetch_barcode(); + $object->fetchBarCode(); $fk_barcode_type = $object->barcode_type; print $object->barcode_type_label ? $object->barcode_type_label : ($object->barcode ? '
'.$langs->trans("SetDefaultBarcodeType").'
' : ''); } diff --git a/htdocs/product/price_suppliers.php b/htdocs/product/price_suppliers.php index fa1849b0192c6..d89ebed0e6e2a 100644 --- a/htdocs/product/price_suppliers.php +++ b/htdocs/product/price_suppliers.php @@ -1260,7 +1260,7 @@ function edit_price_from_multicurrency() { if (!empty($arrayfields['pfp.fk_barcode_type']['checked'])) { print ''; $productfourn->barcode_type = !empty($productfourn->supplier_fk_barcode_type) ? $productfourn->supplier_fk_barcode_type : 0; - $productfourn->fetch_barcode(); + $productfourn->fetchBarCode(); print $productfourn->barcode_type_label ? $productfourn->barcode_type_label : ($productfourn->supplier_barcode ? '
'.$langs->trans("SetDefaultBarcodeType").'
' : ''); print ''; } From 14d548143b23301471a3da417fe39231b880ad58 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 12 Nov 2024 13:08:03 +0100 Subject: [PATCH 7/7] Try to fix phpstan --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b37acf4b7f286..04d68e85489fd 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1631,7 +1631,7 @@ public function swapContactStatus($rowid) * @param int<0,1> $option 0=Return array id->label, 1=Return array code->label, 2=Return complete array * @param int<0,1> $activeonly 0=all status of contact, 1=only the active * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE') - * @return array|array|array|null Array list of type of contacts (id->label if option=0, code->label if option=1), or null if error + * @return array|array|array|null Array list of type of contacts (id->label if option=0, code->label if option=1), or null if error */ public function liste_type_contact($source = 'internal', $order = 'position', $option = 0, $activeonly = 0, $code = '') {