Completed
Push — 1.x-dev ( f03c49...17b59f )
by Doug
68:27 queued 64:38
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 8
    public function getBox()
107
    {
108 8
        return $this->box;
109
    }
110
111
    /**
112
     * Get items packed.
113
     *
114
     * @return ItemList
115
     */
116 31
    public function getItems()
117
    {
118 31
        return $this->items;
119
    }
120
121
    /**
122
     * Get packed weight.
123
     *
124
     * @return int weight in grams
125
     */
126 8
    public function getWeight()
127
    {
128 8
        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 9
    public function getItemWeight()
137
    {
138 9
        if (!is_null($this->itemWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->itemWeight) is always false.
Loading history...
139 7
            return $this->itemWeight;
140
        }
141 9
        $this->itemWeight = 0;
142
        /** @var Item $item */
143 9
        foreach (clone $this->items as $item) {
144 9
            $this->itemWeight += $item->getWeight();
145
        }
146
147 9
        return $this->itemWeight;
148
    }
149
150
    /**
151
     * Get remaining width inside box for another item.
152
     *
153
     * @return int
154
     */
155 2
    public function getRemainingWidth()
156
    {
157 2
        return $this->remainingWidth;
158
    }
159
160
    /**
161
     * Get remaining length inside box for another item.
162
     *
163
     * @return int
164
     */
165 2
    public function getRemainingLength()
166
    {
167 2
        return $this->remainingLength;
168
    }
169
170
    /**
171
     * Get remaining depth inside box for another item.
172
     *
173
     * @return int
174
     */
175 2
    public function getRemainingDepth()
176
    {
177 2
        return $this->remainingDepth;
178
    }
179
180
    /**
181
     * Used width inside box for packing items.
182
     *
183
     * @return int
184
     */
185 3
    public function getUsedWidth()
186
    {
187 3
        return $this->usedWidth;
188
    }
189
190
    /**
191
     * Used length inside box for packing items.
192
     *
193
     * @return int
194
     */
195 3
    public function getUsedLength()
196
    {
197 3
        return $this->usedLength;
198
    }
199
200
    /**
201
     * Used depth inside box for packing items.
202
     *
203
     * @return int
204
     */
205 3
    public function getUsedDepth()
206
    {
207 3
        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 8
    public function getUsedVolume()
234
    {
235 8
        $volume = 0;
236
        /** @var PackedItem $item */
237 8
        foreach (clone $this->items as $item) {
238 8
            $volume += $item->getVolume();
239
        }
240
241 8
        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 8
    public function getVolumeUtilisation()
260
    {
261 8
        $itemVolume = 0;
262
263
        /** @var Item $item */
264 8
        foreach (clone $this->items as $item) {
265 8
            $itemVolume += $item->getVolume();
266
        }
267
268 8
        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 33
    public function setPackedItems(PackedItemList $packedItemList)
286
    {
287 33
        $this->packedItemList = $packedItemList;
288 33
    }
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 33
    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 33
        $this->box = $box;
317 33
        $this->items = $itemList;
318 33
        $this->remainingWidth = $remainingWidth;
319 33
        $this->remainingLength = $remainingLength;
320 33
        $this->remainingDepth = $remainingDepth;
321 33
        $this->remainingWeight = $remainingWeight;
322 33
        $this->usedWidth = $usedWidth;
323 33
        $this->usedLength = $usedLength;
324 33
        $this->usedDepth = $usedDepth;
325 33
    }
326
327
    /**
328
     * The constructor from v3.
329
     *
330
     * @param Box            $box
331
     * @param PackedItemList $packedItems
332
     *
333
     * @return self
334
     */
335 33
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
336
    {
337 33
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
338
        /** @var PackedItem $item */
339 33
        foreach (clone $packedItems as $item) {
340 33
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
341 33
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
342 33
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
343 33
            $weight += $item->getItem()->getWeight();
344
        }
345
346 33
        $packedBox = new self(
347 33
            $box,
348 33
            $packedItems->asItemList(),
349 33
            $box->getInnerWidth() - $maxWidth,
350 33
            $box->getInnerLength() - $maxLength,
351 33
            $box->getInnerDepth() - $maxDepth,
352 33
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
353
            $maxWidth,
354
            $maxLength,
355
            $maxDepth
356
        );
357 33
        $packedBox->setPackedItems($packedItems);
358
359 33
        return $packedBox;
360
    }
361
}
362