Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2026-07-18 16:17:03 +02:00
commit 0d414fcb51
39 changed files with 152 additions and 76 deletions

View file

@ -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, ' </dir>'."\n");
}
$needtoclose = 0;
//if ($needtoclose) {
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
//}
if ($release) {
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
}

View file

@ -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";

View file

@ -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))) {

View file

@ -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) {

View file

@ -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);

View file

@ -3077,7 +3077,7 @@ if ($action == 'create') {
// Thirdparty
$morehtmlref .= '<br>' . $soc->getNomUrl(1, 'customer');
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $soc->id > 0) {
$morehtmlref .= ' (<a href="' . DOL_URL_ROOT . '/comm/propal/list.php?socid=' . $soc->id . '&search_societe=' . urlencode($soc->name) . '">' . $langs->trans("OtherProposals") . '</a>)';
$morehtmlref .= ' (<a href="' . DOL_URL_ROOT . '/comm/propal/list.php?socid=' . ((int) $soc->id) . '">' . $langs->trans("OtherProposals") . '</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -2958,7 +2958,7 @@ if ($action == 'create' && $usercancreate) {
// Thirdparty
$morehtmlref .= '<br>' . $soc->getNomUrl(1, 'customer');
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' (<a href="' . DOL_URL_ROOT . '/commande/list.php?socid=' . $object->thirdparty->id . '&search_societe=' . urlencode($object->thirdparty->name) . '">' . $langs->trans("OtherOrders") . '</a>)';
$morehtmlref .= ' (<a href="' . DOL_URL_ROOT . '/commande/list.php?socid=' . ((int) $object->thirdparty->id) . '">' . $langs->trans("OtherOrders") . '</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -5384,7 +5384,7 @@ if ($action == 'create') {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'customer');
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherBills").'</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -372,11 +372,11 @@ if ($object->id > 0) {
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if ($type == 'bank-transfer') {
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
}
} else {
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
}
}
// 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 .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
$morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => ((int) $object->id)], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$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 {

View file

@ -205,7 +205,7 @@ if ($object->id > 0) {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.dolBuildUrl(DOL_URL_ROOT.'/contrat/list.php', ['socid' => $object->thirdparty->id, 'search_name' => $object->thirdparty->name]).'">'.$langs->trans("OtherContracts").'</a>)</span>';
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.dolBuildUrl(DOL_URL_ROOT.'/contrat/list.php', ['socid' => ((int) $object->thirdparty->id)]).'">'.$langs->trans("OtherContracts").'</a>)</span>';
}
// Project
if (isModEnabled('project')) {

View file

@ -1522,7 +1522,7 @@ if ($action == 'create') {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)</span>';
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherContracts").'</a>)</span>';
}
// 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 .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
$morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => ((int) $object->id)], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$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 {

View file

@ -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)."',";

View file

@ -156,7 +156,7 @@ if ($object->id) {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)</span>';
$morehtmlref .= ' <span class="otherlink valignmiddle">(<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherContracts").'</a>)</span>';
}
// 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 .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
$morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => ((int) $object->id)], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$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 {

View file

@ -194,7 +194,7 @@ $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherContracts").'</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -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 .= '<input type="hidden" name="' . $ef_name . '" id="' . $ef_name . '" value="' . $ef_value . '" />' . "\n";
$out .= '<input type="hidden" name="' . $ef_name . '" id="' . $ef_name . '" value="' . dol_htmlentities($ef_value) . '" />' . "\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;

View file

@ -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).", ";

View file

@ -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;
}

View file

@ -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

View file

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2017-2025 Laurent Destailleur <eldy@users.sourcefore.net>
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
/* Copyright (C) 2017-2025 Laurent Destailleur <eldy@users.sourcefore.net>
* Copyright (C) 2026 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
*
* 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

View file

@ -2448,7 +2448,7 @@ if ($action == 'create') {
}
$morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}

View file

@ -3375,7 +3375,7 @@ if ($action == 'create') {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'supplier');
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
}
// 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 '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create'.($object->fk_account > 0 ? '&accountid='.$object->fk_account : '').'">'.$langs->trans('DoPayment').'</a>'; // 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 '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span>';
} else {
} elseif ($usercancreate) {
print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create&accountid='.$object->fk_account.'">'.$langs->trans('DoPaymentBack').'</a>';
}
}

View file

@ -162,7 +162,7 @@ if ($id > 0 || !empty($ref)) {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherBills").'</a>)</div>';
}
// Project
if (isModEnabled('project')) {

View file

@ -126,7 +126,7 @@ if ($object->id > 0 && $upload_dir !== null) {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherBills").'</a>)</div>';
}
// Project
if (isModEnabled('project')) {

View file

@ -93,7 +93,7 @@ $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object->
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherBills").'</a>)</div>';
}
// Project
if (isModEnabled('project')) {

View file

@ -122,7 +122,7 @@ if ($object->id > 0) {
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
$morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherBills").'</a>)</div>';
}
// Project
if (isModEnabled('project')) {

View file

@ -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);

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}
// Project

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}
// Project

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}
// Project

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}
// Project

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}
// Project

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
}

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -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');

View file

@ -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);

View file

@ -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 .= ' (<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherProposals").'</a>)';
$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherProposals").'</a>)';
}
// Project
if (isModEnabled('project')) {

View file

@ -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)) {

View file

@ -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.');