Passed
Push — 2.x-dev ( eccc16...ab1c97 )
by Doug
07:42
created

PackedBox::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 9
dl 0
loc 20
ccs 10
cts 10
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
namespace DVDoug\BoxPacker;
8
9
/**
10
 * A "box" with items.
11
 *
12
 * @author Doug Wright
13
 */
14
class PackedBox
15
{
16
    /**
17
     * Box used.
18
     *
19
     * @var Box
20
     */
21
    protected $box;
22
23
    /**
24
     * Items in the box.
25
     *
26
     * @var ItemList
27
     */
28
    protected $items;
29
30
    /**
31
     * Total weight of box.
32
     *
33
     * @var int
34
     */
35
    protected $weight;
36
37
    /**
38
     * Total weight of items in the box.
39
     *
40
     * @var int
41
     */
42
    protected $itemWeight;
43
44
    /**
45
     * Remaining width inside box for another item.
46
     *
47
     * @var int
48
     */
49
    protected $remainingWidth;
50
51
    /**
52
     * Remaining length inside box for another item.
53
     *
54
     * @var int
55
     */
56
    protected $remainingLength;
57
58
    /**
59
     * Remaining depth inside box for another item.
60
     *
61
     * @var int
62
     */
63
    protected $remainingDepth;
64
65
    /**
66
     * Remaining weight inside box for another item.
67
     *
68
     * @var int
69
     */
70
    protected $remainingWeight;
71
72
    /**
73
     * Used width inside box for packing items.
74
     *
75
     * @var int
76
     */
77
    protected $usedWidth;
78
79
    /**
80
     * Used length inside box for packing items.
81
     *
82
     * @var int
83
     */
84
    protected $usedLength;
85
86
    /**
87
     * Used depth inside box for packing items.
88
     *
89
     * @var int
90
     */
91
    protected $usedDepth;
92
93
    /**
94
     * @var PackedItemList
95
     */
96
    protected $packedItemList;
97
98
    /**
99
     * Get box used.
100
     *
101
     * @return Box
102
     */
103 8
    public function getBox()
104
    {
105 8
        return $this->box;
106
    }
107
108
    /**
109
     * Get items packed.
110
     *
111
     * @return ItemList
112
     */
113 52
    public function getItems()
114
    {
115 52
        return $this->items;
116
    }
117
118
    /**
119
     * Get packed weight.
120
     *
121
     * @return int weight in grams
122
     */
123 10
    public function getWeight()
124
    {
125 10
        return $this->box->getEmptyWeight() + $this->getItemWeight();
126
    }
127
128
    /**
129
     * Get packed weight of the items only.
130
     *
131
     * @return int weight in grams
132
     */
133 11
    public function getItemWeight()
134
    {
135 11
        if (!is_null($this->itemWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->itemWeight) is always false.
Loading history...
136 9
            return $this->itemWeight;
137
        }
138 11
        $this->itemWeight = 0;
139
        /** @var Item $item */
140 11
        foreach (clone $this->items as $item) {
141 11
            $this->itemWeight += $item->getWeight();
142
        }
143
144 11
        return $this->itemWeight;
145
    }
146
147
    /**
148
     * Get remaining width inside box for another item.
149
     *
150
     * @return int
151
     */
152 1
    public function getRemainingWidth()
153
    {
154 1
        return $this->remainingWidth;
155
    }
156
157
    /**
158
     * Get remaining length inside box for another item.
159
     *
160
     * @return int
161
     */
162 1
    public function getRemainingLength()
163
    {
164 1
        return $this->remainingLength;
165
    }
166
167
    /**
168
     * Get remaining depth inside box for another item.
169
     *
170
     * @return int
171
     */
172 1
    public function getRemainingDepth()
173
    {
174 1
        return $this->remainingDepth;
175
    }
176
177
    /**
178
     * Used width inside box for packing items.
179
     *
180
     * @return int
181
     */
182 4
    public function getUsedWidth()
183
    {
184 4
        return $this->usedWidth;
185
    }
186
187
    /**
188
     * Used length inside box for packing items.
189
     *
190
     * @return int
191
     */
192 4
    public function getUsedLength()
193
    {
194 4
        return $this->usedLength;
195
    }
196
197
    /**
198
     * Used depth inside box for packing items.
199
     *
200
     * @return int
201
     */
202 4
    public function getUsedDepth()
203
    {
204 4
        return $this->usedDepth;
205
    }
206
207
    /**
208
     * Get remaining weight inside box for another item.
209
     *
210
     * @return int
211
     */
212 1
    public function getRemainingWeight()
213
    {
214 1
        return $this->remainingWeight;
215
    }
216
217
    /**
218
     * @return int
219
     */
220 10
    public function getInnerVolume()
221
    {
222 10
        return $this->box->getInnerWidth() * $this->box->getInnerLength() * $this->box->getInnerDepth();
223
    }
224
225
    /**
226
     * Get used volume of the packed box.
227
     *
228
     * @return int
229
     */
230 3
    public function getUsedVolume()
231
    {
232 3
        $volume = 0;
233
        /** @var PackedItem $item */
234 3
        foreach (clone $this->items as $item) {
235 3
            $volume += $item->getVolume();
236
        }
237
238 3
        return $volume;
239
    }
240
241
    /**
242
     * Get unused volume of the packed box.
243
     *
244
     * @return int
245
     */
246 1
    public function getUnusedVolume()
247
    {
248 1
        return $this->getInnerVolume() - $this->getUsedVolume();
249
    }
250
251
    /**
252
     * Get volume utilisation of the packed box.
253
     *
254
     * @return float
255
     */
256 12
    public function getVolumeUtilisation()
257
    {
258 12
        $itemVolume = 0;
259
260
        /** @var Item $item */
261 12
        foreach (clone $this->items as $item) {
262 12
            $itemVolume += $item->getVolume();
263
        }
264
265 12
        return round($itemVolume / $this->box->getInnerVolume() * 100, 1);
266
    }
267
268
    /**
269
     * @return PackedItemList
270
     */
271 47
    public function getPackedItems()
272
    {
273 47
        if (!$this->packedItemList instanceof PackedItemList) {
0 ignored issues
show
introduced by
$this->packedItemList is always a sub-type of DVDoug\BoxPacker\PackedItemList.
Loading history...
274
            throw new RuntimeException('No PackedItemList was set. Are you using the old constructor?');
0 ignored issues
show
Bug introduced by
The type DVDoug\BoxPacker\RuntimeException was not found. Did you mean RuntimeException? If so, make sure to prefix the type with \.
Loading history...
275
        }
276 47
        return $this->packedItemList;
277
    }
278
279
    /**
280
     * @param PackedItemList $packedItemList
281
     */
282 54
    public function setPackedItems(PackedItemList $packedItemList)
283
    {
284 54
        $this->packedItemList = $packedItemList;
285 54
    }
286
287
    /**
288
     * Legacy constructor.
289
     *
290
     * @deprecated
291
     *
292
     * @param Box      $box
293
     * @param ItemList $itemList
294
     * @param int      $remainingWidth
295
     * @param int      $remainingLength
296
     * @param int      $remainingDepth
297
     * @param int      $remainingWeight
298
     * @param int      $usedWidth
299
     * @param int      $usedLength
300
     * @param int      $usedDepth
301
     */
302 54
    public function __construct(
303
        Box $box,
304
        ItemList $itemList,
305
        $remainingWidth,
306
        $remainingLength,
307
        $remainingDepth,
308
        $remainingWeight,
309
        $usedWidth,
310
        $usedLength,
311
        $usedDepth
312
    ) {
313 54
        $this->box = $box;
314 54
        $this->items = $itemList;
315 54
        $this->remainingWidth = $remainingWidth;
316 54
        $this->remainingLength = $remainingLength;
317 54
        $this->remainingDepth = $remainingDepth;
318 54
        $this->remainingWeight = $remainingWeight;
319 54
        $this->usedWidth = $usedWidth;
320 54
        $this->usedLength = $usedLength;
321 54
        $this->usedDepth = $usedDepth;
322 54
    }
323
324
    /**
325
     * The constructor from v3.
326
     *
327
     * @param Box            $box
328
     * @param PackedItemList $packedItems
329
     *
330
     * @return self
331
     */
332 54
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
333
    {
334 54
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
335
        /** @var PackedItem $item */
336 54
        foreach (clone $packedItems as $item) {
337 54
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
338 54
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
339 54
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
340 54
            $weight += $item->getItem()->getWeight();
341
        }
342
343 54
        $packedBox = new self(
344 54
            $box,
345 54
            $packedItems->asItemList(),
346 54
            $box->getInnerWidth() - $maxWidth,
347 54
            $box->getInnerLength() - $maxLength,
348 54
            $box->getInnerDepth() - $maxDepth,
349 54
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
350
            $maxWidth,
351
            $maxLength,
352
            $maxDepth
353
        );
354 54
        $packedBox->setPackedItems($packedItems);
355
356 54
        return $packedBox;
357
    }
358
}
359