From 548f96ff37eba0e44607a956439906ae425ac31d Mon Sep 17 00:00:00 2001 From: Doug Wright Date: Mon, 5 Dec 2022 19:33:15 +0000 Subject: [PATCH] Backport #356 to 3.x --- CHANGELOG.md | 5 +++++ src/PackedBox.php | 28 ++++++++++++++++++++++------ src/PackedItem.php | 31 ++++++++++++++++++++++++------- tests/PackedBoxListTest.php | 2 +- tests/PackedBoxTest.php | 2 +- tests/PackedItemTest.php | 2 +- 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb5aaee..652b995a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## [3.x - Unreleased] - 2022-xx-xx +### Changed +- Calling `json_encode()` on a `PackedBox` or `PackedItem` now additionally serialises the entire underlying + `Box`/`Item` where those objects also implement `JsonSerializable`. Previously the serialisation only included the + key values from the `Box`/`Item` interfaces themselves. + ## [3.10.0] - 2022-09-10 ### Added - Added `ItemSorter`, `BoxSorter` and `PackedBoxSorter` to allow calling applications to have better control over diff --git a/src/PackedBox.php b/src/PackedBox.php index edf1d7be..03f53363 100644 --- a/src/PackedBox.php +++ b/src/PackedBox.php @@ -14,6 +14,8 @@ use function iterator_to_array; use function max; use function round; +use function array_merge; +use function is_array; /** * A "box" with items. @@ -216,13 +218,27 @@ public function __construct(Box $box, PackedItemList $packedItemList) #[ReturnTypeWillChange] public function jsonSerialize()/* : mixed */ { + $userValues = []; + + if ($this->box instanceof JsonSerializable) { + $userSerialisation = $this->box->jsonSerialize(); + if (is_array($userSerialisation)) { + $userValues = $userSerialisation; + } else { + $userValues = ['extra' => $userSerialisation]; + } + } + return [ - 'box' => [ - 'reference' => $this->box->getReference(), - 'innerWidth' => $this->box->getInnerWidth(), - 'innerLength' => $this->box->getInnerLength(), - 'innerDepth' => $this->box->getInnerDepth(), - ], + 'box' => array_merge( + $userValues, + [ + 'reference' => $this->box->getReference(), + 'innerWidth' => $this->box->getInnerWidth(), + 'innerLength' => $this->box->getInnerLength(), + 'innerDepth' => $this->box->getInnerDepth(), + ] + ), 'items' => iterator_to_array($this->items), ]; } diff --git a/src/PackedItem.php b/src/PackedItem.php index 3adde26d..b915145b 100644 --- a/src/PackedItem.php +++ b/src/PackedItem.php @@ -11,6 +11,9 @@ use JsonSerializable; use ReturnTypeWillChange; +use function array_merge; +use function is_array; + /** * A packed item. * @@ -131,6 +134,17 @@ public function toOrientatedItem(): OrientatedItem #[ReturnTypeWillChange] public function jsonSerialize()/* : mixed */ { + $userValues = []; + + if ($this->item instanceof JsonSerializable) { + $userSerialisation = $this->item->jsonSerialize(); + if (is_array($userSerialisation)) { + $userValues = $userSerialisation; + } else { + $userValues = ['extra' => $userSerialisation]; + } + } + return [ 'x' => $this->x, 'y' => $this->y, @@ -138,13 +152,16 @@ public function jsonSerialize()/* : mixed */ 'width' => $this->width, 'length' => $this->length, 'depth' => $this->depth, - 'item' => [ - 'description' => $this->item->getDescription(), - 'width' => $this->item->getWidth(), - 'length' => $this->item->getLength(), - 'depth' => $this->item->getDepth(), - 'keepFlat' => $this->item->getKeepFlat(), - ], + 'item' => array_merge( + $userValues, + [ + 'description' => $this->item->getDescription(), + 'width' => $this->item->getWidth(), + 'length' => $this->item->getLength(), + 'depth' => $this->item->getDepth(), + 'keepFlat' => $this->item->getKeepFlat(), + ] + ), ]; } } diff --git a/tests/PackedBoxListTest.php b/tests/PackedBoxListTest.php index d228203b..3e43cfd2 100644 --- a/tests/PackedBoxListTest.php +++ b/tests/PackedBoxListTest.php @@ -190,6 +190,6 @@ public function testJsonSerialize(): void $packedBoxList = new PackedBoxList(); $packedBoxList->insert($packedBox); - self::assertJsonStringEqualsJsonString('[{"box":{"reference":"Box","innerWidth":10,"innerLength":10,"innerDepth":20},"items":[{"x":0,"y":0,"z":0,"width":4,"length":10,"depth":10,"item":{"description":"Item","width":4,"length":10,"depth":10,"keepFlat":true}}]}]', json_encode($packedBoxList)); + self::assertJsonStringEqualsJsonString('[{"box":{"reference":"Box","innerWidth":10,"innerLength":10,"innerDepth":20,"maxWeight":10,"emptyWeight":10},"items":[{"x":0,"y":0,"z":0,"width":4,"length":10,"depth":10,"item":{"description":"Item","width":4,"length":10,"depth":10,"keepFlat":true,"weight":10}}]}]', json_encode($packedBoxList)); } } diff --git a/tests/PackedBoxTest.php b/tests/PackedBoxTest.php index 2e4a7c21..5278bf7d 100644 --- a/tests/PackedBoxTest.php +++ b/tests/PackedBoxTest.php @@ -98,6 +98,6 @@ public function testJsonSerialize(): void $packedBox = new PackedBox($box, $boxItems); - self::assertJsonStringEqualsJsonString('{"box":{"reference":"Box","innerWidth":10,"innerLength":10,"innerDepth":20},"items":[{"x":0,"y":0,"z":0,"width":4,"length":10,"depth":10,"item":{"description":"Item","width":4,"length":10,"depth":10,"keepFlat":true}}]}', json_encode($packedBox)); + self::assertJsonStringEqualsJsonString('{"box":{"reference":"Box","innerWidth":10,"innerLength":10,"innerDepth":20,"maxWeight":10,"emptyWeight":10},"items":[{"x":0,"y":0,"z":0,"width":4,"length":10,"depth":10,"item":{"description":"Item","width":4,"length":10,"depth":10,"keepFlat":true,"weight":10}}]}', json_encode($packedBox)); } } diff --git a/tests/PackedItemTest.php b/tests/PackedItemTest.php index a7fba622..e581cc77 100644 --- a/tests/PackedItemTest.php +++ b/tests/PackedItemTest.php @@ -33,6 +33,6 @@ public function testVolumeCalculation(): void public function testJsonSerialize(): void { $packedItem = new PackedItem(new TestItem('Item', 1, 2, 3, 10, false), 100, 20, 300, 3, 5, 7); - self::assertJsonStringEqualsJsonString('{"x":100,"y":20,"z":300,"width":3,"length":5,"depth":7,"item":{"description":"Item","width":1,"length":2,"depth":3,"keepFlat":false}}', json_encode($packedItem)); + self::assertJsonStringEqualsJsonString('{"x":100,"y":20,"z":300,"width":3,"length":5,"depth":7,"item":{"description":"Item","width":1,"length":2,"depth":3,"keepFlat":false, "weight":10}}', json_encode($packedItem)); } }