Passed
Push — 1.x-dev ( 8f914b...081a6e )
by Doug
04:31
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 20
    public function getItems()
117
    {
118 20
        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 22
    public function setPackedItems(PackedItemList $packedItemList)
286
    {
287 22
        $this->packedItemList = $packedItemList;
288 22
    }
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 22
    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 22
        $this->box = $box;
317 22
        $this->items = $itemList;
318 22
        $this->remainingWidth = $remainingWidth;
319 22
        $this->remainingLength = $remainingLength;
320 22
        $this->remainingDepth = $remainingDepth;
321 22
        $this->remainingWeight = $remainingWeight;
322 22
        $this->usedWidth = $usedWidth;
323 22
        $this->usedLength = $usedLength;
324 22
        $this->usedDepth = $usedDepth;
325 22
    }
326
327
    /**
328
     * The constructor from v3.
329
     *
330
     * @param Box            $box
331
     * @param PackedItemList $packedItems
332
     *
333
     * @return self
334
     */
335 22
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
336
    {
337 22
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
338
        /** @var PackedItem $item */
339 22
        foreach (clone $packedItems as $item) {
340 22
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
341 22
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
342 22
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
343 22
            $weight += $item->getItem()->getWeight();
344
        }
345
346 22
        $packedBox = new self(
347 22
            $box,
348 22
            $packedItems->asItemList(),
349 22
            $box->getInnerWidth() - $maxWidth,
350 22
            $box->getInnerLength() - $maxLength,
351 22
            $box->getInnerDepth() - $maxDepth,
352 22
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
353 22
            $maxWidth,
354 22
            $maxLength,
355 22
            $maxDepth
356
        );
357 22
        $packedBox->setPackedItems($packedItems);
358
359 22
        return $packedBox;
360
    }
361
}
362