1 | <?php |
||
19 | class Packer implements LoggerAwareInterface |
||
20 | { |
||
21 | use LoggerAwareTrait; |
||
22 | |||
23 | const MAX_BOXES_TO_BALANCE_WEIGHT = 12; |
||
24 | |||
25 | /** |
||
26 | * List of items to be packed |
||
27 | * @var ItemList |
||
28 | */ |
||
29 | protected $items; |
||
30 | |||
31 | /** |
||
32 | * List of box sizes available to pack items into |
||
33 | * @var BoxList |
||
34 | */ |
||
35 | protected $boxes; |
||
36 | |||
37 | /** |
||
38 | * Constructor |
||
39 | */ |
||
40 | 25 | public function __construct() |
|
41 | { |
||
42 | 25 | $this->items = new ItemList(); |
|
43 | 25 | $this->boxes = new BoxList(); |
|
44 | |||
45 | 25 | $this->logger = new NullLogger(); |
|
46 | } |
||
47 | |||
48 | /** |
||
49 | * Add item to be packed |
||
50 | * @param Item $item |
||
51 | * @param int $qty |
||
52 | */ |
||
53 | 25 | public function addItem(Item $item, $qty = 1) |
|
54 | { |
||
55 | 25 | for ($i = 0; $i < $qty; $i++) { |
|
56 | 25 | $this->items->insert($item); |
|
57 | } |
||
58 | 25 | $this->logger->log(LogLevel::INFO, "added {$qty} x {$item->getDescription()}"); |
|
59 | } |
||
60 | |||
61 | /** |
||
62 | * Set a list of items all at once |
||
63 | * @param \Traversable|array $items |
||
64 | */ |
||
65 | 1 | public function setItems($items) |
|
66 | { |
||
67 | 1 | if ($items instanceof ItemList) { |
|
68 | $this->items = clone $items; |
||
69 | } else { |
||
70 | 1 | $this->items = new ItemList(); |
|
71 | 1 | foreach ($items as $item) { |
|
72 | 1 | $this->items->insert($item); |
|
73 | } |
||
74 | } |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Add box size |
||
79 | * @param Box $box |
||
80 | */ |
||
81 | 24 | public function addBox(Box $box) |
|
82 | { |
||
83 | 24 | $this->boxes->insert($box); |
|
84 | 24 | $this->logger->log(LogLevel::INFO, "added box {$box->getReference()}"); |
|
85 | } |
||
86 | |||
87 | /** |
||
88 | * Add a pre-prepared set of boxes all at once |
||
89 | * @param BoxList $boxList |
||
90 | */ |
||
91 | 1 | public function setBoxes(BoxList $boxList) |
|
95 | |||
96 | /** |
||
97 | * Pack items into boxes |
||
98 | * |
||
99 | * @return PackedBoxList |
||
100 | */ |
||
101 | 25 | public function pack() |
|
102 | { |
||
103 | 25 | $packedBoxes = $this->doVolumePacking(); |
|
104 | |||
105 | //If we have multiple boxes, try and optimise/even-out weight distribution |
||
106 | 23 | if ($packedBoxes->count() > 1 && $packedBoxes->count() < static::MAX_BOXES_TO_BALANCE_WEIGHT) { |
|
107 | 5 | $redistributor = new WeightRedistributor($this->boxes); |
|
108 | 5 | $redistributor->setLogger($this->logger); |
|
109 | 5 | $packedBoxes = $redistributor->redistributeWeight($packedBoxes); |
|
110 | } |
||
111 | |||
112 | 23 | $this->logger->log(LogLevel::INFO, "packing completed, {$packedBoxes->count()} boxes"); |
|
113 | 23 | return $packedBoxes; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * Pack items into boxes using the principle of largest volume item first |
||
118 | * |
||
119 | * @throws ItemTooLargeException |
||
120 | * @return PackedBoxList |
||
121 | */ |
||
122 | 25 | public function doVolumePacking() |
|
177 | |||
178 | /** |
||
179 | * Pack as many items as possible into specific given box |
||
180 | * |
||
181 | * @deprecated |
||
182 | * @param Box $box |
||
183 | * @param ItemList $items |
||
184 | * @return PackedBox packed box |
||
185 | */ |
||
186 | public function packIntoBox(Box $box, ItemList $items) |
||
192 | |||
193 | /** |
||
194 | * Pack as many items as possible into specific given box |
||
195 | * @deprecated |
||
196 | * @param Box $box |
||
197 | * @param ItemList $items |
||
198 | * @return ItemList items packed into box |
||
199 | */ |
||
200 | public function packBox(Box $box, ItemList $items) |
||
205 | |||
206 | /** |
||
207 | * Given a solution set of packed boxes, repack them to achieve optimum weight distribution |
||
208 | * |
||
209 | * @deprecated |
||
210 | * @param PackedBoxList $originalBoxes |
||
211 | * @return PackedBoxList |
||
212 | */ |
||
213 | public function redistributeWeight(PackedBoxList $originalBoxes) |
||
219 | } |
||
220 |
This method has been deprecated.