Test Failed
Push — 2.x-dev ( 5e90af...eccc16 )
by Doug
03:16
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 4
    public function getBox()
104
    {
105 4
        return $this->box;
106
    }
107
108
    /**
109
     * Get items packed.
110
     *
111
     * @return ItemList
112
     */
113 29
    public function getItems()
114
    {
115 29
        return $this->items;
116
    }
117
118
    /**
119
     * Get packed weight.
120
     *
121
     * @return int weight in grams
122
     */
123 1
    public function getWeight()
124
    {
125 1
        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 2
    public function getItemWeight()
134
    {
135 2
        if (!is_null($this->itemWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->itemWeight) is always false.
Loading history...
136
            return $this->itemWeight;
137
        }
138 2
        $this->itemWeight = 0;
139
        /** @var Item $item */
140 2
        foreach (clone $this->items as $item) {
141 2
            $this->itemWeight += $item->getWeight();
142
        }
143
144 2
        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 1
    public function getUsedWidth()
183
    {
184 1
        return $this->usedWidth;
185
    }
186
187
    /**
188
     * Used length inside box for packing items.
189
     *
190
     * @return int
191
     */
192 1
    public function getUsedLength()
193
    {
194 1
        return $this->usedLength;
195
    }
196
197
    /**
198
     * Used depth inside box for packing items.
199
     *
200
     * @return int
201
     */
202 1
    public function getUsedDepth()
203
    {
204 1
        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 2
    public function getInnerVolume()
221
    {
222 2
        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 1
    public function getUsedVolume()
231
    {
232 1
        $volume = 0;
233
        /** @var PackedItem $item */
234 1
        foreach (clone $this->items as $item) {
235 1
            $volume += $item->getVolume();
236
        }
237
238 1
        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 2
    public function getVolumeUtilisation()
257
    {
258 2
        $itemVolume = 0;
259
260
        /** @var Item $item */
261 2
        foreach (clone $this->items as $item) {
262 2
            $itemVolume += $item->getVolume();
263
        }
264
265 2
        return round($itemVolume / $this->box->getInnerVolume() * 100, 1);
266
    }
267
268
    /**
269
     * @return PackedItemList
270
     */
271 8
    public function getPackedItems()
272
    {
273 8
        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 8
        return $this->packedItemList;
277
    }
278
279
    /**
280
     * @param PackedItemList $packedItemList
281
     */
282 31
    public function setPackedItems(PackedItemList $packedItemList)
283
    {
284 31
        $this->packedItemList = $packedItemList;
285 31
    }
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 31
    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 31
        $this->box = $box;
314 31
        $this->items = $itemList;
315 31
        $this->remainingWidth = $remainingWidth;
316 31
        $this->remainingLength = $remainingLength;
317 31
        $this->remainingDepth = $remainingDepth;
318 31
        $this->remainingWeight = $remainingWeight;
319 31
        $this->usedWidth = $usedWidth;
320 31
        $this->usedLength = $usedLength;
321 31
        $this->usedDepth = $usedDepth;
322 31
    }
323
324
    /**
325
     * The constructor from v3.
326
     *
327
     * @param Box            $box
328
     * @param PackedItemList $packedItems
329
     *
330
     * @return self
331
     */
332 31
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
333
    {
334 31
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
335
        /** @var PackedItem $item */
336 31
        foreach (clone $packedItems as $item) {
337 21
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
338 21
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
339 21
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
340 21
            $weight += $item->getItem()->getWeight();
341
        }
342
343 31
        $packedBox = new self(
344 31
            $box,
345 31
            $packedItems->asItemList(),
346 31
            $box->getInnerWidth() - $maxWidth,
347 31
            $box->getInnerLength() - $maxLength,
348 31
            $box->getInnerDepth() - $maxDepth,
349 31
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
350
            $maxWidth,
351
            $maxLength,
352
            $maxDepth
353
        );
354 31
        $packedBox->setPackedItems($packedItems);
355
356 31
        return $packedBox;
357
    }
358
}
359