Passed
Pull Request — master (#452)
by
unknown
05:07 queued 03:31
created

PackedBox   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Test Coverage

Coverage 29.5%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 45
c 5
b 0
f 0
dl 0
loc 183
ccs 18
cts 61
cp 0.295
rs 10
wmc 25

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getVolumeUtilisation() 0 3 1
A getItemWeight() 0 3 1
A getBox() 0 3 1
A getInnerVolume() 0 3 1
A getItems() 0 3 1
A getUsedVolume() 0 3 1
A __construct() 0 6 3
A getWeight() 0 3 1
A getRemainingWeight() 0 3 1
A getUnusedVolume() 0 3 1
A getRemainingLength() 0 3 1
A getUsedWidth() 0 9 2
A getUsedDepth() 0 9 2
A generateVisualisationURL() 0 3 1
A getRemainingWidth() 0 3 1
A getRemainingDepth() 0 3 1
A jsonSerialize() 0 22 3
A getUsedLength() 0 9 2
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace DVDoug\BoxPacker;
10
11
use JsonSerializable;
12
13
use function iterator_to_array;
14
use function json_encode;
15
use function max;
16
use function round;
17
use function urlencode;
18
use function is_iterable;
19
20
/**
21
 * A "box" with items.
22
 */
23
class PackedBox implements JsonSerializable
24
{
25
    protected int $itemWeight = 0;
26
27
    protected readonly float $volumeUtilisation;
28
29
    /**
30
     * Get box used.
31
     */
32 22
    public function getBox(): Box
33
    {
34 22
        return $this->box;
35
    }
36
37
    /**
38
     * Get items packed.
39
     */
40 84
    public function getItems(): PackedItemList
0 ignored issues
show
Bug introduced by
The type DVDoug\BoxPacker\PackedItemList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
41
    {
42 84
        return $this->items;
43
    }
44
45
    /**
46
     * Get packed weight.
47
     *
48
     * @return int weight in grams
49
     */
50 4
    public function getWeight(): int
51
    {
52 4
        return $this->box->getEmptyWeight() + $this->getItemWeight();
53
    }
54
55
    /**
56
     * Get packed weight of the items only.
57
     *
58
     * @return int weight in grams
59
     */
60 4
    public function getItemWeight(): int
61
    {
62 4
        return $this->itemWeight;
63
    }
64
65
    /**
66
     * Get remaining width inside box for another item.
67
     */
68
    public function getRemainingWidth(): int
69
    {
70
        return $this->box->getInnerWidth() - $this->getUsedWidth();
71
    }
72
73
    /**
74
     * Get remaining length inside box for another item.
75
     */
76
    public function getRemainingLength(): int
77
    {
78
        return $this->box->getInnerLength() - $this->getUsedLength();
79
    }
80
81
    /**
82
     * Get remaining depth inside box for another item.
83
     */
84
    public function getRemainingDepth(): int
85
    {
86
        return $this->box->getInnerDepth() - $this->getUsedDepth();
87
    }
88
89
    /**
90
     * Used width inside box for packing items.
91
     */
92
    public function getUsedWidth(): int
93
    {
94
        $maxWidth = 0;
95
96
        foreach ($this->items as $item) {
97
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
98
        }
99
100
        return $maxWidth;
101
    }
102
103
    /**
104
     * Used length inside box for packing items.
105
     */
106
    public function getUsedLength(): int
107
    {
108
        $maxLength = 0;
109
110
        foreach ($this->items as $item) {
111
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
112
        }
113
114
        return $maxLength;
115
    }
116
117
    /**
118
     * Used depth inside box for packing items.
119
     */
120
    public function getUsedDepth(): int
121
    {
122
        $maxDepth = 0;
123
124
        foreach ($this->items as $item) {
125
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
126
        }
127
128
        return $maxDepth;
129
    }
130
131
    /**
132
     * Get remaining weight inside box for another item.
133
     */
134
    public function getRemainingWeight(): int
135
    {
136
        return $this->box->getMaxWeight() - $this->getWeight();
137
    }
138
139 84
    public function getInnerVolume(): int
140
    {
141 84
        return $this->box->getInnerWidth() * $this->box->getInnerLength() * $this->box->getInnerDepth();
142
    }
143
144
    /**
145
     * Get used volume of the packed box.
146
     */
147 84
    public function getUsedVolume(): int
148
    {
149 84
        return $this->items->getVolume();
150
    }
151
152
    /**
153
     * Get unused volume of the packed box.
154
     */
155
    public function getUnusedVolume(): int
156
    {
157
        return $this->getInnerVolume() - $this->getUsedVolume();
158
    }
159
160
    /**
161
     * Get volume utilisation of the packed box.
162
     */
163 16
    public function getVolumeUtilisation(): float
164
    {
165 16
        return $this->volumeUtilisation;
166
    }
167
168
    /**
169
     * Create a custom website visualiser URL for this packing.
170
     */
171
    public function generateVisualisationURL(): string
172
    {
173
        return 'https://boxpacker.io/en/master/visualiser.html?packing=' . urlencode(json_encode($this));
174
    }
175
176 84
    public function __construct(protected Box $box, protected PackedItemList $items)
177
    {
178 84
        foreach ($this->items as $item) {
179 82
            $this->itemWeight += $item->getItem()->getWeight();
180
        }
181 84
        $this->volumeUtilisation = round($this->getUsedVolume() / ($this->getInnerVolume() ?: 1) * 100, 1);
0 ignored issues
show
Bug introduced by
The property volumeUtilisation is declared read-only in DVDoug\BoxPacker\PackedBox.
Loading history...
182
    }
183
184
    public function jsonSerialize(): array
185
    {
186
        $userValues = [];
187
188
        if ($this->box instanceof JsonSerializable) {
189
            $userSerialisation = $this->box->jsonSerialize();
0 ignored issues
show
Bug introduced by
The method jsonSerialize() does not exist on DVDoug\BoxPacker\Box. It seems like you code against a sub-type of DVDoug\BoxPacker\Box such as DVDoug\BoxPacker\WorkingVolume or DVDoug\BoxPacker\Test\TestBox. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

189
            /** @scrutinizer ignore-call */ 
190
            $userSerialisation = $this->box->jsonSerialize();
Loading history...
190
            if (is_iterable($userSerialisation)) {
191
                $userValues = $userSerialisation;
192
            } else {
193
                $userValues = ['extra' => $userSerialisation];
194
            }
195
        }
196
197
        return [
198
            'box' => [
199
                ...$userValues,
200
                'reference' => $this->box->getReference(),
201
                'innerWidth' => $this->box->getInnerWidth(),
202
                'innerLength' => $this->box->getInnerLength(),
203
                'innerDepth' => $this->box->getInnerDepth(),
204
            ],
205
            'items' => iterator_to_array($this->items),
206
        ];
207
    }
208
}
209