diff --git a/.github/workflows/exakat.yml b/.github/workflows/exakat.yml
index 90ba405e061..861f6ccd4b0 100644
--- a/.github/workflows/exakat.yml
+++ b/.github/workflows/exakat.yml
@@ -13,5 +13,5 @@ jobs:
- name: Exakat
uses: docker://exakat/exakat-ga
with:
- ignore_rules: 'Performances/PrePostIncrement,Functions/WrongNumberOfArguments,Variables/UndefinedVariable,Classes/DontUnsetProperties,Classes/NonPpp,Classes/StaticMethodsCalledFromObject,Classes/UseClassOperator,Functions/UsesDefaultArguments,Php/NoClassInGlobal,Php/ShouldUseCoalesce,Structures/MergeIfThen,Structures/ElseIfElseif,Structures/RepeatedPrint,Structures/UselessParenthesis'
+ ignore_rules: 'Classes/UseInstanceof,Performances/PrePostIncrement,Functions/WrongNumberOfArguments,Variables/UndefinedVariable,Classes/DontUnsetProperties,Classes/NonPpp,Classes/StaticMethodsCalledFromObject,Classes/UseClassOperator,Functions/UsesDefaultArguments,Php/NoClassInGlobal,Php/ShouldUseCoalesce,Structures/MergeIfThen,Structures/ElseIfElseif,Structures/RepeatedPrint,Structures/UselessParenthesis,Structures/SwitchWithoutDefault,Structures/ShouldMakeTernary,Structures/UseConstant'
ignore_dirs: '/htdocs/includes,/htdocs/build,/htdocs/dev,/htdocs/doc,/htdocs/scripts,/htdocs/test'
\ No newline at end of file
diff --git a/ChangeLog b/ChangeLog
index 62f28b9bd6e..ca5834f63f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,7 +23,7 @@ Following changes may create regressions for some external modules, but were nec
you must now also include declaration of the Trait 'CommonIncoterm' in your class. All incoterm functions were moved into this Trait.
* The GETPOST(..., 'alpha') has now the same behaviour than GETPOST(..., 'alphanohtml') so no html will be allowed. Use GETPOST(..., 'restricthtml') to accept HTML.
* If you have links in your code with '&action=delete' as a parameter, you must also add '&token='.newToken() as another parameter to avoid CSRF protection errors.
-
+* The API addPayment for api_invoice has evolved to accept amount into a foreign currency. You must provide array(amount=>X,mutlicurrency_ammount=>Y) instead of amount.
***** ChangeLog for 12.0.3 compared to 12.0.2 *****
FIX: 10.0 - when the mime file name is different from the filesystem name, the attachment name should be the mime filename
diff --git a/dev/initdata/purge-data.php b/dev/initdata/purge-data.php
index 183140af202..e6a67aa73c8 100755
--- a/dev/initdata/purge-data.php
+++ b/dev/initdata/purge-data.php
@@ -26,7 +26,7 @@
$sapi_type = php_sapi_name();
$script_file = basename(__FILE__);
-$path=dirname(__FILE__).'/';
+$path=__DIR__.'/';
// Test si mode batch
if (substr($sapi_type, 0, 3) == 'cgi') {
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index 1ac1e0f4ad4..e40a84db0ec 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -91,11 +91,7 @@ $hookmanager->initHooks(array('admin'));
// Put here declaration of dictionaries properties
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
-if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) {
- $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0);
-} else {
- $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 27, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0);
-}
+$taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0);
// Name of SQL tables of dictionaries
$tabname = array();
@@ -133,7 +129,6 @@ $tabname[30] = MAIN_DB_PREFIX."c_format_cards";
$tabname[32] = MAIN_DB_PREFIX."c_hrm_public_holiday";
$tabname[33] = MAIN_DB_PREFIX."c_hrm_department";
$tabname[34] = MAIN_DB_PREFIX."c_hrm_function";
-
$tabname[35] = MAIN_DB_PREFIX."c_exp_tax_cat";
$tabname[36] = MAIN_DB_PREFIX."c_exp_tax_range";
$tabname[37] = MAIN_DB_PREFIX."c_units";
@@ -485,8 +480,8 @@ $tabcond[35] = !empty($conf->expensereport->enabled);
$tabcond[36] = !empty($conf->expensereport->enabled);
$tabcond[37] = !empty($conf->product->enabled);
$tabcond[38] = !empty($conf->socialnetworks->enabled);
-$tabcond[39] = (! empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS));
-$tabcond[40] = ! empty($conf->societe->enabled);
+$tabcond[39] = (!empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && !empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES));
+$tabcond[40] = (!empty($conf->societe->enabled) && !empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES));
// List of help for fields
$tabhelp = array();
diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php
index 4b665123e4f..daa43110529 100644
--- a/htdocs/admin/security_file.php
+++ b/htdocs/admin/security_file.php
@@ -154,6 +154,9 @@ if (ini_get('safe_mode') && !empty($conf->global->MAIN_ANTIVIRUS_COMMAND))
}
}
print '';
+if (defined('MAIN_ANTIVIRUS_COMMAND')) {
+ print '
'.$langs->trans("ValueIsForcedBySystem").'';
+}
print "";
print '';
@@ -165,6 +168,9 @@ print ''.$langs->trans("AntiVirusParamExample").'';
print '
| ';
@@ -160,10 +160,10 @@ if (in_array($type, array('mysql', 'mysqli'))) {
print '';
print ' '; print ' ';
- print '';
+ print '';
print ' ';
} elseif (in_array($type, array('pgsql'))) {
- print '';
+ print ' ';
print '';
print ' ';
} else {
diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
index 2202ad5b67e..7ccbd8950b5 100644
--- a/htdocs/commande/class/api_orders.class.php
+++ b/htdocs/commande/class/api_orders.class.php
@@ -544,9 +544,10 @@ class Orders extends DolibarrApi
* Unlink a contact type of given order
*
* @param int $id Id of order to update
- * @param int $rowid Row key of the contact in the array contact_ids.
+ * @param int $contactid Id of contact
+ * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER).
*
- * @url DELETE {id}/contact/{rowid}
+ * @url DELETE {id}/contact/{contactid}/{type}
*
* @return int
*
@@ -554,7 +555,7 @@ class Orders extends DolibarrApi
* @throws RestException 404
* @throws RestException 500
*/
- public function deleteContact($id, $rowid)
+ public function deleteContact($id, $contactid, $type)
{
if (!DolibarrApiAccess::$user->rights->commande->creer) {
throw new RestException(401);
@@ -569,10 +570,16 @@ class Orders extends DolibarrApi
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- $result = $this->commande->delete_linked_contact($rowid);
+ $contacts = $this->commande->liste_contact();
- if (!$result) {
- throw new RestException(500, 'Error when deleted the contact');
+ foreach ($contacts as $contact) {
+ if ($contact['id'] == $contactid && $contact['code'] == $type) {
+ $result = $this->commande->delete_contact($contact['rowid']);
+
+ if (!$result) {
+ throw new RestException(500, 'Error when deleted the contact');
+ }
+ }
}
return array(
diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php
index a11f0f7c800..113068c447c 100644
--- a/htdocs/compta/facture/card-rec.php
+++ b/htdocs/compta/facture/card-rec.php
@@ -1365,6 +1365,8 @@ if ($action == 'create')
// Only on template invoices
$substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen").' ('.$langs->trans("Example").': '.dol_print_date(($object->date_when ? $object->date_when : dol_now()), 'dayhour').')';
$substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree(($object->date_when ? $object->date_when : dol_now()), $object->frequency, $object->unit_frequency), 'dayhour').')';
+ $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $object->nb_gen_done;
+ $substitutionarray['__INVOICE_COUNTER_MAX__'] = $object->nb_gen_max;
$htmltext = ''.$langs->trans("FollowingConstantsWillBeSubstituted").':'; foreach ($substitutionarray as $key => $val) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index cc1b7fe57ed..1c423a2e459 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -477,8 +477,9 @@ class Invoices extends DolibarrApi * * @param int $id Id of invoice to update * @param int $rowid Row key of the contact in the array contact_ids. + * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER). * - * @url DELETE {id}/contact/{rowid} + * @url DELETE {id}/contact/{rowid}/{type} * * @return array * @@ -486,7 +487,7 @@ class Invoices extends DolibarrApi * @throws RestException 404 * @throws RestException 500 */ - public function deleteContact($id, $rowid) + public function deleteContact($id, $rowid, $type) { if (!DolibarrApiAccess::$user->rights->facture->creer) { throw new RestException(401); @@ -502,10 +503,17 @@ class Invoices extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->invoice->delete_contact($rowid); - if ($result < 0) { - throw new RestException(500, 'Error when deleted the contact'); - } + $contacts = $this->invoice->liste_contact(); + + foreach ($contacts as $contact) { + if ($contact['id'] == $rowid && $contact['code'] == $type) { + $result = $this->invoice->delete_contact($contact['rowid']); + + if (!$result) { + throw new RestException(500, 'Error when deleted the contact'); + } + } + } return $this->_cleanObjectDatas($this->invoice); } @@ -1397,28 +1405,29 @@ class Invoices extends DolibarrApi /** * Add a payment to pay partially or completely one or several invoices. * Warning: Take care that all invoices are owned by the same customer. - * Example of value for parameter arrayofamounts: {"1": "99.99", "2": "10"} + * Example of value for parameter arrayofamounts: {"1": {"amount": "99.99", "multicurrency_amount": ""}, "2": {"amount": "", "multicurrency_amount": "10"}} * * @param array $arrayofamounts {@from body} Array with id of invoices with amount to pay for each invoice * @param string $datepaye {@from body} Payment date {@type timestamp} - * @param int $paymentid {@from body} Payment mode Id {@min 1} - * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} - * @param int $accountid {@from body} Account Id {@min 1} - * @param string $num_payment {@from body} Payment number (optional) - * @param string $comment {@from body} Note private (optional) - * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') - * @param string $chqbank {@from body} Issuer bank name (optional) + * @param int $paymentid {@from body} Payment mode Id {@min 1} + * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} + * @param int $accountid {@from body} Account Id {@min 1} + * @param string $num_payment {@from body} Payment number (optional) + * @param string $comment {@from body} Note private (optional) + * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') + * @param string $chqbank {@from body} Issuer bank name (optional) + * @param string $ref_ext {@from body} External reference (optional) + * @param bool $accepthigherpayment {@from body} Accept higher payments that it remains to be paid (optional) * * @url POST /paymentsdistributed * * @return int Payment ID - * * @throws RestException 400 * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ - public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '') + public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $ref_ext = '', $accepthigherpayment = false) { global $conf; @@ -1451,7 +1460,7 @@ class Invoices extends DolibarrApi $multicurrency_amounts = array(); // Loop on each invoice to pay - foreach ($arrayofamounts as $id => $amount) + foreach ($arrayofamounts as $id => $amountarray) { $result = $this->invoice->fetch($id); if (!$result) { @@ -1459,33 +1468,52 @@ class Invoices extends DolibarrApi throw new RestException(404, 'Invoice ID '.$id.' not found'); } - // Calculate amount to pay - $totalpaye = $this->invoice->getSommePaiement(); - $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); - $totaldeposits = $this->invoice->getSumDepositsUsed(); - $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); - if ($amount != 'remain') - { - if ($amount > $resteapayer) - { - $this->db->rollback(); - throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$resteapayer.')'); - } - $resteapayer = $amount; + if (($amountarray["amount"] == "remain" || $amountarray["amount"] > 0) && ($amountarray["multicurrency_amount"] == "remain" || $amountarray["multicurrency_amount"] > 0)) { + $this->db->rollback(); + throw new RestException(400, 'Payment in both currency '.$id.' ( amount: '.$amountarray["amount"].', multicurrency_amount: '.$amountarray["multicurrency_amount"].')'); } - // Clean parameters amount if payment is for a credit note - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $resteapayer = price2num($resteapayer, 'MT'); - $amounts[$id] = -$resteapayer; + + $is_multicurrency = 0; + $total_ttc = $this->invoice->total_ttc; + + if ($amountarray["multicurrency_amount"] > 0 || $amountarray["multicurrency_amount"] == "remain") { + $is_multicurrency = 1; + $total_ttc = $this->invoice->multicurrency_total_ttc; + } + + // Calculate amount to pay + $totalpaye = $this->invoice->getSommePaiement($is_multicurrency); + $totalcreditnotes = $this->invoice->getSumCreditNotesUsed($is_multicurrency); + $totaldeposits = $this->invoice->getSumDepositsUsed($is_multicurrency); + $remainstopay = $amount = price2num($total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + + if (!$is_multicurrency && $amountarray["amount"] != 'remain') + { + $amount = price2num($amountarray["amount"], 'MT'); + } + + if ($is_multicurrency && $amountarray["multicurrency_amount"] != 'remain') + { + $amount = price2num($amountarray["multicurrency_amount"], 'MT'); + } + + if ($amount > $remainstopay && $accepthigherpayment == false) { + $this->db->rollback(); + throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')'); + } + + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { + $amount = -$amount; + } + + if ($is_multicurrency) { + $amounts[$id] = null; // Multicurrency - $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); - $multicurrency_amounts[$id] = -$newvalue; + $multicurrency_amounts[$id] = $amount; } else { - $resteapayer = price2num($resteapayer, 'MT'); - $amounts[$id] = $resteapayer; + $amounts[$id] = $amount; // Multicurrency - $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); - $multicurrency_amounts[$id] = $newvalue; + $multicurrency_amounts[$id] = null; } } @@ -1498,7 +1526,7 @@ class Invoices extends DolibarrApi $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1); $paymentobj->num_payment = $num_payment; $paymentobj->note_private = $comment; - + $paymentobj->ref_ext = $ref_ext; $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices if ($payment_id < 0) { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 4110e5ad26d..8ec349c79f4 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -458,7 +458,7 @@ class Facture extends CommonInvoice $nextdatewhen = null; $previousdaynextdatewhen = null; - // Create invoice from a template invoice + // Create invoice from a template recurring invoice if ($this->fac_rec > 0) { $this->fk_fac_rec_source = $this->fac_rec; diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 6b1b5e0ea0a..02cc5bae399 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -287,6 +287,18 @@ $dolibarr_cron_allow_cli='0'; // Examples: '-1' (sending by cli is forbidden) // $dolibarr_mailing_limit_sendbycli='0'; +// MAIN_ANTIVIRUS_COMMAND (as a constant) +// Force a value for the antivirus command line tool so setup for admin user interface has no effect. +// Default value: '' +// Example: '/usr/bin/clamdscan'; +// define('MAIN_ANTIVIRUS_COMMAND', '/usr/bin/clamdscan'); + +// MAIN_ANTIVIRUS_PARAM (as a constant) +// Force a value for the antivirus parameters on command line so setup for admin user interface has no effect. +// Default value: '' +// Example: '--fdpass'; +// define('MAIN_ANTIVIRUS_PARAM', '--fdpass'); + //################## // Other diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 80589e4c4f3..fd179dec7b6 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -170,29 +170,6 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box } } - - /** - * Standard method to get content of a box - * - * @param array $head Array with properties of box title - * @param array $contents Array with properties of box lines - * - * @return string - */ - public function outputBox($head = null, $contents = null) - { - global $langs, $user, $conf; - - // Trick to get result into a var from a function that makes print instead of return - // TODO Replace ob_start with param nooutput=1 into showBox - ob_start(); - $result = $this->showBox($head, $contents); - $output = ob_get_contents(); - ob_end_clean(); - - return $output; - } - /** * Standard method to show a box (usage by boxes not mandatory, a box can still use its own showBox function) * diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 8cfeea86d95..32d7b145a41 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -684,6 +684,9 @@ class Conf // If we are in develop mode, we activate the option MAIN_SECURITY_CSRF_WITH_TOKEN to 1 if not already defined. if (!isset($this->global->MAIN_SECURITY_CSRF_WITH_TOKEN) && $this->global->MAIN_FEATURES_LEVEL >= 2) $this->global->MAIN_SECURITY_CSRF_WITH_TOKEN = 1; + if (defined('MAIN_ANTIVIRUS_COMMAND')) $this->global->MAIN_ANTIVIRUS_COMMAND = constant('MAIN_ANTIVIRUS_COMMAND'); + if (defined('MAIN_ANTIVIRUS_PARAM')) $this->global->MAIN_ANTIVIRUS_PARAM = constant('MAIN_ANTIVIRUS_PARAM'); + // For backward compatibility if (isset($this->product)) $this->produit = $this->product; if (isset($this->facture)) $this->invoice = $this->facture; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 84960b21832..3f4938360e0 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1916,13 +1916,16 @@ class Form * 'warehouseclosed' = count products from closed warehouses, * 'warehouseinternal' = count products from warehouses for internal correct/transfer only * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) - * @return void + * @param string $nooutput No print, return the output into a string + * @return void|string */ - public function select_produits($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $selected_combinations = array()) + public function select_produits($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $selected_combinations = array(), $nooutput = 0) { // phpcs:enable global $langs, $conf; + $out = ''; + // check parameters $price_level = (!empty($price_level) ? $price_level : 0); if (is_null($ajaxoptions)) $ajaxoptions = array(); @@ -1962,100 +1965,103 @@ class Form if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { $urloption .= '&socid='.$socid; } - print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); if (!empty($conf->variants->enabled)) { - ?> + $out .= ' - trans("RefOrLabel").' : '; + + if (empty($hidelabel)) $out .= $langs->trans("RefOrLabel").' : '; elseif ($hidelabel > 1) { $placeholder = ' placeholder="'.$langs->trans("RefOrLabel").'"'; if ($hidelabel == 2) { - print img_picto($langs->trans("Search"), 'search'); + $out .= img_picto($langs->trans("Search"), 'search'); } } - print 'global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; + $out .= 'global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; if ($hidelabel == 3) { - print img_picto($langs->trans("Search"), 'search'); + $out .= img_picto($langs->trans("Search"), 'search'); } } else { - print $this->select_produits_list($selected, $htmlname, $filtertype, $limit, $price_level, '', $status, $finished, 0, $socid, $showempty, $forcecombo, $morecss, $hidepriceinlabel, $warehouseStatus); + $out .= $this->select_produits_list($selected, $htmlname, $filtertype, $limit, $price_level, '', $status, $finished, 0, $socid, $showempty, $forcecombo, $morecss, $hidepriceinlabel, $warehouseStatus); } + + if (empty($nooutput)) print $out; + else return $out; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return list of products for a customer + * Return list of products for a customer. + * Called by select_produits. * * @param int $selected Preselected product * @param string $htmlname Name of select html @@ -2262,7 +2268,7 @@ class Form $sql .= $this->db->plimit($limit, 0); // Build output string - dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG); + dol_syslog(get_class($this)."::select_produits_list search products", LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -2308,7 +2314,7 @@ class Form $sql .= " WHERE fk_product_price=".$objp->price_rowid; $sql .= " ORDER BY quantity ASC"; - dol_syslog(get_class($this)."::select_produits_list search price by qty", LOG_DEBUG); + dol_syslog(get_class($this)."::select_produits_list search prices by qty", LOG_DEBUG); $result2 = $this->db->query($sql); if ($result2) { diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 7264c83b152..2b98bac30c6 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -114,6 +114,9 @@ class FormFile if (empty($usewithoutform)) // Try to avoid this and set instead the form by the caller. { + // Add a param as GET parameter to detect when POST were cleaned by PHP because a file larger than post_max_size + $url .= (strpos('?', $url) === false ? '?' : '&').'uploadform=1'; + $out .= ' |