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

This commit is contained in:
Laurent Destailleur
2025-09-28 20:01:36 +02:00
8 changed files with 65 additions and 43 deletions

View File

@@ -1141,10 +1141,13 @@ if ($mode == 'common' || $mode == 'commonkanban') {
} }
} }
} }
$urltogo = $_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&token='.newToken().'&module_position='.$module_position.'&action=set&token='.newToken().'&value='.$modName.'&mode='.$mode.$param;
$popupwidth = 500;
$codeenabledisable .= '<!-- Message to show: '.$warningmessage.' -->'."\n"; $codeenabledisable .= '<!-- Message to show: '.$warningmessage.' -->'."\n";
$codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&token='.newToken().'&module_position='.$module_position.'&action=set&token='.newToken().'&value='.$modName.'&mode='.$mode.$param.'"'; $codeenabledisable .= '<a class="reposition" id="ida'.$objMod->numero.'" data-alreadyclicked="0" href="'.$urltogo.'"';
if ($warningmessage) { if ($warningmessage) {
$codeenabledisable .= ' onclick="return confirmDolibarr(\''.dol_escape_js($warningmessage).'\', 360);"'; $codeenabledisable .= ' onclick="return confirmDolibarr(\''.dol_escape_js($warningmessage).'\', \'ida'.$objMod->numero.'\', '.$popupwidth.');"';
} }
$codeenabledisable .= '>'; $codeenabledisable .= '>';
$codeenabledisable .= img_picto($langs->trans("Disabled"), 'switch_off'); $codeenabledisable .= img_picto($langs->trans("Disabled"), 'switch_off');

View File

