diff --git a/dev/build/generate_filelist_xml.php b/dev/build/generate_filelist_xml.php index 7c1fb1d5a30..f73bdadd47b 100755 --- a/dev/build/generate_filelist_xml.php +++ b/dev/build/generate_filelist_xml.php @@ -115,7 +115,7 @@ while ($i < $argc) { $includeconstants[$tmp[0]][$tmp[1]] = $tmp[2]; } if (!empty($result["buildzip"])) { - $buildzip = 1; + $buildzip = $result["buildzip"]; } $i++; } @@ -134,7 +134,7 @@ $savrelease = $release; $tmpver = explode('-', $release, 2); if ($tmpver[0] == 'auto') { $release = DOL_VERSION; - if (!empty($tmpver[1]) && $tmpver[0] == 'auto') { + if (!empty($tmpver[1])) { $release .= '-'.$tmpver[1]; } } @@ -419,12 +419,12 @@ foreach ($arrayofunalterablefiles as $entry) { exit(1); } if ($newdir != $dir) { - if ($needtoclose) { - if ($release) { - fputs($fp, ' '."\n"); - } - $needtoclose = 0; + //if ($needtoclose) { + if ($release) { + fputs($fp, ' '."\n"); } + $needtoclose = 0; + //} if ($release) { fputs($fp, ' '."\n"); } diff --git a/dev/build/makepack-dolibarr.php b/dev/build/makepack-dolibarr.php index 026b0235140..7ebbd98fbe0 100755 --- a/dev/build/makepack-dolibarr.php +++ b/dev/build/makepack-dolibarr.php @@ -230,6 +230,8 @@ if (preg_match("/define\('DOL_VERSION',\s*'([\d\.a-z\-]+)'\)/i", $filefuncConten $PROJVERSION = $matches[1]; } if (empty($PROJVERSION)) { + $DOL_MAJOR_VERSION = 'notfound'; + $DOL_MINOR_VERSION = 'notfound'; if (preg_match("/define\('DOL_MAJOR_VERSION',\s*'([\d\.a-z\-]+)'\)/i", $filefuncContent, $matches)) { $DOL_MAJOR_VERSION = $matches[1]; } @@ -269,7 +271,7 @@ if (strpos($newbuild, '-') === false) { $newbuild .= '-0.4'; // finale (fedora) } $REL1 = preg_replace('/-.*$/', '', $newbuild); -if ($RPMSUBVERSION === 'auto') { +if ($RPMSUBVERSION === 'auto') { // @phpstan-ignore-line $RPMSUBVERSION = preg_replace('/^.*-/', '', $newbuild); } $FILENAMETGZ2 = "$PROJECT-$MAJOR.$MINOR.$REL1"; @@ -314,10 +316,10 @@ for ($i = 1; $i < $argc; $i++) { } // Force output dir if env vars are defined -if ($ENVDESTIBETARC && preg_match('/[a-z]/i', $BUILD)) { +if ($ENVDESTIBETARC && preg_match('/[a-z]/i', $BUILD)) { // @phpstan-ignore-line $DESTI = $ENVDESTIBETARC; } -if ($ENVDESTISTABLE && preg_match('/^[0-9]+$/', $BUILD)) { +if ($ENVDESTISTABLE && preg_match('/^[0-9]+$/', $BUILD)) { // @phpstan-ignore-line $DESTI = $ENVDESTISTABLE; } @@ -349,12 +351,12 @@ if ($target) { $targetUpper = strtoupper($target); if ($targetUpper === 'ALL') { foreach ($LISTETARGET as $key) { - if ($key !== 'SNAPSHOT' && $key !== 'SF' && $key !== 'ASSO') { + if ($key !== 'SNAPSHOT' && $key !== 'SF' && $key !== 'ASSO') { // @phpstan-ignore-line $CHOOSEDTARGET[$key] = 1; } } } - if ($targetUpper !== 'ALL' && $targetUpper !== 'SF' && $targetUpper !== 'ASSO') { + if ($targetUpper !== 'ALL' && $targetUpper !== 'SF' && $targetUpper !== 'ASSO') { // @phpstan-ignore-line $CHOOSEDTARGET[$targetUpper] = 1; } if ($targetUpper === 'SF') { @@ -399,7 +401,7 @@ if ($target) { } elseif ($NUM_SCRIPT === '0') { $CHOOSEDTARGET['-CHKSUM'] = 1; foreach ($LISTETARGET as $key) { - if ($key !== 'SNAPSHOT' && $key !== 'ASSO' && $key !== 'SF') { + if ($key !== 'SNAPSHOT' && $key !== 'ASSO' && $key !== 'SF') { // @phpstan-ignore-line $CHOOSEDTARGET[$key] = 1; } } @@ -495,7 +497,7 @@ foreach ($CHOOSEDTARGET as $tgt => $val) { ksort($CHOOSEDPUBLISH); foreach ($CHOOSEDPUBLISH as $tgt => $val) { - if ($val < 0) { continue; } + if ($val < 0) { continue; } // @phpstan-ignore-line if ($tgt === 'ASSO') { $nbofpublishneedchangelog++; } if ($tgt === 'SF') { $nbofpublishneedchangelog++; $nbofpublishneedtag++; } $nboftargetok++; @@ -621,7 +623,7 @@ if ($nboftargetok) { // ======================================================================== if ($nboftargetneedbuildroot) { - if (!$copyalreadydone) { + if (!$copyalreadydone) { // @phpstan-ignore-line echo "Creation of a buildroot used for all packages\n"; echo "Delete directory $BUILDROOT\n"; @@ -1297,7 +1299,7 @@ if ($nboftargetok) { ksort($CHOOSEDPUBLISH); foreach ($CHOOSEDPUBLISH as $tgt => $val) { - if ($val < 0) { continue; } + if ($val < 0) { continue; } // @phpstan-ignore-line echo "\nList of files to publish (BUILD=$BUILD)\n"; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 38a10d825e3..418cb375bd8 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -349,7 +349,7 @@ if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = p." . $db->sanitize($accountancy_field_name) . " AND aa.fk_pcg_version = '" . $db->escape($pcgvercode) . "'"; } if (!empty($searchCategoryProductList)) { - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ } $sql .= ' WHERE p.entity IN ('.getEntity('product').')'; if (strlen(trim($search_current_account))) { diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index ecfad20791f..9d6485c3921 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -547,9 +547,9 @@ class Subscription extends CommonObject */ public function info($id) { - $sql = 'SELECT c.rowid, c.datec, c.tms as datem, c.fk_user_creat'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'subscription as c'; - $sql .= ' WHERE c.rowid = '.((int) $id); + $sql = "SELECT c.rowid, c.datec, c.tms as datem, c.fk_user_creat"; + $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c"; + $sql .= " WHERE c.rowid = ".((int) $id); $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/admin/external_rss.php b/htdocs/admin/external_rss.php index 0b01aef5a18..9b30053bee6 100644 --- a/htdocs/admin/external_rss.php +++ b/htdocs/admin/external_rss.php @@ -148,7 +148,7 @@ if (GETPOST("delete")) { $obj = $db->fetch_object($resql); $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; - $sql .= " WHERE entity = ".$conf->entity; + $sql .= " WHERE entity = ".((int) $conf->entity); $sql .= " AND box_id = ".((int) $obj->rowid); $resql = $db->query($sql); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 7e96849bb97..100dac6c8c9 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -3077,7 +3077,7 @@ if ($action == 'create') { // Thirdparty $morehtmlref .= '
' . $soc->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $soc->id > 0) { - $morehtmlref .= ' (' . $langs->trans("OtherProposals") . ')'; + $morehtmlref .= ' (' . $langs->trans("OtherProposals") . ')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index edc443833b3..9876695778e 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2958,7 +2958,7 @@ if ($action == 'create' && $usercancreate) { // Thirdparty $morehtmlref .= '
' . $soc->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' (' . $langs->trans("OtherOrders") . ')'; + $morehtmlref .= ' (' . $langs->trans("OtherOrders") . ')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index eb15a2c0a2e..857cd103275 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5384,7 +5384,7 @@ if ($action == 'create') { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherBills").')'; + $morehtmlref .= ' ('.$langs->trans("OtherBills").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 476fdfcd79d..a883b6751fa 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -372,11 +372,11 @@ if ($object->id > 0) { $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if ($type == 'bank-transfer') { if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= '
('.$langs->trans("OtherBills").')
'; + $morehtmlref .= '
('.$langs->trans("OtherBills").')
'; } } else { if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= '
('.$langs->trans("OtherBills").')
'; + $morehtmlref .= '
('.$langs->trans("OtherBills").')
'; } } // Project @@ -386,7 +386,7 @@ if ($object->id > 0) { if (0) { // @phpstan-ignore-line $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php index 438b11096dc..b53c97649e1 100644 --- a/htdocs/contrat/agenda.php +++ b/htdocs/contrat/agenda.php @@ -205,7 +205,7 @@ if ($object->id > 0) { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; + $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 9fd4a9c1a71..4cdb1d36c3b 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1522,7 +1522,7 @@ if ($action == 'create') { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; + $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; } // Project if (isModEnabled('project')) { @@ -1531,7 +1531,7 @@ if ($action == 'create') { if ($permissiontoadd) { $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { diff --git a/htdocs/contrat/class/contratligne.class.php b/htdocs/contrat/class/contratligne.class.php index 877f99d501d..99c4404e0e0 100644 --- a/htdocs/contrat/class/contratligne.class.php +++ b/htdocs/contrat/class/contratligne.class.php @@ -833,7 +833,7 @@ class ContratLigne extends CommonObjectLine if ($this->date_end > 0) { $sql .= ",date_fin_validite"; } - $sql .= ") VALUES ($this->fk_contrat, '', '".$this->db->escape($this->description)."',"; + $sql .= ") VALUES (".((int) $this->fk_contrat).", '', '".$this->db->escape($this->description)."',"; $sql .= ($this->fk_product > 0 ? $this->fk_product : "null").","; $sql .= " '".$this->db->escape((string) $this->qty)."',"; $sql .= " '".$this->db->escape($this->vat_src_code)."',"; diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php index 9aeaec27fbf..e2ee9a9f7d6 100644 --- a/htdocs/contrat/document.php +++ b/htdocs/contrat/document.php @@ -156,7 +156,7 @@ if ($object->id) { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; + $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; } // Project if (isModEnabled('project')) { @@ -165,7 +165,7 @@ if ($object->id) { if (0) { // @phpstan-ignore-line $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { diff --git a/htdocs/contrat/messaging.php b/htdocs/contrat/messaging.php index c8140647354..c0dd3069a8c 100644 --- a/htdocs/contrat/messaging.php +++ b/htdocs/contrat/messaging.php @@ -194,7 +194,7 @@ $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_ // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; + $morehtmlref .= ' ('.$langs->trans("OtherContracts").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9ab5d24404e..27500c38439 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7235,6 +7235,15 @@ abstract class CommonObject // if the extrafields row already exists for the object, we update it if ($linealreadyfound) { array_shift($sqlColumnValues); // drop the 'fk_object' column because its value won't change + if (empty($sqlColumnValues)) { + // No column of the target element to update. This happens when the object was created from + // another element whose extrafields do not exist on this element (e.g. invoice created from a + // shipment: the source line extrafields are copied into array_options but none match facturedet). + // The existing row is already correct, so there is nothing to update: avoid an empty "SET" clause + // that would produce an invalid SQL statement. + $this->db->commit(); + return 1; + } $sqlColumnValueString = implode( ',', /** @@ -9608,10 +9617,12 @@ abstract class CommonObject if (($mode == 'create') && !in_array(abs($visibility), array(1, 3))) { continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list } elseif (($mode == 'edit') && !in_array(abs($visibility), array(1, 3, 4))) { - // We need to make sure, that the values of hidden extrafields are also part of $_POST. Otherwise, they would be empty after an update of the object. See also getOptionalsFromPost + // We need to make sure, that the values of hidden extrafields are also part of $_POST. + // Otherwise, they would be empty after an update of the object. See also getOptionalsFromPost + // TODO: We should not have this hidden field, and action='update' should be done only if field was POSTED by form. $ef_name = 'options_' . $key; $ef_value = $this->array_options[$ef_name] ?? ''; - $out .= '' . "\n"; + $out .= '' . "\n"; // If trouble to preserve content, we can try dol_htmlentities() instead, but real solution is to remove completely the hidden field (see previous TODO). continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation } elseif ($mode == 'view' && empty($visibility)) { continue; diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 60f9d60bc53..28fed72cf21 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -384,7 +384,7 @@ class DiscountAbsolute extends CommonObject $sql .= " multicurrency_amount_ht, multicurrency_amount_tva, multicurrency_amount_ttc,"; $sql .= " fk_facture_source, fk_invoice_supplier_source, multicurrency_code, multicurrency_tx"; $sql .= ")"; - $sql .= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec != '' ? $this->datec : dol_now())."', ".((int) $this->socid).", ".(empty($this->discount_type) ? 0 : intval($this->discount_type)).", ".((int) $userid).", '".$this->db->escape($this->description)."',"; + $sql .= " VALUES (".((int) $conf->entity).", '".$this->db->idate($this->datec != '' ? $this->datec : dol_now())."', ".((int) $this->socid).", ".(empty($this->discount_type) ? 0 : intval($this->discount_type)).", ".((int) $userid).", '".$this->db->escape($this->description)."',"; $sql .= " ".price2num($this->amount_ht).", ".price2num($this->amount_tva).", "; $sql .= " ".($this->total_localtax1 ? price2num($this->total_localtax1) : 0).", ".($this->total_localtax2 ? price2num($this->total_localtax2) : 0).", ".price2num($this->amount_ttc).", ".price2num($this->tva_tx).","; $sql .= " ".price2num($this->localtax1_tx).", ".price2num($this->localtax1_type).", "; diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 9bc6a1ad301..a3c95e6cf38 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1006,8 +1006,11 @@ function num_public_holiday($timestampStart, $timestampEnd, $countryCodeOrId = ' } // Increase number of days (on go up into loop) + // Advance by exactly one GMT day. We can use += instead of dol_time_plus_duree() here because + // inputs of this function are GMT dates (checked above), so a day + // is always exactly 86400 seconds. //var_dump("before ".$jour.' '.$mois.' '.$annee.' '.$timestampStart); - $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd'); + $timestampStart += 86400; //var_dump("after ".$jour.' '.$mois.' '.$annee.' '.$timestampStart); $i++; @@ -1477,7 +1480,7 @@ function getWeekNumbersOfMonth($month, $year) { $nb_days = cal_days_in_month(CAL_GREGORIAN, $month, $year); $TWeek = array(); - for ($day = 1; $day < $nb_days; $day++) { + for ($day = 1; $day <= $nb_days; $day++) { $week_number = getWeekNumber($day, $month, $year); $TWeek[$week_number] = $week_number; } diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 067c030e798..815cdc37110 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -258,10 +258,11 @@ class modAccounting extends DolibarrModules $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'accounting_account as aa'; - $this->export_sql_end[$r] .= ' ,'.MAIN_DB_PREFIX.'accounting_system as ac'; - $this->export_sql_end[$r] .= ' ,'.MAIN_DB_PREFIX.'accounting_account as aa2'; - $this->export_sql_end[$r] .= ' WHERE ac.pcg_version = aa.fk_pcg_version AND aa.entity IN ('.getEntity('accounting').')'; - $this->export_sql_end[$r] .= ' AND aa2.rowid = aa.account_parent AND aa2.active = 1 AND ac.pcg_version = aa2.fk_pcg_version AND aa2.entity IN ('.getEntity('accounting').')'; + $this->export_sql_end[$r] .= ' INNER JOIN '.MAIN_DB_PREFIX.'accounting_system as ac ON ac.pcg_version = aa.fk_pcg_version'; + // LEFT JOIN on the parent account: keep accounts that have no parent (root accounts) or whose parent is + // inactive or belongs to another chart (common when a custom chart is derived from a base one). + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_account as aa2 ON aa2.rowid = aa.account_parent AND aa2.entity IN ('.getEntity('accounting').')'; + $this->export_sql_end[$r] .= ' WHERE aa.entity IN ('.getEntity('accounting').')'; // Imports diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index 145d4da8572..2bef8a3f408 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2026 MDW +/* Copyright (C) 2017-2025 Laurent Destailleur + * Copyright (C) 2026 Regis Houssin + * 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 diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 30da0f8780e..cc222ea8043 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2448,7 +2448,7 @@ if ($action == 'create') { } $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 980a1225d3d..a6ac333555d 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -3375,7 +3375,7 @@ if ($action == 'create') { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'supplier'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' '; + $morehtmlref .= ' '; } // Project if (isModEnabled('project')) { @@ -4311,7 +4311,7 @@ if ($action == 'create') { } // Create payment - if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0) { + if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && $usercancreate) { print ''.$langs->trans('DoPayment').''; // must use facid because id is for payment id not invoice } @@ -4321,7 +4321,7 @@ if ($action == 'create') { if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) { if ($resteapayer == 0) { print ''.$langs->trans('DoPaymentBack').''; - } else { + } elseif ($usercancreate) { print ''.$langs->trans('DoPaymentBack').''; } } diff --git a/htdocs/fourn/facture/contact.php b/htdocs/fourn/facture/contact.php index b1ac80762d9..9128fdb0c2c 100644 --- a/htdocs/fourn/facture/contact.php +++ b/htdocs/fourn/facture/contact.php @@ -162,7 +162,7 @@ if ($id > 0 || !empty($ref)) { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' '; + $morehtmlref .= ' '; } // Project if (isModEnabled('project')) { diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php index 7e6fcd718b2..6aa4d568cbf 100644 --- a/htdocs/fourn/facture/document.php +++ b/htdocs/fourn/facture/document.php @@ -126,7 +126,7 @@ if ($object->id > 0 && $upload_dir !== null) { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' '; + $morehtmlref .= ' '; } // Project if (isModEnabled('project')) { diff --git a/htdocs/fourn/facture/info.php b/htdocs/fourn/facture/info.php index 512f63b85fd..78a231ef6ac 100644 --- a/htdocs/fourn/facture/info.php +++ b/htdocs/fourn/facture/info.php @@ -93,7 +93,7 @@ $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object-> // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' '; + $morehtmlref .= ' '; } // Project if (isModEnabled('project')) { diff --git a/htdocs/fourn/facture/note.php b/htdocs/fourn/facture/note.php index bd78cc64fd6..b2f5adedcde 100644 --- a/htdocs/fourn/facture/note.php +++ b/htdocs/fourn/facture/note.php @@ -122,7 +122,7 @@ if ($object->id > 0) { // Thirdparty $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' '; + $morehtmlref .= ' '; } // Project if (isModEnabled('project')) { diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index a0236cff7cf..db1de33ce7d 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -5658,7 +5658,7 @@ function migrate_blockedlog_add_hmac_key() $hmac_secret_key = 'BLOCKEDLOGHMAC'.$randomsecret; // Example: 'BLOCKEDLOGHMACY3Ewx37RXbSd8gL9JV8p7Wqw7qvq2K2A' - $result = dolibarr_set_const($db, 'BLOCKEDLOG_HMAC_KEY', $hmac_secret_key, 'chaine', 0, 'The secret key for HMAC used for blockedlog record', 0); // Will encrypt the value using dolCrypt and store it. + $result = dolibarr_set_const($db, 'BLOCKEDLOG_HMAC_KEY', $hmac_secret_key, 'chaine', 0, 'The secret key for HMAC used for blockedlog record', $conf->entity); // Will encrypt the value using dolCrypt and store it. if ($result < 0) { dol_print_error($db); diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index c10f3d10e77..1dc616d2315 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -170,7 +170,7 @@ if ($object->id > 0) { if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } // Project diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index e9192c85597..042119b28ce 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -691,7 +691,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } // Project diff --git a/htdocs/mrp/mo_document.php b/htdocs/mrp/mo_document.php index e2fdcc269f1..84af4445a09 100644 --- a/htdocs/mrp/mo_document.php +++ b/htdocs/mrp/mo_document.php @@ -142,7 +142,7 @@ if ($object->id && $upload_dir !== null) { if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } // Project diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index 928e320d95e..5c54251c357 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -329,7 +329,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } // Project diff --git a/htdocs/mrp/mo_note.php b/htdocs/mrp/mo_note.php index edacf43f88d..b98968dbbb5 100644 --- a/htdocs/mrp/mo_note.php +++ b/htdocs/mrp/mo_note.php @@ -119,7 +119,7 @@ if ($id > 0 || !empty($ref)) { if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } // Project diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 2cc6ed2716e..ced1ab85f89 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -710,7 +710,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (is_object($object->thirdparty)) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 4e6ed30b29a..744d2a75bc1 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -621,7 +621,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Thirdparty $morehtmlref .= empty($object->thirdparty) ? '' : $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalInt('MAIN_DISABLE_OTHER_LINK') && !empty($object->thirdparty) && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php index 94a02f0af4d..11828f6df4f 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php @@ -163,7 +163,7 @@ if ($object->id > 0) { // Thirdparty $morehtmlref .= empty($object->thirdparty) ? '' : $object->thirdparty->getNomUrl(1, 'customer'); if (!getDolGlobalInt('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; + $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index bc9dc9dff64..ab913073475 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -392,7 +392,7 @@ if (isModEnabled('stripe') && $paymentmethod === 'stripe') { // Check we are coming from the newpaymentpage // Bypass session check when returning from Stripe confirmPayment() (mode STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=2) // In that case, payment_intent is passed in GET by Stripe and PaymentIntent::retrieve() below acts as verification - if (empty(GETPOST('payment_intent', 'alphanohtml')) && GETPOST('paymentoksessioncode') !== $_SESSION['paymentoksessioncode']) { + if (!GETPOST('payment_intent', 'alphanohtml') && GETPOST('paymentoksessioncode') !== $_SESSION['paymentoksessioncode']) { $error++; $errmsg = 'Attempted direct access to the paymentok page without a valid session.'; dol_syslog($errmsg, LOG_ERR, 0, '_payment'); diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 2a5e8948cfc..c9b0a64ae84 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -405,7 +405,7 @@ class CompanyBankAccount extends Account $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_rib (fk_soc, type, datec, model_pdf)"; - $sql .= " VALUES (".((int) $this->socid).", '".$this->type."', '".$this->db->idate($this->datec)."',"; + $sql .= " VALUES (".((int) $this->socid).", '".$this->db->escape($this->type)."', '".$this->db->idate($this->datec)."',"; $sql .= " '".$this->db->escape(getDolGlobalString("BANKADDON_PDF"))."'"; $sql .= ")"; $resql = $this->db->query($sql); diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index cacec75e83b..79ea5f23658 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1941,7 +1941,7 @@ if ($action == 'create') { // Thirdparty $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier'); if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherProposals").')'; + $morehtmlref .= ' ('.$langs->trans("OtherProposals").')'; } // Project if (isModEnabled('project')) { diff --git a/htdocs/user/class/userbankaccount.class.php b/htdocs/user/class/userbankaccount.class.php index 19db5f1514e..be10af47621 100644 --- a/htdocs/user/class/userbankaccount.class.php +++ b/htdocs/user/class/userbankaccount.class.php @@ -96,7 +96,7 @@ class UserBankAccount extends Account $now = dol_now(); $sql = "INSERT INTO ".$this->db->prefix()."user_rib (fk_user, datec)"; - $sql .= " VALUES (".$this->userid.", '".$this->db->idate($now)."')"; + $sql .= " VALUES (".((int) $this->userid).", '".$this->db->idate($now)."')"; $resql = $this->db->query($sql); if ($resql) { if ($this->db->affected_rows($resql)) { diff --git a/test/phpunit/CodingPhpTest.php b/test/phpunit/CodingPhpTest.php index 65bec3fd9b5..01d385aab51 100644 --- a/test/phpunit/CodingPhpTest.php +++ b/test/phpunit/CodingPhpTest.php @@ -118,7 +118,7 @@ class CodingPhpTest extends CommonClassTest // To process only 1 file, uncomment this /* foreach($returnlist as $key => $val) { - if ($val[0]['name'] != 'societe.class.php') { + if ($val[0]['name'] != 'companybankaccount.class.php') { unset($returnlist[$key]); } } @@ -440,21 +440,79 @@ class CodingPhpTest extends CommonClassTest $this->assertTrue($ok, 'Found a forged SQL string that does not use escape or int cast for file '.$file['relativename']); //exit; - // Check sql string VALUES ... , ".$xxx - // with xxx that is not 'db-' (for $db->escape). It means we forget a ' if string, or an (int) if int, when forging sql request. + // Check that forged sql string is using ' instead of " as string PHP quotes $ok = true; $matches = array(); - preg_match_all('/(VALUES).*,\s*"\s*\.\s*\$(...)/', $filecontent, $matches, PREG_SET_ORDER); + preg_match_all('/\$sql \.= \'\s*VALUES.*\$/', $filecontent, $matches, PREG_SET_ORDER); foreach ($matches as $key => $val) { - if ($val[1] == 'VALUES' && $val[2] == 'db-') { // exclude $db->escape( - continue; - } - if ($val[1] == 'VALUES' && $val[2] == 'thi' && preg_match('/this->db->encrypt/', $val[0])) { // exclude ".$this->db->encrypt( - continue; - } + //if ($val[1] != '\'"' && $val[1] != '\'\'') { var_dump($matches); $ok = false; break; + //} + //if ($reg[0] != 'db') $ok=false; + } + //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; + $this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables in file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...'); + //exit; + + // Check that forged sql string is using ' instead of " as string PHP quotes + $ok = true; + $matches = array(); + preg_match_all('/\$sql \.?= \'SELECT.*\$/', $filecontent, $matches, PREG_SET_ORDER); + foreach ($matches as $key => $val) { + var_dump($matches); + $ok = false; + break; + } + $this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables in file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...'); + + // Check sql string VALUES ... , ".$xxx or string VALUES ... , '".$xxx + // with xxx that is not 'db-' (for $db->escape). It means we forget a ' if string, or an (int) if int, when forging sql request. + // ... = " VALUES (".((int) $this->socid).", '".$this->type."', '".$this->db->idate($this->datec)."',"; + + $ok = true; + $matches = array(); + preg_match_all('/(VALUES).*,\s*\'?"\s*\.\s*\$([a-z\-\>]+)/', $filecontent, $matches, PREG_SET_ORDER); + foreach ($matches as $key => $val) { + $matches2 = array(); + preg_match_all('/,\s*\'?"\s*\.\s*\$([a-z\-\>]+)/', $val[0], $matches2, PREG_SET_ORDER); + foreach ($matches2 as $key2 => $val2) { + if ($val2[1] == 'mydb->escape') { // exclude ".$mydb->escape( + continue; + } + if ($val2[1] == 'dbsession->escape') { // exclude ".$dbsession->escape( + continue; + } + if ($val2[1] == 'dbsession->idate') { // exclude ".$dbsession->escape( + continue; + } + if ($val2[1] == 'this->db->encrypt') { // exclude ".$this->db->encrypt( + continue; + } + if ($val2[1] == 'this->db->escape') { // exclude ".$this->db->escape( + continue; + } + if ($val2[1] == 'this->db->idate') { // exclude ".$this->db->idate( + continue; + } + if ($val2[1] == 'db->encrypt') { // exclude ".$db->encrypt( + continue; + } + if ($val2[1] == 'db->escape') { // exclude ".$db->escape( + continue; + } + if ($val2[1] == 'db->idate') { // exclude ".$db->idate( + continue; + } + if ($val2[1] == 'this->escape') { // exclude ".$this->db->encrypt( + continue; + } + + var_dump($matches2); + $ok = false; + break; + } } //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; $this->assertTrue($ok, 'Found non quoted or not casted var in sql request '.$file['relativename'].' - Bad.');