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