@@ -1446,6 +1446,7 @@ class ExtraFields
} }
} }
if (!getDolGlobalString('MAIN_EXTRAFIELDS_ENABLE_NEW_SELECT2')) { if (!getDolGlobalString('MAIN_EXTRAFIELDS_ENABLE_NEW_SELECT2')) {
//$out .= '<!-- type = sellist -->';
$out .= '<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>'; $out .= '<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
if (is_array($param['options'])) { if (is_array($param['options'])) {
// WARNING!! @FIXME This code is duplicated into core/class/extrafields.class.php // WARNING!! @FIXME This code is duplicated into core/class/extrafields.class.php
@@ -1625,16 +1626,22 @@ class ExtraFields
$labeltoshow = ''; $labeltoshow = '';
$obj = $this->db->fetch_object($resql); $obj = $this->db->fetch_object($resql);
// Several field into label (eq table:code|label:rowid) $nameFields = $InfoFieldList[1];
// If text is "field1|f(a,b,c) as xxx|field2", we must convert string into 'field1|xxx|field2'
$nameFields = preg_replace('/[a-z_]+\([^\)]*\) as ([\w]+)/i', '\1', $nameFields);
// Sanitize field names to avoid error when doing $obj->field
$nameFields = preg_replace('/[^0-9a-z_\.\|]/i', '', $nameFields);
// Several fields into label (eq table:code|label:rowid)
$notrans = false; $notrans = false;
$fields_label = explode('|', $InfoFieldList[1]); $fields_label = explode('|', $nameFields);
if (is_array($fields_label) && count($fields_label) > 1) { if (is_array($fields_label) && count($fields_label) > 1) {
$notrans = true; $notrans = true;
foreach ($fields_label as $field_toshow) { foreach ($fields_label as $field_toshow) {
$labeltoshow .= $obj->$field_toshow.' '; $labeltoshow .= $obj->$field_toshow.' ';
} }
} else { } else {
$labeltoshow = $obj->{$InfoFieldList[1]}; $labeltoshow = $obj->$nameFields;
} }
if ($value == $obj->rowid) { if ($value == $obj->rowid) {
@@ -1647,7 +1654,7 @@ class ExtraFields
$out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>'; $out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
} else { } else {
if (!$notrans) { if (!$notrans) {
$translabel = $langs->trans($obj->{$InfoFieldList[1]}); $translabel = $langs->trans($obj->$nameFields);
$labeltoshow = $translabel; $labeltoshow = $translabel;
} }
if (empty($labeltoshow)) { if (empty($labeltoshow)) {
@@ -1655,6 +1662,8 @@ class ExtraFields
} }
if (!empty($InfoFieldList[3]) && $parentField) { if (!empty($InfoFieldList[3]) && $parentField) {
// Sanitize parent field name to avoid when doing $obj->field
$parentField = preg_replace('/[^a-zA-Z0-9_\-]/', '', $parentField);
$parent = $parentName.':'.$obj->{$parentField}; $parent = $parentName.':'.$obj->{$parentField};
} }

View File

@@ -322,7 +322,7 @@ abstract class DoliDB implements Database
/** /**
* Define sort criteria of request * Define sort criteria of request
* *
* @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' or 't1.fielda,concat(a,b,c) as abc,t2.fieldb'
* @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'. Note: If the quantity for sortorder values is lower than sortfield, we used the last value for missing values. * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'. Note: If the quantity for sortorder values is lower than sortfield, we used the last value for missing values.
* @return string String to provide syntax of a sort sql string * @return string String to provide syntax of a sort sql string
*/ */
@@ -331,17 +331,30 @@ abstract class DoliDB implements Database
if (!empty($sortfield)) { if (!empty($sortfield)) {
$oldsortorder = ''; $oldsortorder = '';
$return = ''; $return = '';
// If text is "field1, f(a,b,c) as xxx, field2", we must convert string into 'field1,xxx,field2'
$sortfield = preg_replace('/[a-z_]+\([^\)]*\) as ([\w]+)/i', '\1', $sortfield);
$fields = explode(',', $sortfield); $fields = explode(',', $sortfield);
$orders = (!empty($sortorder) ? explode(',', $sortorder) : array()); $orders = (!empty($sortorder) ? explode(',', $sortorder) : array());
$i = 0; $i = 0;
foreach ($fields as $val) { foreach ($fields as $val) {
// Sanitized fieldname
$fieldname = preg_replace('/[^0-9a-z_\.]/i', '', $val);
if (!$fieldname) {
continue;
}
if (!$return) { if (!$return) {
$return .= ' ORDER BY '; $return .= ' ORDER BY ';
} else { } else {
$return .= ', '; $return .= ', ';
} }
$return .= preg_replace('/[^0-9a-z_\.]/i', '', $val); // Add field // Add field
$return .= $fieldname;
$tmpsortorder = (empty($orders[$i]) ? '' : trim($orders[$i])); $tmpsortorder = (empty($orders[$i]) ? '' : trim($orders[$i]));

View File

@@ -567,36 +567,28 @@ function cleanSerialize(expr) {
/* /*
* ================================================================= * =================================================================
* Purpose: Display a temporary message in input text fields (For showing help message on * Purpose: Fonction to open a confirm popup on a clie of a link
* input field). * Input: msg
* Input: fieldId * Input: width
* Input: message
* Author: Regis Houssin
* Licence: GPL * Licence: GPL
* ================================================================== * ==================================================================
*/ */
function displayMessage(fieldId,message) { function confirmDolibarr(msg, id, width = 400) {
var textbox = document.getElementById(fieldId); let alink = document.getElementById(id);
if (textbox.value == '') { if (alink.getAttribute("data-alreadyclicked") === "0") {
textbox.style.color = 'grey'; new Promise(res => {
textbox.value = message; $("#dialogforpopup").text(msg).dialog({
modal: true,
width: width,
buttons: {
OK() { $(this).dialog("close"); res(false); alink.setAttribute("data-alreadyclicked", "1"); alink.click(); },
} }
});
});
return false;
} else {
return true;
} }
/*
* =================================================================
* Purpose: Hide a temporary message in input text fields (For showing help message on
* input field).
* Input: fiedId
* Input: message
* Author: Regis Houssin
* Licence: GPL
* ==================================================================
*/
function hideMessage(fieldId,message) {
var textbox = document.getElementById(fieldId);
textbox.style.color = 'black';
if (textbox.value == message) textbox.value = '';
} }

View File

@@ -202,7 +202,7 @@ print $formadmin->selectTypeOfFields('type', GETPOST('type', 'alpha'));
<td> <td>
<table class="nobordernopadding"> <table class="nobordernopadding">
<tr><td> <tr><td>
<textarea name="param" id="param" cols="80" rows="<?php echo ROWS_4 ?>"><?php echo GETPOST('param', 'alpha'); ?></textarea> <textarea name="param" id="param" cols="80" rows="<?php echo ROWS_4 ?>" spellcheck="false""><?php echo GETPOST('param', 'alpha'); ?></textarea>
</td><td> </td><td>
<span id="helpselect" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?></span> <span id="helpselect" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?></span>
<span id="helpsellist" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").'<br>'.$langs->trans("ExtrafieldParamHelpsellistb").'<br>'.$langs->trans("ExtrafieldParamHelpsellistc").'<br>'.$langs->trans("ExtrafieldParamHelpsellistd").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '<br>'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?></span> <span id="helpsellist" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").'<br>'.$langs->trans("ExtrafieldParamHelpsellistb").'<br>'.$langs->trans("ExtrafieldParamHelpsellistc").'<br>'.$langs->trans("ExtrafieldParamHelpsellistd").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '<br>'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?></span>

View File

@@ -266,7 +266,7 @@ if (in_array($type, array_keys($typewecanchangeinto))) {
<td> <td>
<table class="nobordernopadding"> <table class="nobordernopadding">
<tr><td> <tr><td>
<textarea name="param" id="param" cols="80" rows="<?php echo ROWS_4 ?>"><?php echo dol_htmlcleanlastbr($param_chain); ?></textarea> <textarea name="param" id="param" cols="80" rows="<?php echo ROWS_4 ?>" spellcheck="false"><?php echo dol_htmlcleanlastbr($param_chain); ?></textarea>
</td><td> </td><td>
<span id="helpselect" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?></span> <span id="helpselect" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?></span>
<span id="helpsellist" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").'<br>'.$langs->trans("ExtrafieldParamHelpsellistb").'<br>'.$langs->trans("ExtrafieldParamHelpsellistc").'<br>'.$langs->trans("ExtrafieldParamHelpsellistd").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '<br>'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?></span> <span id="helpsellist" class="spanforparamtooltip"><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").'<br>'.$langs->trans("ExtrafieldParamHelpsellistb").'<br>'.$langs->trans("ExtrafieldParamHelpsellistc").'<br>'.$langs->trans("ExtrafieldParamHelpsellistd").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '<br>'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?></span>

View File

@@ -1,5 +1,4 @@
<?php <?php
/* Copyright (C) 2025 Frédéric France <frederic.france@free.fr> /* Copyright (C) 2025 Frédéric France <frederic.france@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -14,13 +13,19 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
/** /**
* @var Conf $conf * @var Conf $conf
* @var DoliDB $db
* @var CommonObject $object * @var CommonObject $object
* @var DoliDB $db
* @var ExtraFields $extrafields
*
* @var array<string,mixed> $arrayfields
* @var ?string $extrafieldsobjectkey
* @var ?string $extrafieldsobjectprefix
* @var ?string $search_options_pattern
* @var array<string,mixed> $search_array_options
*/ */
print '<!-- extrafields_list_search_input.tpl.php -->'."\n"; print '<!-- extrafields_list_search_input.tpl.php -->'."\n";

View File

@@ -485,7 +485,7 @@ ExtrafieldParamHelpPassword=Leaving this field blank means this value will be st
ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>code3,value3<br>...<br><br>In order to have the list depending on another complementary attribute list:<br>1,value1|options_<i>parent_list_code</i>:parent_key<br>2,value2|options_<i>parent_list_code</i>:parent_key <br><br>In order to have the list depending on another list:<br>1,value1|<i>parent_list_code</i>:parent_key<br>2,value2|<i>parent_list_code</i>:parent_key ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>code3,value3<br>...<br><br>In order to have the list depending on another complementary attribute list:<br>1,value1|options_<i>parent_list_code</i>:parent_key<br>2,value2|options_<i>parent_list_code</i>:parent_key <br><br>In order to have the list depending on another list:<br>1,value1|<i>parent_list_code</i>:parent_key<br>2,value2|<i>parent_list_code</i>:parent_key
ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>3,value3<br>... ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>3,value3<br>...
ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>3,value3<br>... ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')<br><br> for example: <br>1,value1<br>2,value2<br>3,value3<br>...
ExtrafieldParamHelpsellist=List of values coming from a table<br><br>Syntax: table_name:label_field:id_field::filtersql<br>Example: c_typent:libelle:id::filtersql<br><br>- id_field is necessarily a primary int key<br>- filtersql is a condition. It must use the USF syntax. Example: (active:=:1) to display only active value ExtrafieldParamHelpsellist=List of values coming from a table<br><br>Syntax: table_name:label_field:id_field::filtersql<br>Example: c_typent:libelle:id::filtersql<br><br>- label_field is the name of the field in database, or can be several fiels separated by |<br>- id_field is necessarily a primary int key<br>- filtersql is a condition. It must use the USF syntax. Example: (active:=:1) to display only active value
ExtrafieldParamHelpsellistb=In USF syntax, use the name of fields in database table or extra.fieldname to use the field in the extrafield table. ExtrafieldParamHelpsellistb=In USF syntax, use the name of fields in database table or extra.fieldname to use the field in the extrafield table.
ExtrafieldParamHelpsellistc=You can also use $ID$ in filter which is the current ID of current object or more generally, use $property$ to get the value of the property of the current edited object. ExtrafieldParamHelpsellistc=You can also use $ID$ in filter which is the current ID of current object or more generally, use $property$ to get the value of the property of the current edited object.
ExtrafieldParamHelpsellistd=Use the string __NOW__ or __USER_ID__ to get the current date or current user ID. ExtrafieldParamHelpsellistd=Use the string __NOW__ or __USER_ID__ to get the current date or current user ID.