From c49745a68c3e812ac0c014e34744265347425c0b Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Fri, 17 Jul 2026 11:40:48 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Conditionally=20add=20`purchasable`=20to=20?= =?UTF-8?q?line=20item=E2=80=99s=20extra=20fields,=20to=20prevent=20except?= =?UTF-8?q?ions=20on=20to=20array?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/models/LineItem.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/LineItem.php b/src/models/LineItem.php index f76c7f93f5..d21fb0019e 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_filter([ 'lineItemStatus', 'order', - 'purchasable', + $this->type === LineItemType::Purchasable ? 'purchasable' : null, 'shippingCategory', 'snapshot', 'taxCategory', 'fulfilledTotalQuantity', - ]; + ]); } /** From bdcce223ff22a5b212951f42add3e876558d379e Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 21 Jul 2026 08:52:04 +0100 Subject: [PATCH 2/5] More specific filtering --- src/models/LineItem.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/LineItem.php b/src/models/LineItem.php index d21fb0019e..c5a7016720 100755 --- a/src/models/LineItem.php +++ b/src/models/LineItem.php @@ -669,7 +669,7 @@ public function fields(): array */ public function extraFields(): array { - return array_filter([ + return array_values(array_filter([ 'lineItemStatus', 'order', $this->type === LineItemType::Purchasable ? 'purchasable' : null, @@ -677,7 +677,7 @@ public function extraFields(): array 'snapshot', 'taxCategory', 'fulfilledTotalQuantity', - ]); + ], fn ($value) => $value !== null)); } /** From 83c6ce6daac080835953196e02213d18fd198682 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 21 Jul 2026 09:14:37 +0100 Subject: [PATCH 3/5] Add unit tests --- tests/unit/models/LineItemTest.php | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) 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']); + } } From ad3e10cff4977b7cb66bb07ce52fa913da0a5369 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 21 Jul 2026 09:14:59 +0100 Subject: [PATCH 4/5] fix cs --- src/models/LineItem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/LineItem.php b/src/models/LineItem.php index c5a7016720..4506cbd657 100755 --- a/src/models/LineItem.php +++ b/src/models/LineItem.php @@ -677,7 +677,7 @@ public function extraFields(): array 'snapshot', 'taxCategory', 'fulfilledTotalQuantity', - ], fn ($value) => $value !== null)); + ], fn($value) => $value !== null)); } /** From 203eb59b99b674c1ef472d0625dbdfcef0daba34 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 21 Jul 2026 09:19:16 +0100 Subject: [PATCH 5/5] changelog item [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) 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