Skip to content

Commit d8e165f

Browse files
committed
- [0007915]: Fix fatal error "Call to a member function getId() on null" on product detail page when an out-of-stock variant is in the basket. hasProductVariantInBasket() delegated to Basket::getArtStockInBasket() which calls getArticle(true) (buyable-check). For out-of-stock variants this returns null. Replaced with direct basket iteration using getArticle(false) to skip the buyable check.
1 parent 020f814 commit d8e165f

2 files changed

Lines changed: 13 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88

99
### FIX
1010

11+
- [0007915](https://bugs.oxid-esales.com/view.php?id=7915): Fix fatal error "Call to a member function getId() on null" on product detail page when an out-of-stock variant is in the basket. `hasProductVariantInBasket()` delegated to `Basket::getArtStockInBasket()` which calls `getArticle(true)` (buyable-check). For out-of-stock variants this returns null. Replaced with direct basket iteration using `getArticle(false)` to skip the buyable check.
1112
- [0007916](https://bugs.oxid-esales.com/view.php?id=7916): Fix orphaned oscpaypal_order rows with OSCPAYPALSTATUS=COMPLETED and empty OXORDERID. When `sess_challenge` was cleared before `captureOrder()` completed (e.g. by a concurrent cancel request), the capture flow proceeded and created tracking records that could not be matched by webhook processing. Added defense-in-depth validation at four levels: `AjaxPaymentController::captureOrder()` now aborts if the shop order cannot be resolved, `PayPalOrderCompletedSubscriber` rejects events with empty shopOrderId, `Payment::trackPayPalOrder()` throws on empty shopOrderId, and `OrderRepository::paypalOrderByOrderIdAndPayPalId()` refuses to create new records with empty shopOrderId.
1213

1314
## [3.7.1] - 2026-03-19

src/Model/Basket.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,17 +252,22 @@ public function getPayPalCheckoutRoundDiff()
252252
*/
253253
public function hasProductVariantInBasket(\OxidEsales\Eshop\Application\Model\Article $product)
254254
{
255-
$return = false;
256-
257255
$variantIds = $product->getVariantIds();
258-
foreach ($variantIds as $id) {
259-
if ($this->getArtStockInBasket($id)) {
260-
$return = true;
261-
break;
256+
if (empty($variantIds)) {
257+
return false;
258+
}
259+
260+
$variantIdMap = array_flip($variantIds);
261+
foreach ($this->getContents() as $basketItem) {
262+
// Use getArticle(false) to skip the buyable check – out-of-stock
263+
// variants that are still in the basket must not cause a fatal error.
264+
$article = $basketItem->getArticle(false);
265+
if ($article && isset($variantIdMap[$article->getId()])) {
266+
return true;
262267
}
263268
}
264269

265-
return $return;
270+
return false;
266271
}
267272

268273
/**

0 commit comments

Comments
 (0)