';
// Transaction reconciliated or edit link
if ($objp->conciliated && $bankaccount->canBeConciliated() > 0) { // If line not conciliated and account can be conciliated
@@ -1692,19 +1691,14 @@ if ($resql) {
print '';
}
}
- print '
';
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
$selected = 0;
if (in_array($obj->rowid, $arrayofselected)) {
$selected = 1;
}
- print '';
+ print '';
}
print '
';
if (!$i) {
diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
index 9f000786b7f..5d2bb71109b 100644
--- a/htdocs/compta/bank/card.php
+++ b/htdocs/compta/bank/card.php
@@ -1060,19 +1060,19 @@ if ($action == 'create') {
// IBAN
print '
';
if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) {
$objsoc = new Societe($db);
$objsoc->fetch($object->socid);
diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php
index eeeccddd671..edb54631786 100644
--- a/htdocs/contrat/agenda.php
+++ b/htdocs/contrat/agenda.php
@@ -57,8 +57,8 @@ if ($user->socid) {
$result = restrictedArea($user, 'contrat', $id, '');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST("sortfield", 'alpha');
-$sortorder = GETPOST("sortorder", 'alpha');
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php
index b4cf2fc1fbf..953fd0002d2 100644
--- a/htdocs/contrat/document.php
+++ b/htdocs/contrat/document.php
@@ -55,8 +55,8 @@ $result = restrictedArea($user, 'contrat', $id);
// Get parameters
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST("sortfield", 'alpha');
-$sortorder = GETPOST("sortorder", 'alpha');
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php
index ed980f9e86e..e6446e3585b 100644
--- a/htdocs/contrat/list.php
+++ b/htdocs/contrat/list.php
@@ -79,8 +79,8 @@ $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_en
$optioncss = GETPOST('optioncss', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST("sortfield", 'alpha');
-$sortorder = GETPOST("sortorder", 'alpha');
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php
index 31621ba420a..39dfe336a31 100644
--- a/htdocs/contrat/services_list.php
+++ b/htdocs/contrat/services_list.php
@@ -39,8 +39,8 @@ $optioncss = GETPOST('optioncss', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST("sortfield", 'alpha');
-$sortorder = GETPOST("sortorder", 'alpha');
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 7de04ab0d14..029ac6cbfc1 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -3694,23 +3694,23 @@ abstract class CommonObject
/**
* Fetch array of objects linked to current object (object of enabled modules only). Links are loaded into
* this->linkedObjectsIds array +
- * this->linkedObjects array if $loadalsoobjects = 1
+ * this->linkedObjects array if $loadalsoobjects = 1 or $loadalsoobjects = type
* Possible usage for parameters:
* - all parameters empty -> we look all link to current object (current object can be source or target)
- * - source id+type -> will get target list linked to source
- * - target id+type -> will get source list linked to target
- * - source id+type + target type -> will get target list of the type
- * - target id+type + target source -> will get source list of the type
+ * - source id+type -> will get list of targets linked to source
+ * - target id+type -> will get list of sources linked to target
+ * - source id+type + target type -> will get list of targets of the type linked to source
+ * - target id+type + source type -> will get list of sources of the type linked to target
*
- * @param int $sourceid Object source id (if not defined, id of object)
- * @param string $sourcetype Object source type (if not defined, element name of object)
- * @param int $targetid Object target id (if not defined, id of object)
- * @param string $targettype Object target type (if not defined, elemennt name of object)
- * @param string $clause 'OR' or 'AND' clause used when both source id and target id are provided
- * @param int $alsosametype 0=Return only links to object that differs from source type. 1=Include also link to objects of same type.
- * @param string $orderby SQL 'ORDER BY' clause
- * @param int $loadalsoobjects Load also array this->linkedObjects (Use 0 to increase performances)
- * @return int <0 if KO, >0 if OK
+ * @param int $sourceid Object source id (if not defined, id of object)
+ * @param string $sourcetype Object source type (if not defined, element name of object)
+ * @param int $targetid Object target id (if not defined, id of object)
+ * @param string $targettype Object target type (if not defined, element name of object)
+ * @param string $clause 'OR' or 'AND' clause used when both source id and target id are provided
+ * @param int $alsosametype 0=Return only links to object that differs from source type. 1=Include also link to objects of same type.
+ * @param string $orderby SQL 'ORDER BY' clause
+ * @param int|string $loadalsoobjects Load also array this->linkedObjects. Use 0 to increase performances, Use 1 to load all, Use value of type ('facture', 'facturerec', ...) to load only a type of object.
+ * @return int <0 if KO, >0 if OK
* @see add_object_linked(), updateObjectLinked(), deleteObjectLinked()
*/
public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '', $clause = 'OR', $alsosametype = 1, $orderby = 'sourcetype', $loadalsoobjects = 1)
@@ -3892,10 +3892,9 @@ abstract class CommonObject
$module = 'mrp';
}
-
- // Here $module, $classfile and $classname are set
+ // Here $module, $classfile and $classname are set, we can use them.
if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) {
- if ($loadalsoobjects) {
+ if ($loadalsoobjects && (is_numeric($loadalsoobjects) || ($loadalsoobjects === $objecttype))) {
dol_include_once('/'.$classpath.'/'.$classfile.'.class.php');
//print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname);
if (class_exists($classname)) {
@@ -6110,6 +6109,7 @@ abstract class CommonObject
}
$sql .= ")";
+
$resql = $this->db->query($sql);
if (!$resql) {
$this->error = $this->db->lasterror();
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index 184b97a3c98..4c0ec1ff5a5 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -1947,8 +1947,8 @@ class ExtraFields
if (!empty($onlykey) && $onlykey != '@GETPOSTISSET' && $key != $onlykey) {
continue;
}
- if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && $this->attributes[$object->table_element]['type'][$key] != 'boolean') {
- //when unticking boolean field, it's not set in POST
+
+ if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && (! in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'chkbxlst')))) {
continue;
}
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index de8c4519a22..88fca7b536a 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -3120,7 +3120,7 @@ class Form
$sql = "SELECT p.rowid, p.ref, p.label, p.price, p.duration, p.fk_product_type, p.stock,";
$sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
- $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
+ $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.default_vat_code, pfp.fk_soc, s.nom as name,";
$sql .= " pfp.supplier_reputation";
// if we use supplier description of the products
if (!empty($conf->global->PRODUIT_FOURN_TEXTS)) {
@@ -3275,7 +3275,7 @@ class Form
$optlabel = $objp->ref;
if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) {
- $optlabel .= ' ('.$objp->ref_fourn.')';
+ $optlabel .= ' ('.$objp->ref_fourn.')';
}
if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) {
$optlabel .= ' ('.$outbarcode.')';
@@ -3416,7 +3416,6 @@ class Form
$opt .= "\n";
-
// Add new entry
// "key" value of json key array is used by jQuery automatically as selected value. Example: 'type' = product or service, 'price_ht' = unit price without tax
// "label" value of json key array is used by jQuery automatically as text for combo box
@@ -3427,7 +3426,11 @@ class Form
'value'=>$outref,
'label'=>$outval,
'qty'=>$outqty,
- 'price_ht'=>price2num($objp->unitprice, 'MT'),
+ 'price_qty_ht'=>price2num($objp->fprice, 'MU'), // Keep higher resolution for price for the min qty
+ 'price_unit_ht'=>price2num($objp->unitprice, 'MU'), // This is used to fill the Unit Price
+ 'price_ht'=>price2num($objp->unitprice, 'MU'), // This is used to fill the Unit Price (for compatibility)
+ 'tva_tx'=>$objp->tva_tx,
+ 'default_vat_code'=>$objp->default_vat_code,
'discount'=>$outdiscount,
'type'=>$outtype,
'duration_value'=>$outdurationvalue,
@@ -3662,7 +3665,7 @@ class Form
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
- * Charge dans cache la liste des délais de livraison possibles
+ * Load int a cache property th elist of possible delivery delays.
*
* @return int Nb of lines loaded, <0 if KO
*/
@@ -3671,7 +3674,7 @@ class Form
// phpcs:enable
global $langs;
- $num = count($this->cache_availability);
+ $num = count($this->cache_availability); // TODO Use $conf->cache['availability'] instead of $this->cache_availability
if ($num > 0) {
return 0; // Cache already loaded
}
@@ -3755,7 +3758,7 @@ class Form
{
global $langs;
- $num = count($this->cache_demand_reason);
+ $num = count($this->cache_demand_reason); // TODO Use $conf->cache['input_reason'] instead of $this->cache_demand_reason
if ($num > 0) {
return 0; // Cache already loaded
}
@@ -3851,7 +3854,7 @@ class Form
// phpcs:enable
global $langs;
- $num = count($this->cache_types_paiements);
+ $num = count($this->cache_types_paiements); // TODO Use $conf->cache['payment_mode'] instead of $this->cache_types_paiements
if ($num > 0) {
return $num; // Cache already loaded
}
@@ -4092,7 +4095,7 @@ class Form
// phpcs:enable
global $langs;
- $num = count($this->cache_transport_mode);
+ $num = count($this->cache_transport_mode); // TODO Use $conf->cache['payment_mode'] instead of $this->cache_transport_mode
if ($num > 0) {
return $num; // Cache already loaded
}
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index 80a9c75dffc..7ceca2f373b 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -1569,6 +1569,7 @@ class FormMail extends Form
// For mass emailing, we have different keys
$tmparray['__ID__'] = 'IdRecord';
+ $tmparray['__THIRDPARTY_CUSTOMER_CODE__'] = 'CustomerCode';
$tmparray['__EMAIL__'] = 'EMailRecipient';
$tmparray['__LASTNAME__'] = 'Lastname';
$tmparray['__FIRSTNAME__'] = 'Firstname';
diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php
index 25ab99bfe01..4f5557279f4 100644
--- a/htdocs/core/class/html.formsetup.class.php
+++ b/htdocs/core/class/html.formsetup.class.php
@@ -215,7 +215,7 @@ class FormSetup
$out = '
';
$out .= '';
$out .= '
';
- $out .= '
' . $this->langs->trans("Parameter") . '
';
+ $out .= '
' . $this->langs->trans("Parameter") . '
';
$out .= '
' . $this->langs->trans("Value") . '
';
$out .= '
';
$out .= '';
@@ -353,7 +353,8 @@ class FormSetup
*/
$item = new FormSetupItem($confKey);
- $item->setTypeFromTypeString($params['type']);
+ // need to be ignored from scrutinizer setTypeFromTypeString was created as deprecated to incite developper to use object oriented usage
+ /** @scrutinizer ignore-deprecated */ $item->setTypeFromTypeString($params['type']);
if (!empty($params['enabled'])) {
$item->enabled = $params['enabled'];
@@ -560,13 +561,16 @@ class FormSetupItem
/** @var string $helpText */
public $helpText = '';
- /** @var string $value */
+ /** @var string $fieldValue */
public $fieldValue;
+ /** @var array $fieldAttr fields attribute only for compatible fields like input text */
+ public $fieldAttr;
+
/** @var bool|string set this var to override field output will override $fieldInputOverride and $fieldOutputOverride too */
public $fieldOverride = false;
- /** @var bool|string set this var to override field output */
+ /** @var bool|string set this var to override field input */
public $fieldInputOverride = false;
/** @var bool|string set this var to override field output */
@@ -583,6 +587,7 @@ class FormSetupItem
/**
* TODO each type must have setAs{type} method to help configuration
* And set var as protected when its done configuration must be done by method
+ * this is important for retrocompatibility of futures versions
* @var string $type 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type'
*/
protected $type = 'string';
@@ -594,13 +599,19 @@ class FormSetupItem
/**
* Constructor
*
- * @param $confKey the conf key used in database
+ * @param string $confKey the conf key used in database
*/
public function __construct($confKey)
{
- global $langs, $db, $conf;
+ global $langs, $db, $conf, $form;
$this->db = $db;
- $this->form = new Form($this->db);
+
+ if (!empty($form) && is_object($form) && get_class($form) == 'Form') { // the form class has a cache inside so I am using it to optimize
+ $this->form = $form;
+ } else {
+ $this->form = new Form($this->db);
+ }
+
$this->langs = $langs;
$this->entity = $conf->entity;
@@ -700,6 +711,10 @@ class FormSetupItem
return $this->fieldInputOverride;
}
+ $this->fieldAttr['name'] = $this->confKey;
+ $this->fieldAttr['id'] = 'setup-'.$this->confKey;
+ $this->fieldAttr['value'] = $this->fieldValue;
+
$out = '';
if ($this->type == 'title') {
@@ -726,7 +741,9 @@ class FormSetupItem
$out.= $this->form->select_produits($selected, $this->confKey, '', 0, 0, 1, 2, '', 0, array(), 0, '1', 0, $this->cssClass, 0, '', null, 1);
}
} else {
- $out.= '';
+ if (empty($this->fieldAttr)) { $this->fieldAttr['class'] = 'flat '.(empty($this->cssClass) ? 'minwidth200' : $this->cssClass); }
+
+ $out.= 'fieldAttr).' />';
}
return $out;
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index c092690a505..f881447cd67 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -555,9 +555,9 @@ class Translate
* Return translated value of key for special keys ("Currency...", "Civility...", ...).
* Search in lang file, then into database. Key must be any complete entry into lang file: CurrencyEUR, ...
* If not found, return key.
- * The string return is not formated (translated with transnoentitiesnoconv)
- * NOTE: To avoid infinite loop (getLabelFromKey->transnoentities->getTradFromKey), if you modify this function,
- * check that getLabelFromKey is not called with same value than input.
+ * The string return is not formated (translated with transnoentitiesnoconv).
+ * NOTE: To avoid infinite loop (getLabelFromKey->transnoentities->getTradFromKey->getLabelFromKey), if you modify this function,
+ * check that getLabelFromKey is never called with the same value than $key.
*
* @param string $key Key to translate
* @return string Translated string (translated with transnoentitiesnoconv)
@@ -585,7 +585,7 @@ class Translate
$newstr = $this->getLabelFromKey($db, $reg[1], 'c_lead_status', 'code', 'label');
} elseif (preg_match('/^OrderSource([0-9A-Z]+)$/i', $key, $reg)) {
// TODO OrderSourceX must be replaced with content of table llx_c_input_reason or llx_c_input_method
- //$newstr=$this->getLabelFromKey($db,$reg[1],'c_ordersource','code','label');
+ //$newstr=$this->getLabelFromKey($db,$reg[1],'llx_c_input_reason','code','label');
}
/* Disabled. There is too many cases where translation of $newstr is not defined is normal (like when output with setEventMessage an already translated string)
@@ -945,9 +945,9 @@ class Translate
*
* @param DoliDB $db Database handler
* @param string $key Translation key to get label (key in language file)
- * @param string $tablename Table name without prefix
- * @param string $fieldkey Field for key
- * @param string $fieldlabel Field for label
+ * @param string $tablename Table name without prefix. This value must always be a hardcoded string and not a value coming from user input.
+ * @param string $fieldkey Field for key. This value must always be a hardcoded string and not a value coming from user input.
+ * @param string $fieldlabel Field for label. This value must always be a hardcoded string and not a value coming from user input.
* @param string $keyforselect Use another value than the translation key for the where into select
* @param int $filteronentity Use a filter on entity
* @return string Label in UTF8 (but without entities)
@@ -959,10 +959,15 @@ class Translate
if ($key == '') {
return '';
}
+ // Test should be useless because the 3 variables are never set from user input but we keep it in case of.
+ if (preg_match('/[^0-9A-Z_]/i', $tablename) || preg_match('/[^0-9A-Z_]/i', $fieldkey) || preg_match('/[^0-9A-Z_]/i', $fieldlabel)) {
+ $this->error = 'Bad value for parameter tablename, fieldkey or fieldlabel';
+ return -1;
+ }
//print 'param: '.$key.'-'.$keydatabase.'-'.$this->trans($key); exit;
- // Check if a translation is available (this can call getTradFromKey)
+ // Check if a translation is available (Note: this can call getTradFromKey that can call getLabelFromKey)
$tmp = $this->transnoentitiesnoconv($key);
if ($tmp != $key && $tmp != 'ErrorBadValueForParamNotAString') {
return $tmp; // Found in language array
@@ -973,6 +978,7 @@ class Translate
return $this->cache_labels[$tablename][$key]; // Found in cache
}
+ // Not found in loaded language file nor in cache. So we will take the label into database.
$sql = "SELECT ".$fieldlabel." as label";
$sql .= " FROM ".MAIN_DB_PREFIX.$tablename;
$sql .= " WHERE ".$fieldkey." = '".$db->escape($keyforselect ? $keyforselect : $key)."'";
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index e081c59b14b..b408985a92d 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -399,21 +399,23 @@ class Utils
if ($execmethod == 2) { // With this method, there is no way to get the return code, only output
$handlein = popen($fullcommandclear, 'r');
$i = 0;
- while (!feof($handlein)) {
- $i++; // output line number
- $read = fgets($handlein);
- // Exclude warning line we don't want
- if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) {
- continue;
- }
- fwrite($handle, $read);
- if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) {
- $ok = 1;
- } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) {
- $ok = 1;
+ if ($handlein) {
+ while (!feof($handlein)) {
+ $i++; // output line number
+ $read = fgets($handlein);
+ // Exclude warning line we don't want
+ if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) {
+ continue;
+ }
+ fwrite($handle, $read);
+ if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) {
+ $ok = 1;
+ } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) {
+ $ok = 1;
+ }
}
+ pclose($handlein);
}
- pclose($handlein);
}
diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php
index e806d9b5957..448677002df 100644
--- a/htdocs/core/lib/admin.lib.php
+++ b/htdocs/core/lib/admin.lib.php
@@ -240,6 +240,7 @@ function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handle
if (empty($nocommentremoval)) {
$buf = preg_replace('/([,;ERLT\)])\s*--.*$/i', '\1', $buf); //remove comment from a line that not start with -- before add it to the buffer
}
+ if ($buffer) $buffer .= ' ';
$buffer .= trim($buf);
}
@@ -639,7 +640,7 @@ function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules)
if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled)
//$head[$h][1] = $form->textwithpicto($langs->trans("AvailableModules"), $desc);
$head[$h][1] = $langs->trans("AvailableModules");
- $head[$h][1] .= $form->textwithpicto('', $langs->trans("YouMustEnableOneModule").'.