From 1693f8a8a49a7dd1bad8f55b764c0bed6e911389 Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 23 Jul 2026 19:06:39 +0200 Subject: [PATCH] Qual: Fix 'SqlInjection' notices (#39216) * Qual: Fix 'SqlInjection' notices # Qual: Fix 'SqlInjection' notices Batch of 25 files with changes to fix 'SqlInjection' Notices * Qual: Enhance SQL injection prevention in CodingPhpTest.php Improved the SQL injection prevention mechanism in the CodingPhpTest.php file by adding a check for integer and float casts in the IN clause of SQL queries to avoid false positives. --------- Co-authored-by: Laurent Destailleur --- .../comm/propal/class/propaleligne.class.php | 4 +- htdocs/compta/bank/treso.php | 40 ++--- .../compta/paiement/class/cpaiement.class.php | 14 +- htdocs/contact/class/contact.class.php | 16 +- htdocs/contrat/services_list.php | 100 ++++++------ htdocs/core/actions_massactions.inc.php | 22 +-- htdocs/core/lib/date.lib.php | 13 +- .../modules/import/modules_import.class.php | 146 +++++++++--------- htdocs/core/modules/modPropale.class.php | 91 +++++------ htdocs/core/tpl/objectline_view.tpl.php | 10 +- .../class/expensereportline.class.php | 6 +- htdocs/fichinter/card-rec.php | 4 +- htdocs/fichinter/class/fichinter.class.php | 7 +- .../class/fournisseur.orderline.class.php | 8 +- .../fourn/class/fournisseur.product.class.php | 4 +- htdocs/fourn/commande/list.php | 4 +- htdocs/install/upgrade.php | 8 +- .../template/class/myobject.class.php | 61 ++++---- .../modulebuilder/template/myobject_list.php | 2 +- htdocs/mrp/class/mo.class.php | 4 +- htdocs/product/composition/card.php | 2 +- htdocs/reception/card.php | 4 +- .../societe/class/api_thirdparties.class.php | 10 +- htdocs/societe/paymentmodes.php | 12 +- .../class/html.formwebportal.class.php | 6 +- test/phpunit/CodingPhpTest.php | 6 +- 26 files changed, 304 insertions(+), 300 deletions(-) diff --git a/htdocs/comm/propal/class/propaleligne.class.php b/htdocs/comm/propal/class/propaleligne.class.php index 1861ed3ce60..6a5a51cdc18 100644 --- a/htdocs/comm/propal/class/propaleligne.class.php +++ b/htdocs/comm/propal/class/propaleligne.class.php @@ -583,7 +583,7 @@ class PropaleLigne extends CommonObjectLine $sql .= ' fk_unit,'; $sql .= ' date_start, date_end'; $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)'; - $sql .= " VALUES (".$this->fk_propal.","; + $sql .= " VALUES (".((int) $this->fk_propal).","; $sql .= " ".($this->fk_parent_line > 0 ? "'".$this->db->escape((string) $this->fk_parent_line)."'" : "null").","; $sql .= " ".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " '".$this->db->escape($this->desc)."',"; @@ -795,7 +795,7 @@ class PropaleLigne extends CommonObjectLine $sql .= " description = '".$this->db->escape($this->desc)."'"; $sql .= ", label = ".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null"); $sql .= ", product_type = ".((int) $this->product_type); - $sql .= ", vat_src_code = '".(empty($this->vat_src_code) ? '' : $this->vat_src_code)."'"; + $sql .= ", vat_src_code = '".(empty($this->vat_src_code) ? '' : $this->db->escape($this->vat_src_code))."'"; $sql .= ", tva_tx='".price2num($this->tva_tx)."'"; $sql .= ", localtax1_tx=".price2num($this->localtax1_tx); $sql .= ", localtax2_tx=".price2num($this->localtax2_tx); diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index 939bde75a43..d22f78a931c 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -125,7 +125,7 @@ if (GETPOST("account") || GETPOST("ref")) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql .= " WHERE f.entity IN (".getEntity('invoice').")"; $sql .= " AND f.paye = 0 AND f.fk_statut = 1"; // Not paid - $sql .= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice + $sql .= " AND (f.fk_account IN (0, ".((int) $object->id).") OR f.fk_account IS NULL)"; // Id bank account of invoice $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; @@ -134,9 +134,9 @@ if (GETPOST("account") || GETPOST("ref")) { $sql .= " s.rowid as socid, s.nom as name, s.fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid"; - $sql .= " WHERE ff.entity = ".$conf->entity; + $sql .= " WHERE ff.entity = ".((int) $conf->entity); $sql .= " AND ff.paye = 0 AND fk_statut = 1"; // Not paid - $sql .= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice + $sql .= " AND (ff.fk_account IN (0, ".((int) $object->id).") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; @@ -145,9 +145,9 @@ if (GETPOST("account") || GETPOST("ref")) { $sql .= " 0 as socid, 'noname' as name, 0 as fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id"; - $sql .= " WHERE cs.entity = ".$conf->entity; + $sql .= " WHERE cs.entity = ".((int) $conf->entity); $sql .= " AND cs.paye = 0"; // Not paid - $sql .= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution + $sql .= " AND (cs.fk_account IN (0, ".((int) $object->id).") OR cs.fk_account IS NULL)"; // Id bank account of social contribution $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; @@ -156,9 +156,9 @@ if (GETPOST("account") || GETPOST("ref")) { $sql .= " s.rowid as socid, CONCAT(s.firstname, ' ', s.lastname) as name, 0 as fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."salary as sa"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as s ON sa.fk_user = s.rowid"; - $sql .= " WHERE sa.entity = ".$conf->entity; + $sql .= " WHERE sa.entity = ".((int) $conf->entity); $sql .= " AND sa.paye = 0"; // Not paid - $sql .= " AND (sa.fk_account IN (0, ".$object->id.") OR sa.fk_account IS NULL)"; // Id bank account of salary + $sql .= " AND (sa.fk_account IN (0, ".((int) $object->id).") OR sa.fk_account IS NULL)"; // Id bank account of salary $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; @@ -166,9 +166,9 @@ if (GETPOST("account") || GETPOST("ref")) { $sql = " SELECT 'vat' as family, t.rowid as objid, t.label as ref, (-1*t.amount) as total_ttc, t.datev as dlr,"; $sql .= " 0 as socid, 'noname' as name, 0 as fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."tva as t"; - $sql .= " WHERE t.entity = ".$conf->entity; + $sql .= " WHERE t.entity = ".((int) $conf->entity); $sql .= " AND t.paye = 0"; // Not paid - $sql .= " AND (t.fk_account IN (-1, 0, ".$object->id.") OR t.fk_account IS NULL)"; // Id bank account of vat + $sql .= " AND (t.fk_account IN (-1, 0, ".((int) $object->id).") OR t.fk_account IS NULL)"; // Id bank account of vat $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; @@ -188,20 +188,20 @@ if (GETPOST("account") || GETPOST("ref")) { $resql = $db->query($sql); if ($resql) { $nbtotalofrecords += $db->num_rows($resql); - while ($sqlobj = $db->fetch_object($resql)) { + while ($res_obj = $db->fetch_object($resql)) { $tmpobj = new stdClass(); - $tmpobj->family = $sqlobj->family; - $tmpobj->objid = $sqlobj->objid; - $tmpobj->ref = $sqlobj->ref; - $tmpobj->total_ttc = $sqlobj->total_ttc; - $tmpobj->type = $sqlobj->type; - $tmpobj->dlr = $db->jdate($sqlobj->dlr); - $tmpobj->socid = $sqlobj->socid; - $tmpobj->name = $sqlobj->name; - $tmpobj->fournisseur = $sqlobj->fournisseur; + $tmpobj->family = $res_obj->family; + $tmpobj->objid = $res_obj->objid; + $tmpobj->ref = $res_obj->ref; + $tmpobj->total_ttc = $res_obj->total_ttc; + $tmpobj->type = $res_obj->type; + $tmpobj->dlr = $db->jdate($res_obj->dlr); + $tmpobj->socid = $res_obj->socid; + $tmpobj->name = $res_obj->name; + $tmpobj->fournisseur = $res_obj->fournisseur; $tab_sqlobj[] = $tmpobj; - $tab_sqlobjOrder[] = $db->jdate($sqlobj->dlr); + $tab_sqlobjOrder[] = $db->jdate($res_obj->dlr); } $db->free($resql); } else { diff --git a/htdocs/compta/paiement/class/cpaiement.class.php b/htdocs/compta/paiement/class/cpaiement.class.php index b997d2adab1..89fe684eb80 100644 --- a/htdocs/compta/paiement/class/cpaiement.class.php +++ b/htdocs/compta/paiement/class/cpaiement.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2015 Florian Henry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2023-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2026 MDW * * 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 @@ -130,11 +130,11 @@ class Cpaiement extends CommonDict $sql .= 'accountancy_code,'; $sql .= 'module'; $sql .= ') VALUES ('; - $sql .= ' '.(!isset($this->entity) ? getEntity('c_paiement') : $this->entity).','; + $sql .= ' '.(!isset($this->entity) ? getEntity('c_paiement') : ((int) $this->entity)).','; $sql .= ' '.(!isset($this->code) ? 'NULL' : "'".$this->db->escape($this->code)."'").','; $sql .= ' '.(!isset($this->libelle) ? 'NULL' : "'".$this->db->escape($this->libelle)."'").','; - $sql .= ' '.(!isset($this->type) ? 'NULL' : $this->type).','; - $sql .= ' '.(!isset($this->active) ? 'NULL' : $this->active).','; + $sql .= ' '.(!isset($this->type) ? 'NULL' : "'".$this->db->escape($this->type)."'").','; + $sql .= ' '.(!isset($this->active) ? 'NULL' : ((int) $this->active)).','; $sql .= ' '.(!isset($this->accountancy_code) ? 'NULL' : "'".$this->db->escape($this->accountancy_code)."'").','; $sql .= ' '.(!isset($this->module) ? 'NULL' : "'".$this->db->escape($this->module)."'"); $sql .= ')'; @@ -277,11 +277,11 @@ class Cpaiement extends CommonDict // Update request $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; - $sql .= ' id = '.(isset($this->id) ? $this->id : "null").','; + $sql .= ' id = '.(isset($this->id) ? ((int) $this->id) : "null").','; $sql .= ' code = '.(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").','; $sql .= ' libelle = '.(isset($this->libelle) ? "'".$this->db->escape($this->libelle)."'" : "null").','; - $sql .= ' type = '.(isset($this->type) ? $this->type : "null").','; - $sql .= ' active = '.(isset($this->active) ? $this->active : "null").','; + $sql .= ' type = '.(isset($this->type) ? "'".$this->db->escape($this->type)."'" : "null").','; + $sql .= ' active = '.(isset($this->active) ? ((int) $this->active) : "null").','; $sql .= ' accountancy_code = '.(isset($this->accountancy_code) ? "'".$this->db->escape($this->accountancy_code)."'" : "null").','; $sql .= ' module = '.(isset($this->module) ? "'".$this->db->escape($this->module)."'" : "null"); $sql .= ' WHERE id = '.((int) $this->id); diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 34eb76d7982..557bc7ca714 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2020 Open-Dsi * Copyright (C) 2024-2025 Frédéric France - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * * 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 @@ -665,8 +665,8 @@ class Contact extends CommonObject $sql .= ", zip='".$this->db->escape($this->zip)."'"; $sql .= ", town='".$this->db->escape($this->town)."'"; $sql .= ", ref_ext = ".(!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "NULL"); - $sql .= ", fk_pays=".($this->country_id > 0 ? $this->country_id : 'NULL'); - $sql .= ", fk_departement=".($this->state_id > 0 ? $this->state_id : 'NULL'); + $sql .= ", fk_pays=".($this->country_id > 0 ? ((int) $this->country_id) : 'NULL'); + $sql .= ", fk_departement=".($this->state_id > 0 ? ((int) $this->state_id) : 'NULL'); $sql .= ", poste='".$this->db->escape($this->poste)."'"; $sql .= ", fax='".$this->db->escape($this->fax)."'"; $sql .= ", email='".$this->db->escape($this->email)."'"; @@ -681,7 +681,7 @@ class Contact extends CommonObject $sql .= ", priv = ".((int) $this->priv); $sql .= ", fk_prospectlevel = '".$this->db->escape($this->fk_prospectlevel)."'"; if (isset($this->stcomm_id)) { - $sql .= ", fk_stcommcontact = ".($this->stcomm_id > 0 || $this->stcomm_id == -1 ? $this->stcomm_id : "0"); + $sql .= ", fk_stcommcontact = ".($this->stcomm_id > 0 || $this->stcomm_id == -1 ? ((int) $this->stcomm_id) : "0"); } $sql .= ", statut = ".((int) $this->status); $sql .= ", fk_user_modif=".($user->id > 0 ? "'".$this->db->escape((string) $user->id)."'" : "NULL"); @@ -2009,11 +2009,11 @@ class Contact extends CommonObject $sql .= "fk_soc,"; $sql .= "fk_c_type_contact,"; $sql .= "fk_socpeople) "; - $sql .= " VALUES (".$conf->entity.","; + $sql .= " VALUES (".((int) $conf->entity).","; $sql .= "'".$this->db->idate(dol_now())."',"; - $sql .= $socid.", "; - $sql .= $idrole." , "; - $sql .= $this->id; + $sql .= ((int) $socid).", "; + $sql .= ((int) $idrole)." , "; + $sql .= ((int) $this->id); $sql .= ")"; $result = $this->db->query($sql); diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 692c93a71e5..cb76169a009 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -7,7 +7,7 @@ * Copyright (C) 2018-2026 Frédéric France * Copyright (C) 2019 Juanjo Menent * Copyright (C) 2023-2024 William Mead - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -100,22 +100,22 @@ $socid = GETPOSTINT('socid'); $opouvertureprevuemonth = GETPOST('opouvertureprevuemonth'); $opouvertureprevueday = GETPOST('opouvertureprevueday'); $opouvertureprevueyear = GETPOST('opouvertureprevueyear'); -$filter_opouvertureprevue = GETPOST('filter_opouvertureprevue', 'alphawithlgt'); +$sqlfilter_opouvertureprevue = GETPOST('filter_opouvertureprevue', 'alphawithlgt'); // @phan-suppress-current-line SqlInjection $op1month = GETPOSTINT('op1month'); $op1day = GETPOSTINT('op1day'); $op1year = GETPOSTINT('op1year'); -$filter_op1 = GETPOST('filter_op1', 'alphawithlgt'); +$sqlfilter_op1 = GETPOST('filter_op1', 'alphawithlgt'); // @phan-suppress-current-line SqlInjection $op2month = GETPOSTINT('op2month'); $op2day = GETPOSTINT('op2day'); $op2year = GETPOSTINT('op2year'); -$filter_op2 = GETPOST('filter_op2', 'alphawithlgt'); +$sqlfilter_op2 = GETPOST('filter_op2', 'alphawithlgt'); // @phan-suppress-current-line SqlInjection $opcloturemonth = GETPOSTINT('opcloturemonth'); $opclotureday = GETPOSTINT('opclotureday'); $opclotureyear = GETPOSTINT('opclotureyear'); -$filter_opcloture = GETPOST('filter_opcloture', 'alphawithlgt'); +$sqlfilter_opcloture = GETPOST('filter_opcloture', 'alphawithlgt'); // @phan-suppress-current-line SqlInjection // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context @@ -205,19 +205,19 @@ if (empty($reshook)) { $opouvertureprevuemonth = ""; $opouvertureprevueday = ""; $opouvertureprevueyear = ""; - $filter_opouvertureprevue = ""; + $sqlfilter_opouvertureprevue = ""; $op1month = ""; $op1day = ""; $op1year = ""; - $filter_op1 = ""; + $sqlfilter_op1 = ""; $op2month = ""; $op2day = ""; $op2year = ""; - $filter_op2 = ""; + $sqlfilter_op2 = ""; $opcloturemonth = ""; $opclotureday = ""; $opclotureyear = ""; - $filter_opcloture = ""; + $sqlfilter_opcloture = ""; $filter = ''; $toselect = array(); $search_array_options = array(); @@ -316,12 +316,12 @@ if ($search_status == "5") { $sql .= " AND cd.statut = 5"; } if ($search_option == 'late' && $search_status != '0') { - $warning_date = $db->idate(dol_now() - $conf->contract->services->expires->warning_delay); - $sql .= " AND cd.date_fin_validite < '".addslashes($warning_date)."'"; + $warning_date = $db->idate(dol_now() - (int) $conf->contract->services->expires->warning_delay); + $sql .= " AND cd.date_fin_validite < '".$db->escape($warning_date)."'"; } if ($search_option == 'late' && $search_status == '0') { - $warning_date = $db->idate(dol_now() - $conf->contract->services->expires->warning_delay); - $sql .= " AND (cd.date_ouverture_prevue < '".addslashes($warning_date)."' OR cd.date_fin_validite < '".addslashes($warning_date)."')"; + $warning_date = $db->idate(dol_now() - (int) $conf->contract->services->expires->warning_delay); + $sql .= " AND (cd.date_ouverture_prevue < '".$db->escape($warning_date)."' OR cd.date_fin_validite < '".$db->escape($warning_date)."')"; } if ($search_subprice) { $sql .= natural_search("cd.subprice", $search_subprice, 1); @@ -354,55 +354,55 @@ if ($socid > 0) { $filter_dateouvertureprevue = ''; $filter_date1 = ''; $filter_date2 = ''; -$filter_opcloture = ''; +$sqlfilter_opcloture = ''; $filter_dateouvertureprevue_start = dol_mktime(0, 0, 0, (int) $opouvertureprevuemonth, (int) $opouvertureprevueday, (int) $opouvertureprevueyear); $filter_dateouvertureprevue_end = dol_mktime(23, 59, 59, (int) $opouvertureprevuemonth, (int) $opouvertureprevueday, (int) $opouvertureprevueyear); -if ($filter_dateouvertureprevue_start != '' && $filter_opouvertureprevue == -1) { - $filter_opouvertureprevue = ' BETWEEN '; +if ($filter_dateouvertureprevue_start != '' && $sqlfilter_opouvertureprevue == -1) { + $sqlfilter_opouvertureprevue = ' BETWEEN '; } $filter_date1_start = dol_mktime(0, 0, 0, (int) $op1month, (int) $op1day, (int) $op1year); $filter_date1_end = dol_mktime(23, 59, 59, (int) $op1month, (int) $op1day, (int) $op1year); -if ($filter_date1_start != '' && $filter_op1 == -1) { - $filter_op1 = ' BETWEEN '; +if ($filter_date1_start != '' && $sqlfilter_op1 == -1) { + $sqlfilter_op1 = ' BETWEEN '; } $filter_date2_start = dol_mktime(0, 0, 0, (int) $op2month, (int) $op2day, (int) $op2year); $filter_date2_end = dol_mktime(23, 59, 59, (int) $op2month, (int) $op2day, (int) $op2year); -if ($filter_date2_start != '' && $filter_op2 == -1) { - $filter_op2 = ' BETWEEN '; +if ($filter_date2_start != '' && $sqlfilter_op2 == -1) { + $sqlfilter_op2 = ' BETWEEN '; } $filter_datecloture_start = dol_mktime(0, 0, 0, (int) $opcloturemonth, (int) $opclotureday, (int) $opclotureyear); $filter_datecloture_end = dol_mktime(23, 59, 59, (int) $opcloturemonth, (int) $opclotureday, (int) $opclotureyear); -if ($filter_datecloture_start != '' && $filter_opcloture == -1) { - $filter_opcloture = ' BETWEEN '; +if ($filter_datecloture_start != '' && $sqlfilter_opcloture == -1) { + $sqlfilter_opcloture = ' BETWEEN '; } -if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue != -1 && $filter_opouvertureprevue != ' BETWEEN ' && $filter_dateouvertureprevue_start != '') { - $sql .= " AND cd.date_ouverture_prevue ".preg_replace('/[^<>]/', '', $filter_opouvertureprevue)." '".$db->idate($filter_dateouvertureprevue_start)."'"; +if (!empty($sqlfilter_opouvertureprevue) && $sqlfilter_opouvertureprevue != -1 && $sqlfilter_opouvertureprevue != ' BETWEEN ' && $filter_dateouvertureprevue_start != '') { + $sql .= " AND cd.date_ouverture_prevue ".preg_replace('/[^<>]/', '', $sqlfilter_opouvertureprevue)." '".$db->idate($filter_dateouvertureprevue_start)."'"; } -if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue == ' BETWEEN ') { - $sql .= " AND cd.date_ouverture_prevue ".$db->sanitize($filter_opouvertureprevue)." '".$db->idate($filter_dateouvertureprevue_start)."' AND '".$db->idate($filter_dateouvertureprevue_end)."'"; +if (!empty($sqlfilter_opouvertureprevue) && $sqlfilter_opouvertureprevue == ' BETWEEN ') { + $sql .= " AND cd.date_ouverture_prevue ".$db->sanitize($sqlfilter_opouvertureprevue)." '".$db->idate($filter_dateouvertureprevue_start)."' AND '".$db->idate($filter_dateouvertureprevue_end)."'"; } -if (!empty($filter_op1) && $filter_op1 != -1 && $filter_op1 != ' BETWEEN ' && $filter_date1_start != '') { - $sql .= " AND cd.date_ouverture ".preg_replace('/[^<>]/', '', $filter_op1)." '".$db->idate($filter_date1_start)."'"; +if (!empty($sqlfilter_op1) && $sqlfilter_op1 != -1 && $sqlfilter_op1 != ' BETWEEN ' && $filter_date1_start != '') { + $sql .= " AND cd.date_ouverture ".preg_replace('/[^<>]/', '', $sqlfilter_op1)." '".$db->idate($filter_date1_start)."'"; } -if (!empty($filter_op1) && $filter_op1 == ' BETWEEN ') { - $sql .= " AND cd.date_ouverture ".$db->sanitize($filter_op1)." '".$db->idate($filter_date1_start)."' AND '".$db->idate($filter_date1_end)."'"; +if (!empty($sqlfilter_op1) && $sqlfilter_op1 == ' BETWEEN ') { + $sql .= " AND cd.date_ouverture ".$db->sanitize($sqlfilter_op1)." '".$db->idate($filter_date1_start)."' AND '".$db->idate($filter_date1_end)."'"; } -if (!empty($filter_op2) && $filter_op2 != -1 && $filter_op2 != ' BETWEEN ' && $filter_date2_start != '') { - $sql .= " AND cd.date_fin_validite ".preg_replace('/[^<>]/', '', $filter_op2)." '".$db->idate($filter_date2_start)."'"; +if (!empty($sqlfilter_op2) && $sqlfilter_op2 != -1 && $sqlfilter_op2 != ' BETWEEN ' && $filter_date2_start != '') { + $sql .= " AND cd.date_fin_validite ".preg_replace('/[^<>]/', '', $sqlfilter_op2)." '".$db->idate($filter_date2_start)."'"; } -if (!empty($filter_op2) && $filter_op2 == ' BETWEEN ') { - $sql .= " AND cd.date_fin_validite ".$db->sanitize($filter_op2)." '".$db->idate($filter_date2_start)."' AND '".$db->idate($filter_date2_end)."'"; +if (!empty($sqlfilter_op2) && $sqlfilter_op2 == ' BETWEEN ') { + $sql .= " AND cd.date_fin_validite ".$db->sanitize($sqlfilter_op2)." '".$db->idate($filter_date2_start)."' AND '".$db->idate($filter_date2_end)."'"; } -if (!empty($filter_opcloture) && $filter_opcloture != ' BETWEEN ' && $filter_opcloture != -1 && $filter_datecloture_start != '') { - $sql .= " AND cd.date_cloture ".preg_replace('/[^<>]/', '', $filter_opcloture)." '".$db->idate($filter_datecloture_start)."'"; +if (!empty($sqlfilter_opcloture) && $sqlfilter_opcloture != ' BETWEEN ' && $sqlfilter_opcloture != -1 && $filter_datecloture_start != '') { + $sql .= " AND cd.date_cloture ".preg_replace('/[^<>]/', '', $sqlfilter_opcloture)." '".$db->idate($filter_datecloture_start)."'"; } -if (!empty($filter_opcloture) && $filter_opcloture == ' BETWEEN ') { - $sql .= " AND cd.date_cloture ".$db->sanitize($filter_opcloture)." '".$db->idate($filter_datecloture_start)."' AND '".$db->idate($filter_datecloture_end)."'"; +if (!empty($sqlfilter_opcloture) && $sqlfilter_opcloture == ' BETWEEN ') { + $sql .= " AND cd.date_cloture ".$db->sanitize($sqlfilter_opcloture)." '".$db->idate($filter_datecloture_start)."' AND '".$db->idate($filter_datecloture_end)."'"; } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -503,17 +503,17 @@ if ($search_status != '') { if ($search_option) { $param .= "&search_option=".urlencode($search_option); } -if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue != -1) { - $param .= '&filter_opouvertureprevue='.urlencode($filter_opouvertureprevue); +if (!empty($sqlfilter_opouvertureprevue) && $sqlfilter_opouvertureprevue != -1) { + $param .= '&filter_opouvertureprevue='.urlencode($sqlfilter_opouvertureprevue); } -if (!empty($filter_op1) && $filter_op1 != -1) { - $param .= '&filter_op1='.urlencode($filter_op1); +if (!empty($sqlfilter_op1) && $sqlfilter_op1 != -1) { + $param .= '&filter_op1='.urlencode($sqlfilter_op1); } -if (!empty($filter_op2) && $filter_op2 != -1) { - $param .= '&filter_op2='.urlencode($filter_op2); +if (!empty($sqlfilter_op2) && $sqlfilter_op2 != -1) { + $param .= '&filter_op2='.urlencode($sqlfilter_op2); } -if (!empty($filter_opcloture) && $filter_opcloture != -1) { - $param .= '&filter_opcloture='.urlencode($filter_opcloture); +if (!empty($sqlfilter_opcloture) && $sqlfilter_opcloture != -1) { + $param .= '&filter_opcloture='.urlencode($sqlfilter_opcloture); } if ($filter_dateouvertureprevue_start != '') { $param .= '&opouvertureprevueday='.((int) $opouvertureprevueday).'&opouvertureprevuemonth='.((int) $opouvertureprevuemonth).'&opouvertureprevueyear='.((int) $opouvertureprevueyear); @@ -668,7 +668,7 @@ if (!empty($arrayfields['s.nom']['checked'])) { if (!empty($arrayfields['cd.date_ouverture_prevue']['checked'])) { print ''; $arrayofoperators = array('<' => '<', '>' => '>'); - print $form->selectarray('filter_opouvertureprevue', $arrayofoperators, $filter_opouvertureprevue, 1, 0, 0, '', 0, 0, 0, '', 'width50'); + print $form->selectarray('filter_opouvertureprevue', $arrayofoperators, $sqlfilter_opouvertureprevue, 1, 0, 0, '', 0, 0, 0, '', 'width50'); print ' '; $filter_dateouvertureprevue = dol_mktime(0, 0, 0, (int) $opouvertureprevuemonth, (int) $opouvertureprevueday, (int) $opouvertureprevueyear); print $form->selectDate($filter_dateouvertureprevue, 'opouvertureprevue', 0, 0, 1, '', 1, 0); @@ -677,7 +677,7 @@ if (!empty($arrayfields['cd.date_ouverture_prevue']['checked'])) { if (!empty($arrayfields['cd.date_ouverture']['checked'])) { print ''; $arrayofoperators = array('<' => '<', '>' => '>'); - print $form->selectarray('filter_op1', $arrayofoperators, $filter_op1, 1, 0, 0, '', 0, 0, 0, '', 'width50'); + print $form->selectarray('filter_op1', $arrayofoperators, $sqlfilter_op1, 1, 0, 0, '', 0, 0, 0, '', 'width50'); print ' '; $filter_date1 = dol_mktime(0, 0, 0, (int) $op1month, (int) $op1day, (int) $op1year); print $form->selectDate($filter_date1, 'op1', 0, 0, 1, '', 1, 0); @@ -686,7 +686,7 @@ if (!empty($arrayfields['cd.date_ouverture']['checked'])) { if (!empty($arrayfields['cd.date_fin_validite']['checked'])) { print ''; $arrayofoperators = array('<' => '<', '>' => '>'); - print $form->selectarray('filter_op2', $arrayofoperators, $filter_op2, 1, 0, 0, '', 0, 0, 0, '', 'width50'); + print $form->selectarray('filter_op2', $arrayofoperators, $sqlfilter_op2, 1, 0, 0, '', 0, 0, 0, '', 'width50'); print ' '; $filter_date2 = dol_mktime(0, 0, 0, (int) $op2month, (int) $op2day, (int) $op2year); print $form->selectDate($filter_date2, 'op2', 0, 0, 1, '', 1, 0); @@ -695,7 +695,7 @@ if (!empty($arrayfields['cd.date_fin_validite']['checked'])) { if (!empty($arrayfields['cd.date_cloture']['checked'])) { print ''; $arrayofoperators = array('<' => '<', '>' => '>'); - print $form->selectarray('filter_opcloture', $arrayofoperators, $filter_opcloture, 1, 0, 0, '', 0, 0, 0, '', 'width50'); + print $form->selectarray('filter_opcloture', $arrayofoperators, $sqlfilter_opcloture, 1, 0, 0, '', 0, 0, 0, '', 'width50'); print ' '; $filter_date_cloture = dol_mktime(0, 0, 0, (int) $opcloturemonth, (int) $opclotureday, (int) $opclotureyear); print $form->selectDate($filter_date_cloture, 'opcloture', 0, 0, 1, '', 1, 0); diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 618070a32cf..29fd51c267b 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -503,29 +503,29 @@ if (!$error && $massaction == 'confirm_presend') { // Send email if there is at least one qualified object for current thirdparty if (count($listofqualifiedobj) > 0) { $langs->load("commercial"); - $from = ''; + $email_from = ''; $reg = array(); $fromtype = GETPOST('fromtype'); if ($fromtype === 'user') { - $from = dol_string_nospecial($user->getFullName($langs), ' ', array(",")).' <'.$user->email.'>'; + $email_from = dol_string_nospecial($user->getFullName($langs), ' ', array(",")).' <'.$user->email.'>'; } elseif ($fromtype === 'company') { - $from = getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'>'; + $email_from = getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'>'; } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) { $tmp = explode(',', getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES')); - $from = trim($tmp[((int) $reg[1] - 1)]); + $email_from = trim($tmp[((int) $reg[1] - 1)]); } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) { $sql = "SELECT rowid, label, email FROM ".MAIN_DB_PREFIX."c_email_senderprofile WHERE rowid = ".(int) $reg[1]; $resql = $db->query($sql); $obj = $db->fetch_object($resql); if ($obj) { - $from = dol_string_nospecial($obj->label, ' ', array(",")).' <'.$obj->email.'>'; + $email_from = dol_string_nospecial($obj->label, ' ', array(",")).' <'.$obj->email.'>'; } } else { - $from = GETPOST('fromname').' <'.GETPOST('frommail').'>'; + $email_from = GETPOST('fromname').' <'.GETPOST('frommail').'>'; } - $replyto = $from; + $replyto = $email_from; $subject = GETPOST('subject', 'restricthtml'); $message = GETPOST('message', 'restricthtml'); @@ -667,7 +667,7 @@ if (!$error && $massaction == 'confirm_presend') { // Send mail (substitutionarray must be done just before this) require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subjectreplaced, (string) $sendto, $from, $messagereplaced, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, (int) $deliveryreceipt, -1, '', '', $trackid, '', $sendcontext, '', $upload_dir_tmp); + $mailfile = new CMailFile($subjectreplaced, (string) $sendto, $email_from, $messagereplaced, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, (int) $deliveryreceipt, -1, '', '', $trackid, '', $sendcontext, '', $upload_dir_tmp); if ($mailfile->error) { $resaction .= '
'.$mailfile->error.'
'; } else { @@ -692,7 +692,7 @@ if (!$error && $massaction == 'confirm_presend') { if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD'; if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/ - $actionmsg = $langs->transnoentities('MailSentByTo', $from, (string) $sendto); + $actionmsg = $langs->transnoentities('MailSentByTo', $email_from, (string) $sendto); if ($message) { if ($sendtocc) { $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); @@ -761,12 +761,12 @@ if (!$error && $massaction == 'confirm_presend') { } else { $langs->load("other"); if ($mailfile->error) { - $resaction .= $langs->trans('ErrorFailedToSendMail', $from, (string) $sendto); + $resaction .= $langs->trans('ErrorFailedToSendMail', $email_from, (string) $sendto); $resaction .= '
'.$mailfile->error.'
'; } elseif (getDolGlobalString('MAIN_DISABLE_ALL_MAILS')) { $resaction .= '
No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
'; } else { - $resaction .= $langs->trans('ErrorFailedToSendMail', $from, (string) $sendto) . '
(unhandled error)
'; + $resaction .= $langs->trans('ErrorFailedToSendMail', $email_from, (string) $sendto) . '
(unhandled error)
'; } } } diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 3857436367d..e8319cb3fad 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -391,23 +391,24 @@ function dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $exclu $day_date = intval($day_date); $month_date = intval($month_date); $year_date = intval($year_date); + $sql_datefield = $db->sanitize($datefield); if ($month_date > 0) { if ($month_date > 12) { // protection for bad value of month return " AND 1 = 2"; } if ($year_date > 0 && empty($day_date)) { - $sqldate .= ($excludefirstand ? "" : " AND ").$datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, $month_date, $gm)); + $sqldate .= ($excludefirstand ? "" : " AND ").$sql_datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, $month_date, $gm)); $sqldate .= "' AND '".$db->idate(dol_get_last_day($year_date, $month_date, $gm))."'"; } elseif ($year_date > 0 && !empty($day_date)) { - $sqldate .= ($excludefirstand ? "" : " AND ").$datefield." BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date, $day_date, $year_date, $gm)); + $sqldate .= ($excludefirstand ? "" : " AND ").$sql_datefield." BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date, $day_date, $year_date, $gm)); $sqldate .= "' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date, $day_date, $year_date, $gm))."'"; } else { // This case is not reliable on TZ, but we should not need it. - $sqldate .= ($excludefirstand ? "" : " AND ")." date_format( ".$datefield.", '%c') = '".$db->escape((string) $month_date)."'"; + $sqldate .= ($excludefirstand ? "" : " AND ")." date_format( ".$sql_datefield.", '%c') = '".$db->escape((string) $month_date)."'"; } } elseif ($year_date > 0) { - $sqldate .= ($excludefirstand ? "" : " AND ").$datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, 1, $gm)); + $sqldate .= ($excludefirstand ? "" : " AND ").$sql_datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, 1, $gm)); $sqldate .= "' AND '".$db->idate(dol_get_last_day($year_date, 12, $gm))."'"; } return $sqldate; @@ -806,7 +807,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $countryCodeOrId = ' $tmpArrayOfPublicHolidays = array(); $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; $sql .= " FROM ".MAIN_DB_PREFIX."c_hrm_public_holiday"; - $sql .= " WHERE active = 1 and fk_country IN (0".($country_id > 0 ? ", ".$country_id : 0).")"; + $sql .= " WHERE active = 1 and fk_country IN (0".($country_id > 0 ? ", ".((int) $country_id) : 0).")"; $sql .= " AND entity IN (0," .getEntity('holiday') .")"; $resql = $db->query($sql); @@ -1072,7 +1073,7 @@ function listPublicHoliday($timestampStart, $timestampEnd, $countryCodeOrId = '' $tmpArrayOfPublicHolidays = array(); $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; $sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday"; - $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")"; + $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . ((int) $country_id) : 0) . ")"; $sql .= " AND entity IN (0," . getEntity('holiday') . ")"; $resql = $db->query($sql); diff --git a/htdocs/core/modules/import/modules_import.class.php b/htdocs/core/modules/import/modules_import.class.php index 0c787faa245..4627a45c705 100644 --- a/htdocs/core/modules/import/modules_import.class.php +++ b/htdocs/core/modules/import/modules_import.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -1039,8 +1039,8 @@ class ModeleImports foreach ($objimport->array_import_tables[0] as $alias => $tablename) { // Build sql request $sql = ''; - $listfields = array(); - $listvalues = array(); + $sql_listfields = array(); + $sql_listvalues = array(); $i = 0; $errorforthistable = 0; @@ -1081,7 +1081,7 @@ class ModeleImports } if ($key <= $maxfields) { - // Set $newval with value to insert and set $listvalues with sql request part for insert + // Set $newval with value to insert and set $sql_listvalues with sql request part for insert $newval = ''; if ($arrayrecord[($key - 1)]['type'] > 0) { $newval = $arrayrecord[($key - 1)]['val']; // If type of field into input file is not empty string (so defined into input file), we get value @@ -1199,11 +1199,11 @@ class ModeleImports if ($isidorref == 'ref') { $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); - $class = $objimport->array_import_convertvalue[0][$val]['class']; - $method = $objimport->array_import_convertvalue[0][$val]['method']; - $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield']; - $code = $arrayrecord[$arrayfield[$codefromfield]]['val']; - $cachekey = $file.'_'.$class.'_'.$method.'_'.$code; + $class = $objimport->array_import_convertvalue[0][$val]['class']; + $method = $objimport->array_import_convertvalue[0][$val]['method']; + $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield']; + $code = $arrayrecord[$arrayfield[$codefromfield]]['val']; + $cachekey = $file.'_'.$class.'_'.$method.'_'.$code; if (isset($this->cacheconvert[$cachekey][$newval]) && $this->cacheconvert[$cachekey][$newval] != '') { $newval = $this->cacheconvert[$cachekey][$newval]; } else { @@ -1236,11 +1236,11 @@ class ModeleImports $newval = '0'; } } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeunits' || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchscalefromcodeunits') { - $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); - $class = $objimport->array_import_convertvalue[0][$val]['class']; - $method = $objimport->array_import_convertvalue[0][$val]['method']; - $units = $objimport->array_import_convertvalue[0][$val]['units']; - $cachekey = $file.'_'.$class.'_'.$method.'_'.$units; + $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); + $class = $objimport->array_import_convertvalue[0][$val]['class']; + $method = $objimport->array_import_convertvalue[0][$val]['method']; + $units = $objimport->array_import_convertvalue[0][$val]['units']; + $cachekey = $file.'_'.$class.'_'.$method.'_'.$units; if (isset($this->cacheconvert[$cachekey][$newval]) && $this->cacheconvert[$cachekey][$newval] != '') { $newval = $this->cacheconvert[$cachekey][$newval]; } else { @@ -1350,8 +1350,8 @@ class ModeleImports break; } $classinstance = new $class($this->db); - $computedFieldPos = isset($arrayfield[$val]) ? ((int) $arrayfield[$val]) : 0; - $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $computedFieldPos)); + $computedFieldPos = isset($arrayfield[$val]) ? ((int) $arrayfield[$val]) : 0; + $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $computedFieldPos)); if (empty($classinstance->error) && empty($classinstance->errors)) { $newval = $res; // We get new value computed. } else { @@ -1447,38 +1447,38 @@ class ModeleImports // ... } - // Define $listfields and $listvalues to build the SQL request + // Define $sql_listfields and $sql_listvalues to build the SQL request if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) { - if (!in_array("socialnetworks", $listfields)) { - $listfields[] = "socialnetworks"; - $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array - $listvalues[$socialkey] = ''; + if (!in_array("socialnetworks", $sql_listfields)) { + $sql_listfields[] = "socialnetworks"; + $socialkey = array_search("socialnetworks", $sql_listfields); // Return position of 'socialnetworks' key in array + $sql_listvalues[$socialkey] = ''; } //var_dump($newval); var_dump($arrayrecord[($key - 1)]['type']); if (!empty($newval) && $arrayrecord[($key - 1)]['type'] > 0) { - $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array + $socialkey = array_search("socialnetworks", $sql_listfields); // Return position of 'socialnetworks' key in array //var_dump('sk='.$socialkey); // socialkey=19 $socialnetwork = explode("_", $fieldname)[1]; - if (empty($listvalues[$socialkey]) || $listvalues[$socialkey] == "null") { + if (empty($sql_listvalues[$socialkey]) || $sql_listvalues[$socialkey] == "null") { $json = new stdClass(); $json->$socialnetwork = $newval; - $listvalues[$socialkey] = json_encode($json); + $sql_listvalues[$socialkey] = json_encode($json); } else { - $jsondata = $listvalues[$socialkey]; + $jsondata = $sql_listvalues[$socialkey]; $json = json_decode($jsondata); $json->$socialnetwork = $newval; - $listvalues[$socialkey] = json_encode($json); + $sql_listvalues[$socialkey] = json_encode($json); } } } else { - $listfields[] = $fieldname; + $sql_listfields[] = $this->db->sanitize($fieldname); // Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert if (empty($newval) && $arrayrecord[($key - 1)]['type'] < 0) { - $listvalues[] = ($newval == '0' ? (int) $newval : "null"); + $sql_listvalues[] = ($newval == '0' ? (int) $newval : "null"); } elseif (empty($newval) && $arrayrecord[($key - 1)]['type'] == 0) { - $listvalues[] = "''"; + $sql_listvalues[] = "''"; } else { - $listvalues[] = "'".$this->db->escape($newval)."'"; + $sql_listvalues[] = "'".$this->db->escape($newval)."'"; } } } @@ -1488,7 +1488,7 @@ class ModeleImports // We add hidden fields (but only if there is at least one field to add into table) // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file. // Previously we processed the ->import_fields_array. - if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) { + if (!empty($sql_listfields) && is_array($objimport->array_import_fieldshidden[0])) { // Loop on each hidden fields to add them into listfields/listvalues foreach ($objimport->array_import_fieldshidden[0] as $tmpkey => $tmpval) { if (!preg_match('/^' . preg_quote($alias, '/') . '\./', $tmpkey)) { @@ -1496,22 +1496,22 @@ class ModeleImports } $keyfieldcache = preg_replace('/^' . preg_quote($alias, '/') . '\./', '', $tmpkey); - if (in_array($keyfieldcache, $listfields)) { // avoid duplicates in insert + if (in_array($keyfieldcache, $sql_listfields)) { // avoid duplicates in insert continue; } elseif ($tmpval == 'user->id') { - $listfields[] = $keyfieldcache; - $listvalues[] = ((int) $user->id); + $sql_listfields[] = $keyfieldcache; // @phan-suppress-current-line SqlInjection + $sql_listvalues[] = ((int) $user->id); } elseif (preg_match('/^lastrowid-/', $tmpval)) { $tmp = explode('-', $tmpval); $lastinsertid = (isset($last_insert_id_array[$tmp[1]])) ? $last_insert_id_array[$tmp[1]] : 0; - $listfields[] = $keyfieldcache; - $listvalues[] = (int) $lastinsertid; + $sql_listfields[] = $keyfieldcache; // @phan-suppress-current-line SqlInjection + $sql_listvalues[] = (int) $lastinsertid; $keyfield = $keyfieldcache; - //print $tmpkey."-".$tmpval."-".$listfields."-".$listvalues."
";exit; + //print $tmpkey."-".$tmpval."-".$sql_listfields."-".$sql_listvalues."
";exit; } elseif (preg_match('/^const-/', $tmpval)) { $tmp = explode('-', $tmpval, 2); - $listfields[] = $keyfieldcache; - $listvalues[] = "'".$this->db->escape($tmp[1])."'"; + $sql_listfields[] = $keyfieldcache; // @phan-suppress-current-line SqlInjection + $sql_listvalues[] = "'".$this->db->escape($tmp[1])."'"; } elseif (preg_match('/^rule-/', $tmpval)) { // Example: rule-computeAmount, rule-computeDirection, ... $fieldname = $tmpkey; if (!empty($objimport->array_import_convertvalue[0][$fieldname])) { @@ -1534,14 +1534,14 @@ class ModeleImports $fieldname = $fieldArr[1]; } - // Set $listfields and $listvalues - $listfields[] = $fieldname; + // Set $sql_listfields and $sql_listvalues + $sql_listfields[] = $this->db->sanitize($fieldname); if ($type == 'int') { - $listvalues[] = (int) $res; + $sql_listvalues[] = (int) $res; } elseif ($type == 'double') { - $listvalues[] = (float) $res; + $sql_listvalues[] = (float) $res; } else { - $listvalues[] = "'".$this->db->escape($res)."'"; + $sql_listvalues[] = "'".$this->db->escape($res)."'"; } } else { $this->errors[$error]['type'] = 'CLASSERROR'; @@ -1561,13 +1561,13 @@ class ModeleImports } } } - //print 'listfields='.$listfields.'
listvalues='.$listvalues.'
'; + //print 'listfields='.$sql_listfields.'
listvalues='.$sql_listvalues.'
'; - // If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined + // If no error for this $alias/$tablename, we have a complete $sql_listfields and $sql_listvalues that are defined // so we can try to make the insert or update now. if (!$errorforthistable) { - //print "$alias/$tablename/$listfields/$listvalues
"; - if (!empty($listfields)) { + //print "$alias/$tablename/$sql_listfields/$sql_listvalues
"; + if (!empty($sql_listfields)) { $updatedone = false; $insertdone = false; $where = array(); @@ -1584,7 +1584,7 @@ class ModeleImports if (empty($lastinsertid)) { // No insert done yet for a parent table $sqlSelect = "SELECT ".$sanitizedfname." FROM ".$this->db->sanitize($tablename); - $data = array_combine($listfields, $listvalues); + $data = array_combine($sql_listfields, $sql_listvalues); $where = array(); // filters to forge SQL request $filters = array(); // filters to forge output error message foreach ($updatekeys as $key) { @@ -1611,7 +1611,7 @@ class ModeleImports $filters[] = $col." LIKE '%".$this->db->escape($this->db->escapeforlike($stringtosearch))."%'"; //var_dump($where[1]); // This provide a value for sql string inside a like } else { - $sanitizedvalue = $data[$keyfordata]; + $sanitizedvalue = $data[$keyfordata]; // @phan-suppress-current-line SqlInjection /* Not required, the value in $data[$key] seems already sanitized $type = $objimport->array_import_types[0][$key]['type'] ?? 'string'; if ($type == 'int') { @@ -1675,7 +1675,7 @@ class ModeleImports $keyfield = 'rowid'; } - $sqlSelect .= " WHERE ".$keyfield." = ".((int) $lastinsertid); + $sqlSelect .= " WHERE ".$this->db->sanitize($keyfield)." = ".((int) $lastinsertid); if (!empty($tablewithentity_cache[$tablename])) { $sqlSelect .= " AND entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")"; @@ -1701,26 +1701,26 @@ class ModeleImports if (!empty($lastinsertid)) { // We db escape social network field because he isn't in field creation - if (in_array("socialnetworks", $listfields)) { - $socialkey = array_search("socialnetworks", $listfields); - $tmpsql = $listvalues[$socialkey]; - $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + if (in_array("socialnetworks", $sql_listfields)) { + $socialkey = array_search("socialnetworks", $sql_listfields); + $tmpsql = $sql_listvalues[$socialkey]; + $sql_listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; } // Build SQL UPDATE request $sqlstart = "UPDATE ".$tablename; - $data = array_combine($listfields, $listvalues); - $set = array(); + $data = array_combine($sql_listfields, $sql_listvalues); + $sql_set = array(); foreach ($data as $key => $val) { - $set[] = $key." = ".$val; // $val was escaped/sanitized previously + $sql_set[] = $key." = ".$val; // $val was escaped/sanitized previously @phan-suppress-current-line SqlInjection } - $sqlstart .= " SET ".implode(', ', $set).", import_key = '".$this->db->escape($importid)."'"; + $sqlstart .= " SET ".implode(', ', $sql_set).", import_key = '".$this->db->escape($importid)."'"; if (empty($keyfield)) { $keyfield = 'rowid'; } - $sqlend = " WHERE ".$keyfield." = ".((int) $lastinsertid); + $sqlend = " WHERE ".$this->db->escape($keyfield)." = ".((int) $lastinsertid); if ($is_table_category_link && !empty($where)) { '@phan-var-force string[] $where'; @@ -1760,28 +1760,28 @@ class ModeleImports // Update not done, we do insert if (!$error && !$updatedone) { // We db escape social network field because he isn't in field creation - if (in_array("socialnetworks", $listfields)) { - $socialkey = array_search("socialnetworks", $listfields); - $tmpsql = $listvalues[$socialkey]; - $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; + if (in_array("socialnetworks", $sql_listfields)) { + $socialkey = array_search("socialnetworks", $sql_listfields); + $tmpsql = $sql_listvalues[$socialkey]; + $sql_listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'"; } // Build SQL INSERT request - $sqlstart = "INSERT INTO ".$tablename."(".implode(", ", $listfields).", import_key"; - $sqlend = ") VALUES(".implode(', ', $listvalues).", '".$this->db->escape($importid)."'"; + $sqlstart = "INSERT INTO ".$tablename."(".implode(", ", $sql_listfields).", import_key"; + $sqlend = ") VALUES(".implode(', ', $sql_listvalues).", '".$this->db->escape($importid)."'"; if (!empty($tablewithentity_cache[$tablename])) { $sqlstart .= ", entity"; - $sqlend .= ", ".$conf->entity; + $sqlend .= ", ".((int) $conf->entity); } if (!empty($objimport->array_import_tables_creator[0][$alias])) { - $sqlstart .= ", ".$objimport->array_import_tables_creator[0][$alias]; - $sqlend .= ", ".$user->id; + $sqlstart .= ", ".$this->db->sanitize($objimport->array_import_tables_creator[0][$alias]); + $sqlend .= ", ".((int) $user->id); } - $sql = $sqlstart.$sqlend.")"; - //dol_syslog("import_csv.modules", LOG_DEBUG); + $sql = $sqlstart.$sqlend.")"; + //dol_syslog("import_csv.modules", LOG_DEBUG); - // Run insert request - $resql = $this->db->query($sql); + // Run insert request + $resql = $this->db->query($sql); if ($resql) { if (!$is_table_category_link) { $last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that child tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr). diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index 8c740744a8b..f058c11fe18 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -8,6 +8,7 @@ * Copyright (C) 2020 Ahmad Jamaly Rabib * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2026 Charlene Benke + * Copyright (C) 2026 MDW * * 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 @@ -129,8 +130,8 @@ class modPropale extends DolibarrModules // Boxes $this->boxes = array( - 0=>array('file'=>'box_graph_propales_permonth.php', 'enabledbydefaulton'=>'Home'), - 1=>array('file'=>'box_propales.php', 'enabledbydefaulton'=>'Home'), + 0 => array('file' => 'box_graph_propales_permonth.php', 'enabledbydefaulton' => 'Home'), + 1 => array('file' => 'box_propales.php', 'enabledbydefaulton' => 'Home'), ); // Permissions @@ -212,11 +213,11 @@ class modPropale extends DolibarrModules $this->export_label[$r] = 'ProposalsAndProposalsLines'; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r] = array(array("propale", "export")); $this->export_fields_array[$r] = array( - 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 'ps.nom'=>'ParentCompany', 's.code_client'=>'CustomerCode', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'co.code'=>'CountryCode', 's.phone'=>'Phone', - 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 'c.rowid'=>"Id", 'c.ref'=>"Ref", 'c.ref_client'=>"RefCustomer", - 'c.fk_soc'=>"IdCompany", 'c.datec'=>"DateCreation", 'c.datep'=>"DatePropal", 'c.fin_validite'=>"DateEndPropal", - 'c.total_ht'=>"TotalHT", 'c.total_ttc'=>"TotalTTC", - 'cir.label'=>'Source', + 's.rowid' => "IdCompany", 's.nom' => 'CompanyName', 'ps.nom' => 'ParentCompany', 's.code_client' => 'CustomerCode', 's.address' => 'Address', 's.zip' => 'Zip', 's.town' => 'Town', 'co.code' => 'CountryCode', 's.phone' => 'Phone', + 's.siren' => 'ProfId1', 's.siret' => 'ProfId2', 's.ape' => 'ProfId3', 's.idprof4' => 'ProfId4', 'c.rowid' => "Id", 'c.ref' => "Ref", 'c.ref_client' => "RefCustomer", + 'c.fk_soc' => "IdCompany", 'c.datec' => "DateCreation", 'c.datep' => "DatePropal", 'c.fin_validite' => "DateEndPropal", + 'c.total_ht' => "TotalHT", 'c.total_ttc' => "TotalTTC", + 'cir.label' => 'Source', ); if (isModEnabled("multicurrency")) { $this->export_fields_array[$r]['c.multicurrency_code'] = 'Currency'; @@ -226,18 +227,18 @@ class modPropale extends DolibarrModules $this->export_fields_array[$r]['c.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC'; } $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array( - 'c.fk_statut'=>'Status', 'c.note_public'=>"NotePublic", 'c.note_private'=>"NotePrivate", 'c.date_livraison'=>'DeliveryDate', - 'c.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', - 'c.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin')); + 'c.fk_statut' => 'Status', 'c.note_public' => "NotePublic", 'c.note_private' => "NotePrivate", 'c.date_livraison' => 'DeliveryDate', + 'c.fk_user_author' => 'CreatedById', 'uc.login' => 'CreatedByLogin', + 'c.fk_user_valid' => 'ValidatedById', 'uv.login' => 'ValidatedByLogin')); if (isModEnabled("project")) { $this->export_fields_array[$r]['pj.ref'] = 'ProjectRef'; } $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array( - 'cd.rowid'=>'LineId', 'cd.description'=>"LineDescription", 'cd.product_type'=>'TypeOfLineServiceOrProduct', - 'cd.tva_tx'=>"LineVATRate", 'cd.qty'=>"LineQty", 'cd.total_ht'=>"LineTotalHT", 'cd.total_tva'=>"LineTotalVAT", 'cd.total_ttc'=>"LineTotalTTC", + 'cd.rowid' => 'LineId', 'cd.description' => "LineDescription", 'cd.product_type' => 'TypeOfLineServiceOrProduct', + 'cd.tva_tx' => "LineVATRate", 'cd.qty' => "LineQty", 'cd.total_ht' => "LineTotalHT", 'cd.total_tva' => "LineTotalVAT", 'cd.total_ttc' => "LineTotalTTC", )); $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array( - 'p.rowid'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel' + 'p.rowid' => 'ProductId', 'p.ref' => 'ProductRef', 'p.label' => 'ProductLabel' )); // Add multicompany field if (getDolGlobalString('MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED')) { @@ -254,27 +255,27 @@ class modPropale extends DolibarrModules // 'cd.total_tva'=>"Numeric",'cd.total_ttc'=>"Numeric",'p.rowid'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text' //); $this->export_TypeFields_array[$r] = array( - 's.nom'=>'Text', 'ps.nom'=>'Text', 's.code_client'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'co.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', - 's.ape'=>'Text', 's.idprof4'=>'Text', 'c.ref'=>"Text", 'c.ref_client'=>"Text", 'c.datec'=>"Date", 'c.datep'=>"Date", 'c.fin_validite'=>"Date", - 'c.total_ht'=>"Numeric", 'c.total_ttc'=>"Numeric", 'c.fk_statut'=>'Status', 'c.note_public'=>"Text", 'c.note_private'=>"Text", 'c.date_livraison'=>'Date', - 'pj.ref'=>'Text', 'cd.description'=>"Text", 'cd.product_type'=>'Boolean', 'cd.tva_tx'=>"Numeric", 'cd.qty'=>"Numeric", 'cd.total_ht'=>"Numeric", - 'cd.total_tva'=>"Numeric", 'cd.total_ttc'=>"Numeric", 'p.ref'=>'Text', 'p.label'=>'Text', - 'c.entity'=>'List:entity:label:rowid', - 'cir.label'=>'Text', + 's.nom' => 'Text', 'ps.nom' => 'Text', 's.code_client' => 'Text', 's.address' => 'Text', 's.zip' => 'Text', 's.town' => 'Text', 'co.code' => 'Text', 's.phone' => 'Text', 's.siren' => 'Text', 's.siret' => 'Text', + 's.ape' => 'Text', 's.idprof4' => 'Text', 'c.ref' => "Text", 'c.ref_client' => "Text", 'c.datec' => "Date", 'c.datep' => "Date", 'c.fin_validite' => "Date", + 'c.total_ht' => "Numeric", 'c.total_ttc' => "Numeric", 'c.fk_statut' => 'Status', 'c.note_public' => "Text", 'c.note_private' => "Text", 'c.date_livraison' => 'Date', + 'pj.ref' => 'Text', 'cd.description' => "Text", 'cd.product_type' => 'Boolean', 'cd.tva_tx' => "Numeric", 'cd.qty' => "Numeric", 'cd.total_ht' => "Numeric", + 'cd.total_tva' => "Numeric", 'cd.total_ttc' => "Numeric", 'p.ref' => 'Text', 'p.label' => 'Text', + 'c.entity' => 'List:entity:label:rowid', + 'cir.label' => 'Text', ); $this->export_entities_array[$r] = array( - 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.code_client'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'co.code'=>'company', 's.phone'=>'company', - 's.siren'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.siret'=>'company', 'c.rowid'=>"propal", 'c.ref'=>"propal", 'c.ref_client'=>"propal", - 'c.fk_soc'=>"propal", 'c.datec'=>"propal", 'c.datep'=>"propal", 'c.fin_validite'=>"propal", 'c.total_ht'=>"propal", - 'c.total_ttc'=>"propal", 'c.fk_statut'=>"propal", 'c.note_public'=>"propal", 'c.note_private'=>"propal", 'c.date_livraison'=>"propal", - 'c.fk_user_author'=>'user', 'uc.login'=>'user', - 'c.fk_user_valid'=>'user', 'uv.login'=>'user', - 'pj.ref'=>'project', - 'cd.rowid'=>'propal_line', - 'cd.description'=>"propal_line", 'cd.product_type'=>'propal_line', 'cd.tva_tx'=>"propal_line", 'cd.qty'=>"propal_line", - 'cd.total_ht'=>"propal_line", 'cd.total_tva'=>"propal_line", 'cd.total_ttc'=>"propal_line", 'p.rowid'=>'product', 'p.ref'=>'product', 'p.label'=>'product' + 's.rowid' => "company", 's.nom' => 'company', 'ps.nom' => 'company', 's.code_client' => 'company', 's.address' => 'company', 's.zip' => 'company', 's.town' => 'company', 'co.code' => 'company', 's.phone' => 'company', + 's.siren' => 'company', 's.ape' => 'company', 's.idprof4' => 'company', 's.siret' => 'company', 'c.rowid' => "propal", 'c.ref' => "propal", 'c.ref_client' => "propal", + 'c.fk_soc' => "propal", 'c.datec' => "propal", 'c.datep' => "propal", 'c.fin_validite' => "propal", 'c.total_ht' => "propal", + 'c.total_ttc' => "propal", 'c.fk_statut' => "propal", 'c.note_public' => "propal", 'c.note_private' => "propal", 'c.date_livraison' => "propal", + 'c.fk_user_author' => 'user', 'uc.login' => 'user', + 'c.fk_user_valid' => 'user', 'uv.login' => 'user', + 'pj.ref' => 'project', + 'cd.rowid' => 'propal_line', + 'cd.description' => "propal_line", 'cd.product_type' => 'propal_line', 'cd.tva_tx' => "propal_line", 'cd.qty' => "propal_line", + 'cd.total_ht' => "propal_line", 'cd.total_tva' => "propal_line", 'cd.total_ttc' => "propal_line", 'p.rowid' => 'product', 'p.ref' => 'product', 'p.label' => 'product' ); - $this->export_dependencies_array[$r] = array('propal_line'=>'cd.rowid', 'product'=>'cd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $this->export_dependencies_array[$r] = array('propal_line' => 'cd.rowid', 'product' => 'cd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them $keyforselect = 'propal'; $keyforelement = 'propal'; $keyforaliasextra = 'extra'; @@ -313,7 +314,7 @@ class modPropale extends DolibarrModules $this->export_sql_end[$r] .= ' WHERE c.fk_soc = s.rowid AND c.rowid = cd.fk_propal'; $this->export_sql_end[$r] .= ' AND c.entity IN ('.getEntity('propal').')'; if (!empty($user) && !$user->hasRight('societe', 'client', 'voir')) { - $this->export_sql_end[$r] .= ' AND sc.fk_user = '.(empty($user) ? 0 : $user->id); + $this->export_sql_end[$r] .= ' AND sc.fk_user = '.(empty($user) ? 0 : ((int) $user->id)); } $parameters = array(); $hookmanager->executeHooks('printExportWhere', $parameters, $this); // Note that $action and $object may have been modified by hook @@ -329,7 +330,7 @@ class modPropale extends DolibarrModules $this->import_icon[$r] = $this->picto; $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r] = array('c' => MAIN_DB_PREFIX.'propal', 'extra' => MAIN_DB_PREFIX.'propal_extrafields'); - $this->import_tables_creator_array[$r] = array('c'=>'fk_user_author'); // Fields to store import user id + $this->import_tables_creator_array[$r] = array('c' => 'fk_user_author'); // Fields to store import user id $this->import_fields_array[$r] = array( 'c.ref' => 'Ref*', 'c.ref_client' => 'RefCustomer', @@ -354,7 +355,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'propal' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'propal' AND entity IN (0, ".((int) $conf->entity).")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -388,14 +389,14 @@ class modPropale extends DolibarrModules 'c.multicurrency_total_ttc' => '0' ]; $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); - $this->import_updatekeys_array[$r] = array('c.ref'=>'Ref'); + $this->import_updatekeys_array[$r] = array('c.ref' => 'Ref'); $this->import_convertvalue_array[$r] = array( 'c.ref' => array( - 'rule'=>'getrefifauto', - 'class'=>(!getDolGlobalString('PROPALE_ADDON') ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON), - 'path'=>"/core/modules/propale/".(!getDolGlobalString('PROPALE_ADDON') ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON).'.php', - 'classobject'=>'Propal', - 'pathobject'=>'/comm/propal/class/propal.class.php', + 'rule' => 'getrefifauto', + 'class' => (!getDolGlobalString('PROPALE_ADDON') ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON), + 'path' => "/core/modules/propale/".(!getDolGlobalString('PROPALE_ADDON') ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON).'.php', + 'classobject' => 'Propal', + 'pathobject' => '/comm/propal/class/propal.class.php', ), 'c.fk_soc' => array( 'rule' => 'fetchidfromref', @@ -443,7 +444,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'propaldet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'propaldet' AND entity IN (0, ".((int) $conf->entity).")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -483,10 +484,10 @@ class modPropale extends DolibarrModules $this->import_updatekeys_array[$r] = array('cd.fk_propal' => 'Quotation Id', 'cd.fk_product' => 'Product Id'); $this->import_convertvalue_array[$r] = array( 'cd.fk_propal' => array( - 'rule'=>'fetchidfromref', - 'file'=>'/comm/propal/class/propal.class.php', - 'class'=>'Propal', - 'method'=>'fetch' + 'rule' => 'fetchidfromref', + 'file' => '/comm/propal/class/propal.class.php', + 'class' => 'Propal', + 'method' => 'fetch' ) ); } diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 625888f4662..9dde26b1773 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -649,20 +649,20 @@ if ($this->status == 0 && $tmppermtoedit && $action != 'selectlines') { ) ) { $accountancy_category_asset = getDolGlobalString('ASSET_ACCOUNTANCY_CATEGORY'); - $filters = array(); + $sanitized_filters = array(); if (!empty($product_static->accountancy_code_buy)) { - $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy) . "'"; + $sanitized_filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy) . "'"; } if (!empty($product_static->accountancy_code_buy_intra)) { - $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_intra) . "'"; + $sanitized_filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_intra) . "'"; } if (!empty($product_static->accountancy_code_buy_export)) { - $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_export) . "'"; + $sanitized_filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_export) . "'"; } $sql = "SELECT COUNT(*) AS found"; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account"; $sql .= " WHERE pcg_type = '" . $this->db->escape($conf->global->ASSET_ACCOUNTANCY_CATEGORY) . "'"; - $sql .= " AND (" . implode(' OR ', $filters). ")"; + $sql .= " AND (" . implode(' OR ', $sanitized_filters). ")"; $resql_asset = $this->db->query($sql); if (!$resql_asset) { print 'Error SQL: ' . $this->db->lasterror(); diff --git a/htdocs/expensereport/class/expensereportline.class.php b/htdocs/expensereport/class/expensereportline.class.php index 4cbeacb4a7e..08b593dc9b0 100644 --- a/htdocs/expensereport/class/expensereportline.class.php +++ b/htdocs/expensereport/class/expensereportline.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (c) 2018-2024 Frédéric France * Copyright (C) 2016-2020 Ferran Marcet - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024 William Mead * @@ -349,7 +349,7 @@ class ExpenseReportLine extends CommonObjectLine $sql .= ' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)'; $sql .= " VALUES (".$this->db->escape((string) $this->fk_expensereport).","; $sql .= " ".((int) $this->fk_c_type_fees).","; - $sql .= " ".((int) (!empty($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : ((!empty($this->fk_projet) && $this->fk_projet > 0) ? $this->fk_projet : 'null')).","; + $sql .= " ".((int) (!empty($this->fk_project) && $this->fk_project > 0) ? ((int) $this->fk_project) : ((!empty($this->fk_projet) && $this->fk_projet > 0) ? ((int) $this->fk_projet) : 'null')).","; $sql .= " ".((float) $this->vatrate).","; $sql .= " '".$this->db->escape(empty($this->vat_src_code) ? '' : $this->vat_src_code)."',"; $sql .= " ".((float) price2num($this->localtax1_tx)).","; @@ -503,7 +503,7 @@ class ExpenseReportLine extends CommonObjectLine } else { $sql .= ", fk_projet=null"; } - $sql .= " WHERE rowid = ".((int) ($this->rowid ? $this->rowid : $this->id)); + $sql .= " WHERE rowid = ".((int) ($this->rowid ? $this->rowid : ((int) $this->id))); dol_syslog("ExpenseReportLine::update"); diff --git a/htdocs/fichinter/card-rec.php b/htdocs/fichinter/card-rec.php index 419fd2cada2..02ff12a1a86 100644 --- a/htdocs/fichinter/card-rec.php +++ b/htdocs/fichinter/card-rec.php @@ -748,7 +748,7 @@ if ($action == 'create') { $num = count($object->lines); $i = 0; while ($i < $num) { - $type =0; + $type = 0; // Show product and description if (isset($object->lines[$i]->product_type)) { $type = $object->lines[$i]->product_type; @@ -808,7 +808,7 @@ if ($action == 'create') { $sql .= " , ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; - $sql .= " AND f.entity = ".$conf->entity; + $sql .= " AND f.entity = ".((int) $conf->entity); if (!empty($socid)) { $sql .= " AND s.rowid = ".((int) $socid); } diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 7f720491c5b..647ff014b18 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -42,7 +42,8 @@ require_once DOL_DOCUMENT_ROOT.'/subtotals/class/commonsubtotal.class.php'; */ class Fichinter extends CommonObject { - use CommonSignedObject, CommonSubtotal; + use CommonSignedObject; + use CommonSubtotal; /** * @var string Prefix to check for any trigger code of any business class to prevent bad value for trigger code. @@ -351,7 +352,7 @@ class Fichinter extends CommonObject $sql .= ", note_public"; $sql .= ") "; $sql .= " VALUES ("; - $sql .= $this->socid; + $sql .= ((int) $this->socid); $sql .= ", '".$this->db->idate($now)."'"; $sql .= ", '".$this->db->escape($this->ref)."'"; $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null"); @@ -697,7 +698,7 @@ class Fichinter extends CommonObject $this->error = $this->db->lasterror(); } $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; diff --git a/htdocs/fourn/class/fournisseur.orderline.class.php b/htdocs/fourn/class/fournisseur.orderline.class.php index 9603c0f03a7..5054945b327 100644 --- a/htdocs/fourn/class/fournisseur.orderline.class.php +++ b/htdocs/fourn/class/fournisseur.orderline.class.php @@ -14,7 +14,7 @@ * Copyright (C) 2021 Josep Lluís Amador * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2024 Solution Libre SAS - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024 William Mead * Copyright (C) 2026 Pierre Ardoin * @@ -354,11 +354,11 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit,"; $sql .= " fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc,"; $sql .= " fk_parent_line)"; - $sql .= " VALUES (".$this->fk_commande.", '".$this->db->escape($this->label)."','".$this->db->escape($this->desc)."',"; + $sql .= " VALUES (".((int) $this->fk_commande).", '".$this->db->escape($this->label)."','".$this->db->escape($this->desc)."',"; $sql .= " ".($this->date_start ? "'".$this->db->idate($this->date_start)."'" : "null").","; $sql .= " ".($this->date_end ? "'".$this->db->idate($this->date_end)."'" : "null").","; if ($this->fk_product) { - $sql .= $this->fk_product.","; + $sql .= ((int) $this->fk_product).","; } else { $sql .= "null,"; } @@ -385,7 +385,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= ", ".($this->multicurrency_total_ht ? price2num($this->multicurrency_total_ht) : '0'); $sql .= ", ".($this->multicurrency_total_tva ? price2num($this->multicurrency_total_tva) : '0'); $sql .= ", ".($this->multicurrency_total_ttc ? price2num($this->multicurrency_total_ttc) : '0'); - $sql .= ", ".((!empty($this->fk_parent_line) && $this->fk_parent_line > 0) ? $this->fk_parent_line : 'null'); + $sql .= ", ".((!empty($this->fk_parent_line) && $this->fk_parent_line > 0) ? ((int) $this->fk_parent_line) : 'null'); $sql .= ")"; dol_syslog(get_class($this)."::insert", LOG_DEBUG); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index cda2291ece2..a431ac1e50d 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -561,7 +561,7 @@ class ProductFournisseur extends Product $sql .= " barcode = ".(empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").","; $sql .= " fk_barcode_type = ".(empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape((string) $fk_barcode_type)."'"); if (getDolGlobalString('PRODUCT_USE_SUPPLIER_PACKAGING')) { - $sql .= ", packaging = ".(empty($packaging) ? 1 : $packaging); + $sql .= ", packaging = ".(empty($packaging) ? 1 : ((float) $packaging)); } $sql .= " WHERE rowid = ".((int) $this->product_fourn_price_id); @@ -648,7 +648,7 @@ class ProductFournisseur extends Product $sql .= " ".((int) $availability).","; $sql .= " ".($newdefaultvatcode ? "'".$this->db->escape($newdefaultvatcode)."'" : "null").","; $sql .= " ".((int) $newnpr).","; - $sql .= $conf->entity.","; + $sql .= ((int) $conf->entity).","; $sql .= ($delivery_time_days != '' ? ((int) $delivery_time_days) : 'null').","; $sql .= (empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").","; $sql .= (empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").","; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 03185f6e11d..56c4c56358f 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -10,7 +10,7 @@ * Copyright (C) 2018-2022 Charlene Benke * Copyright (C) 2019 Nicolas Zabouri * Copyright (C) 2021-2026 Alexandre Spangaro - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -474,7 +474,7 @@ if (empty($reshook)) { $sql .= ", fk_target"; $sql .= ", targettype"; $sql .= ") VALUES ("; - $sql .= $id_order; + $sql .= ((int) $id_order); $sql .= ", '".$db->escape($objecttmp->origin)."'"; $sql .= ", ".((int) $objecttmp->id); $sql .= ", '".$db->escape($objecttmp->element)."'"; diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index 04ff7f194b0..de3c60be078 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -295,10 +295,10 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $values = $db->fetch_array($resql); if (is_array($values)) { $i = 0; - $createsql = $values[1]; + $createsql = $values[1]; // @phan-suppress-current-line SqlInjection $reg = array(); while (preg_match('/CONSTRAINT `(0_[0-9a-zA-Z]+|[_0-9a-zA-Z]+_ibfk_[0-9]+)`/i', $createsql, $reg) && $i < 100) { - $sqldrop = "ALTER TABLE ".$val." DROP FOREIGN KEY ".$reg[1]; + $sqldrop = "ALTER TABLE ".$db->sanitize($val)." DROP FOREIGN KEY ".$db->sanitize($reg[1]); $resqldrop = $db->query($sqldrop); if ($resqldrop) { print ''.$sqldrop.";\n"; @@ -335,7 +335,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $filelist = array(); $i = 0; $ok = 0; - $from = '^'.preg_quote($newversionfrom, '/'); + $from_regex = '^'.preg_quote($newversionfrom, '/'); $to = preg_quote($newversionto.'.sql', '/').'$'; // Get files list @@ -354,7 +354,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ // Define which file to run foreach ($filesindir as $file) { - if (preg_match('/'.$from.'\-/i', $file)) { + if (preg_match('/'.$from_regex.'\-/i', $file)) { $filelist[] = $file; } elseif (preg_match('/\-'.$to.'/i', $file)) { // First test may be false if we migrate from x.y.* to x.y.* $filelist[] = $file; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index efcb01fef93..00c40a9761a 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -208,37 +208,37 @@ class MyObject extends CommonObject //BEGIN MODULEBUILDER LINES // If this object has a subtable with lines - /** - * @var string Name of subtable line - */ - public $table_element_line = 'mymodule_myobjectline'; + /** + * @var string Name of subtable line + */ + public $table_element_line = 'mymodule_myobjectline'; - /** - * @var string Field with ID of parent key if this object has a parent - */ - public $fk_element = 'fk_myobject'; + /** + * @var string Field with ID of parent key if this object has a parent + */ + public $fk_element = 'fk_myobject'; - /** - * @var string Name of subtable class that manage subtable lines - */ - public $class_element_line = 'MyObjectline'; + /** + * @var string Name of subtable class that manage subtable lines + */ + public $class_element_line = 'MyObjectline'; - /** - * @var array|string> List of child tables. To test if we can delete object. - */ - protected $childtables = array('mychildtable' => array('name'=>'MyObject', 'fk_element'=>'fk_myobject')); + /** + * @var array|string> List of child tables. To test if we can delete object. + */ + protected $childtables = array('mychildtable' => array('name' => 'MyObject', 'fk_element' => 'fk_myobject')); - /** - * @var string[] List of child tables. To know object to delete on cascade. - * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will - * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object - */ - protected $childtablesoncascade = array('mymodule_myobjectdet'); + /** + * @var string[] List of child tables. To know object to delete on cascade. + * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + */ + protected $childtablesoncascade = array('mymodule_myobjectdet'); - /** - * @var MyObjectLine[] Array of subtable lines - */ - public $lines = array(); + /** + * @var MyObjectLine[] Array of subtable lines + */ + public $lines = array(); //END MODULEBUILDER LINES @@ -332,8 +332,9 @@ class MyObject extends CommonObject } // get lines so they will be clone - foreach ($this->lines as $line) + foreach ($this->lines as $line) { $line->fetch_optionals(); + } //END MODULEBUILDER LINES // Reset some properties unset($object->id); @@ -470,7 +471,7 @@ class MyObject extends CommonObject $sql .= " WHERE t.entity IN (".getEntity($this->element).")"; } elseif (preg_match('/^\w+@\w+$/', (string) $this->ismultientitymanaged)) { $tmparray = explode('@', (string) $this->ismultientitymanaged); - $sql .= " LEFT JOIN ".$this->db->prefix().$tmparray[1]." as pt ON t.".$this->db->sanitize($tmparray[0])." = pt.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix().$this->db->sanitize($tmparray[1])." as pt ON t.".$this->db->sanitize($tmparray[0])." = pt.rowid"; $sql .= " WHERE pt.entity IN (".getEntity($this->element).")"; } else { $sql .= " WHERE 1 = 1"; @@ -649,14 +650,14 @@ class MyObject extends CommonObject if (preg_match('/^[\(]?PROV/i', $this->ref)) { // Now we rename also files into index $sql = 'UPDATE '.$this->db->prefix()."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'myobject/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->error = $this->db->lasterror(); } $sql = 'UPDATE '.$this->db->prefix()."ecm_files set filepath = 'myobject/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 7d8bad82a3a..014905c9696 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -340,7 +340,7 @@ if (!empty($object->ismultientitymanaged) && (int) $object->ismultientitymanaged $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")"; } elseif (preg_match('/^\w+@\w+$/', (string) $object->ismultientitymanaged)) { $tmparray = explode('@', (string) $object->ismultientitymanaged); - $sql .= " LEFT JOIN ".$object->db->prefix().$tmparray[1]." as pt ON t.".$db->sanitize($tmparray[0])." = pt.rowid"; + $sql .= " LEFT JOIN ".$object->db->prefix().$db->sanitize($tmparray[1])." as pt ON t.".$db->sanitize($tmparray[0])." = pt.rowid"; $sql .= " WHERE pt.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")"; } else { $sql .= " WHERE 1 = 1"; diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index 5c18f038180..79c31bbc9c8 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -1188,14 +1188,14 @@ class Mo extends CommonObject if (preg_match('/^[\(]?PROV/i', $this->ref)) { // Now we rename also files into index $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'mrp/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->error = $this->db->lasterror(); } $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'mrp/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $sql .= " WHERE filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index af0f1aae53a..947fb6d5033 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -184,7 +184,7 @@ if ($action == 'search') { $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON p.rowid = cp.fk_product'; if (getDolGlobalInt('MAIN_MULTILANGS')) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND lang='".($current_lang)."'"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND lang='".$db->escape($current_lang)."'"; } $sql .= ' WHERE p.entity IN ('.getEntity('product').')'; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index a19f1e194f7..312793fe0f6 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1334,7 +1334,7 @@ if ($action == 'create' && $permissiontoadd) { } // Note Public - $htmltext =''; + $htmltext = ''; print ''; print ''; print $form->textwithpicto($langs->trans('NotePublic'), $htmltext); @@ -2585,7 +2585,7 @@ if ($action == 'create' && $permissiontoadd) { $sql .= ', p.description as product_desc'; $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as ed"; $sql .= ", ".MAIN_DB_PREFIX."reception as e"; - $sql .= ", ".MAIN_DB_PREFIX.(($origin == 'supplier_order') ? 'commande_fournisseur' : $origin)."det as obj"; + $sql .= ", ".MAIN_DB_PREFIX.(($origin == 'supplier_order') ? 'commande_fournisseur' : $origin)."det as obj"; // @phan-suppress-current-line SqlInjection $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON obj.fk_product = p.rowid"; $sql .= " WHERE e.entity IN (".getEntity('reception').")"; $sql .= " AND obj.fk_commande = ".((int) $origin_id); diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 38797ac01dd..df33ae19ed8 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2019 Cedric Ancelin * Copyright (C) 2020-2025 Frédéric France * Copyright (C) 2023 Alexandre Janniaux - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024 Jon Bendtsen * Copyright (C) 2025 William Mead * Copyright (C) 2025 Charlene Benke @@ -1343,7 +1343,7 @@ class Thirdparties extends DolibarrApi throw new RestException(405, 'Discount not owned by this thirdpartie'); } - if ( price2num((float) $amount_ttc_1 + (float) $amount_ttc_2) != $discount->amount_ttc) { + if (price2num((float) $amount_ttc_1 + (float) $amount_ttc_2) != $discount->amount_ttc) { throw new RestException(405, 'Sum of the 2 discounts is different that the original discount'); } if ($discount->fk_facture_line) { @@ -1433,7 +1433,7 @@ class Thirdparties extends DolibarrApi $sql = "SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line"; $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f"; - $sql .= " WHERE re.rowid IN (".$this->db->sanitize(((int) $newid1).",".((int) $newid2)).") AND f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id); + $sql .= " WHERE re.rowid IN (".((int) $newid1).",".((int) $newid2).") AND f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id); $sql .= $this->db->order("f.type", "ASC"); @@ -2391,7 +2391,7 @@ class Thirdparties extends DolibarrApi throw new RestException(403); } - $sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '".$this->db->escape($site)."'"; + $sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'"; $result = $this->db->query($sql); // We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one. @@ -2553,7 +2553,7 @@ class Thirdparties extends DolibarrApi throw new RestException(403); } - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '".$this->db->escape($site)."'"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'"; $result = $this->db->query($sql); if ($result && $this->db->num_rows($result) == 0) { diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index cb41cfd75e0..e78cebe6d86 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -673,10 +673,10 @@ if (empty($reshook)) { if (empty($newcu)) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account"; - $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity; + $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".((int) $conf->entity); } else { $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX."societe_account"; - $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity; // Keep the = here for entity. Only 1 record must be modified ! + $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".((int) $conf->entity); // Keep the = here for entity. Only 1 record must be modified ! } $resql = $db->query($sql); @@ -699,7 +699,7 @@ if (empty($reshook)) { } else { $sql = 'UPDATE '.MAIN_DB_PREFIX."societe_account"; $sql .= " SET key_account = '".$db->escape($newcu)."', site_account = '".$db->escape($tmpsite_account)."'"; - $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified ! + $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".((int) $conf->entity); // Keep = here for entity. Only 1 record must be modified ! $resql = $db->query($sql); } } @@ -744,7 +744,7 @@ if (empty($reshook)) { if (empty($newsup)) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token WHERE fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".((int) $conf->entity); // TODO Add site and site_account on oauth_token table - //$sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($site_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($service)."' AND entity = ".$conf->entity; + //$sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($site_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($service)."' AND entity = ".((int) $conf->entity); } else { try { $stripesup = \Stripe\Account::retrieve($newsup); @@ -753,9 +753,9 @@ if (empty($reshook)) { $tokenstring['type'] = $stripesup->type; $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token"; $sql .= " SET tokenstring = '".$db->escape(json_encode($tokenstring))."'"; - $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified ! + $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".((int) $conf->entity); // Keep = here for entity. Only 1 record must be modified ! // TODO Add site and site_account on oauth_token table - $sql .= " WHERE fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified ! + $sql .= " WHERE fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".((int) $conf->entity); // Keep = here for entity. Only 1 record must be modified ! } catch (Exception $e) { $error++; setEventMessages($e->getMessage(), null, 'errors'); diff --git a/htdocs/webportal/class/html.formwebportal.class.php b/htdocs/webportal/class/html.formwebportal.class.php index 8bd2532108e..c57c0b3281a 100644 --- a/htdocs/webportal/class/html.formwebportal.class.php +++ b/htdocs/webportal/class/html.formwebportal.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2023-2024 Laurent Destailleur * Copyright (C) 2023-2024 Lionel Vessiller * Copyright (C) 2023-2024 Patrice Andreani - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2026 MDW * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2026 Charlene Benke * @@ -965,7 +965,7 @@ class FormWebPortal extends Form } $sql = "SELECT " . $this->db->sanitize($keyList); - $sql .= ' FROM ' . $this->db->prefix() . $InfoFieldList[0]; + $sql .= ' FROM ' . $this->db->prefix() . $this->db->sanitize($InfoFieldList[0]); if (strpos($InfoFieldList[4], 'extra') !== false) { $sql .= ' as main'; } @@ -1078,7 +1078,7 @@ class FormWebPortal extends Form $sql .= ' as main'; } // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'"; - // $sql.= ' AND entity = '.$conf->entity; + // $sql.= ' AND entity = '.((int) $conf->entity); dol_syslog(__METHOD__ . ' type=chkbxlst', LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/test/phpunit/CodingPhpTest.php b/test/phpunit/CodingPhpTest.php index 01d385aab51..5ed93dcd9c0 100644 --- a/test/phpunit/CodingPhpTest.php +++ b/test/phpunit/CodingPhpTest.php @@ -616,15 +616,15 @@ class CodingPhpTest extends CommonClassTest // Checks with IN - // Check string ' IN (".xxx' or ' IN (\'.xxx' with xxx that is not '$this->db->sanitize' and not '$db->sanitize'. It means we forgot a db->sanitize when forging a sql request. + // Check string ' IN (".xxx' or ' IN (\'.xxx' with xxx that is not '$this->db->sanitize' and not '$db->sanitize' and without int or float cast. It means we forgot a db->sanitize when forging a sql request. $ok = true; $lines = array(); $matches = array(); - preg_match_all('/\s+IN\s*\([\'"]\s*\.\s*(.........)(.*)/i', $filecontent, $matches, PREG_SET_ORDER); + preg_match_all('/\s+IN\s*\([\'"]\s*\.\s*((?![(]*(float|int)).........)(.*)/i', $filecontent, $matches, PREG_SET_ORDER); foreach ($matches as $key => $val) { //var_dump($val); if (!in_array($val[1], array('$sanitize', '$db->sani', '$this->db', 'getEntity', 'WON\',\'L', 'self::STA', 'Commande:', 'CommandeF', 'Entrepot:', 'Facture::', 'FactureFo', 'ExpenseRe', 'Societe::', 'Ticket::S'))) { - $lines[] = self::reportAndGetLine($val[1].$val[2], $filecontent, $report_filepath, "NotSanitizedString in IN/NOT IN sql query `{$val[1]}{$val[2]}...`)"); + $lines[] = self::reportAndGetLine($val[1].$val[2], $filecontent, $report_filepath, "NotSanitizedString '${val[1]}' in IN/NOT IN sql query `{$val[1]}{$val[2]}...`)"); $ok = false; // break; // Not breaking, report all lines }