FIX #34342 PHP 8.1 undefined array key warnings in Product::getSellPrice() multiprices (#37144)

When using multiprices (PRODUIT_MULTIPRICES or
PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES), getSellPrice() accesses
$this->multiprices[$level], multiprices_ttc, multiprices_min,
multiprices_min_ttc, and multiprices_base_type arrays using the
buyer's price_level as key without checking if the key exists.

This causes 'undefined array key' warnings on PHP 8.1+ when a
third party has a price_level set but the product doesn't have
prices defined for that specific level.

Similarly, prices_by_qty array accesses for PRODUIT_CUSTOMER_PRICES_BY_QTY
and PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES modes could trigger
warnings when the array index doesn't exist.

Changes:
- Add isset() checks with safe defaults for all multiprices array
  accesses (0 for prices, 'HT' for price_base_type)
- Replace direct prices_by_qty access with !empty() checks

Co-authored-by: f-hoedl <hoefla14@htl-kaindorf.ac.at>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
This commit is contained in:
minimexat 2026-02-08 15:08:58 +01:00 committed by GitHub
parent 28a7c69f11
commit f70eaae6f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2420,11 +2420,11 @@ class Product extends CommonObject
}
if (!$pricebycustomerexist && !empty($thirdparty_buyer->price_level)) {
$pu_ht = $this->multiprices[$thirdparty_buyer->price_level];
$pu_ttc = $this->multiprices_ttc[$thirdparty_buyer->price_level];
$price_min = $this->multiprices_min[$thirdparty_buyer->price_level];
$price_min_ttc = $this->multiprices_min_ttc[$thirdparty_buyer->price_level];
$price_base_type = $this->multiprices_base_type[$thirdparty_buyer->price_level];
$pu_ht = isset($this->multiprices[$thirdparty_buyer->price_level]) ? $this->multiprices[$thirdparty_buyer->price_level] : 0;
$pu_ttc = isset($this->multiprices_ttc[$thirdparty_buyer->price_level]) ? $this->multiprices_ttc[$thirdparty_buyer->price_level] : 0;
$price_min = isset($this->multiprices_min[$thirdparty_buyer->price_level]) ? $this->multiprices_min[$thirdparty_buyer->price_level] : 0;
$price_min_ttc = isset($this->multiprices_min_ttc[$thirdparty_buyer->price_level]) ? $this->multiprices_min_ttc[$thirdparty_buyer->price_level] : 0;
$price_base_type = isset($this->multiprices_base_type[$thirdparty_buyer->price_level]) ? $this->multiprices_base_type[$thirdparty_buyer->price_level] : 'HT';
if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) {
// using this option is a bug. kept for backward compatibility
if (isset($this->multiprices_tva_tx[$thirdparty_buyer->price_level])) {
@ -2439,11 +2439,11 @@ class Product extends CommonObject
}
}
} elseif (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($thirdparty_buyer->price_level)) { // // If price per segment
$pu_ht = $this->multiprices[$thirdparty_buyer->price_level];
$pu_ttc = $this->multiprices_ttc[$thirdparty_buyer->price_level];
$price_min = $this->multiprices_min[$thirdparty_buyer->price_level];
$price_min_ttc = $this->multiprices_min_ttc[$thirdparty_buyer->price_level];
$price_base_type = $this->multiprices_base_type[$thirdparty_buyer->price_level];
$pu_ht = isset($this->multiprices[$thirdparty_buyer->price_level]) ? $this->multiprices[$thirdparty_buyer->price_level] : 0;
$pu_ttc = isset($this->multiprices_ttc[$thirdparty_buyer->price_level]) ? $this->multiprices_ttc[$thirdparty_buyer->price_level] : 0;
$price_min = isset($this->multiprices_min[$thirdparty_buyer->price_level]) ? $this->multiprices_min[$thirdparty_buyer->price_level] : 0;
$price_min_ttc = isset($this->multiprices_min_ttc[$thirdparty_buyer->price_level]) ? $this->multiprices_min_ttc[$thirdparty_buyer->price_level] : 0;
$price_base_type = isset($this->multiprices_base_type[$thirdparty_buyer->price_level]) ? $this->multiprices_base_type[$thirdparty_buyer->price_level] : 'HT';
if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) {
// using this option is a bug. kept for backward compatibility
if (isset($this->multiprices_tva_tx[$thirdparty_buyer->price_level])) {
@ -2490,7 +2490,7 @@ class Product extends CommonObject
}
} elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY')) {
// If price per quantity
if ($this->prices_by_qty[0]) {
if (!empty($this->prices_by_qty[0])) {
// yes, this product has some prices per quantity
// Search price into product_price_by_qty from $this->id
foreach ($this->prices_by_qty_list[0] as $priceforthequantityarray) {
@ -2508,7 +2508,7 @@ class Product extends CommonObject
}
} elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
// If price per quantity and customer
if ($this->prices_by_qty[$thirdparty_buyer->price_level]) {
if (!empty($this->prices_by_qty[$thirdparty_buyer->price_level])) {
// yes, this product has some prices per quantity
// Search price into product_price_by_qty from $this->id
foreach ($this->prices_by_qty_list[$thirdparty_buyer->price_level] as $priceforthequantityarray) {