diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cc0f09e2..5900a41f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Fixed a bug where product variant field layout tabs displayed incorrectly on variant slideouts. ([#4335](https://github.com/craftcms/commerce/issues/4335)) +- Fixed a PHP error that could occur when serializing a line item object. ([#4337](https://github.com/craftcms/commerce/issues/4337)) ## 5.7.0 - 2026-07-16 diff --git a/src/models/LineItem.php b/src/models/LineItem.php index f76c7f93f5..4506cbd657 100755 --- a/src/models/LineItem.php +++ b/src/models/LineItem.php @@ -669,15 +669,15 @@ public function fields(): array */ public function extraFields(): array { - return [ + return array_values(array_filter([ 'lineItemStatus', 'order', - 'purchasable', + $this->type === LineItemType::Purchasable ? 'purchasable' : null, 'shippingCategory', 'snapshot', 'taxCategory', 'fulfilledTotalQuantity', - ]; + ], fn($value) => $value !== null)); } /** diff --git a/tests/unit/models/LineItemTest.php b/tests/unit/models/LineItemTest.php index 4944f2a91d..825a2a28aa 100644 --- a/tests/unit/models/LineItemTest.php +++ b/tests/unit/models/LineItemTest.php @@ -213,4 +213,53 @@ public function testCustomLineItem(): void self::assertEquals(20.00, $order->getTotal()); } + + /** + * @return void + * @since 5.1.0 + */ + public function testCustomLineItemToArrayDoesNotThrow(): void + { + $lineItem = new LineItem(); + $lineItem->type = LineItemType::Custom; + $lineItem->description = 'Custom'; + $lineItem->setSku('custom-sku'); + $lineItem->setPrice(10.00); + $lineItem->qty = 2; + + $order = new Order(); + $order->number = Plugin::getInstance()->getCarts()->generateCartNumber(); + $order->setLineItems([$lineItem]); + + self::assertNotContains('purchasable', $lineItem->extraFields()); + + $data = $lineItem->toArray([], ['*']); + self::assertIsArray($data); + + $data = $lineItem->toArray([], ['purchasable']); + self::assertIsArray($data); + self::assertArrayNotHasKey('purchasable', $data); + } + + /** + * @return void + * @since 5.1.0 + */ + public function testPurchasableLineItemToArrayIncludesPurchasable(): void + { + $variant = Variant::find()->sku('rad-hood')->one(); + $lineItem = new LineItem(); + $lineItem->populateFromPurchasable($variant); + $lineItem->qty = 1; + + $order = new Order(); + $order->number = Plugin::getInstance()->getCarts()->generateCartNumber(); + $order->setLineItems([$lineItem]); + + self::assertContains('purchasable', $lineItem->extraFields()); + + $data = $lineItem->toArray([], ['purchasable']); + self::assertArrayHasKey('purchasable', $data); + self::assertNotNull($data['purchasable']); + } }