Test Failed
Branch master (62528d)
by Zangra
14:14 queued 12:04
created

International   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 43
eloc 93
c 4
b 1
f 0
dl 0
loc 219
rs 8.96

17 Methods

Rating   Name   Duplication   Size   Complexity  
B toXML() 0 47 9
A getParcelContents() 0 3 1
A setCustomsInfo() 0 3 1
A setProduct() 0 6 2
A setOptions() 0 3 1
A setParcelContents() 0 13 4
A getReceiver() 0 3 1
A getPossibleProductValues() 0 8 1
A setParcelWeight() 0 3 1
A setReceiver() 0 3 1
A getProduct() 0 3 1
A addOption() 0 3 1
A getCustomsInfo() 0 3 1
A addParcelContent() 0 3 1
A getOptions() 0 3 1
A getParcelWeight() 0 3 1
C createFromXML() 0 48 15

How to fix   Complexity   

Complex Class

Complex classes like International often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use International, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
4
namespace Bpost\BpostApiClient\Bpost\Order\Box;
5
6
use Bpost\BpostApiClient\Bpost\Order\Box\CustomsInfo\CustomsInfo;
7
use Bpost\BpostApiClient\Bpost\Order\Box\International\ParcelContent;
8
use Bpost\BpostApiClient\Bpost\Order\Box\Option\Messaging;
9
use Bpost\BpostApiClient\Bpost\Order\Box\Option\Option;
10
use Bpost\BpostApiClient\Bpost\Order\Receiver;
11
use Bpost\BpostApiClient\Bpost\ProductConfiguration\Product;
12
use Bpost\BpostApiClient\Common\XmlHelper;
13
use Bpost\BpostApiClient\Exception\BpostLogicException\BpostInvalidLengthException;
14
use Bpost\BpostApiClient\Exception\BpostLogicException\BpostInvalidValueException;
15
use Bpost\BpostApiClient\Exception\BpostNotImplementedException;
16
use DOMDocument;
17
use DOMElement;
18
use DOMException;
19
use SimpleXMLElement;
20
21
/**
22
 * bPost International class
23
 *
24
 * @author    Tijs Verkoyen <[email protected]>
25
 *
26
 * @version   3.0.0
27
 *
28
 * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
29
 * @license   BSD License
30
 */
31
class International implements IBox
32
{
33
    private ?string $product = null;
34
35
    private array $options = [];
36
37
    private ?Receiver $receiver = null;
38
39
    private ?int $parcelWeight = null;
40
41
    private ?CustomsInfo $customsInfo = null;
42
43
    private array $parcelContents = [];
44
45
    public function setCustomsInfo(?CustomsInfo $customsInfo): void
46
    {
47
        $this->customsInfo = $customsInfo;
48
    }
49
50
    public function getCustomsInfo(): ?CustomsInfo
51
    {
52
        return $this->customsInfo;
53
    }
54
55
    public function setOptions(array $options): void
56
    {
57
        $this->options = $options;
58
    }
59
60
    public function getOptions(): array
61
    {
62
        return $this->options;
63
    }
64
65
    public function addOption(Option $option): void
66
    {
67
        $this->options[] = $option;
68
    }
69
70
    public function setParcelWeight(?int $parcelWeight): void
71
    {
72
        $this->parcelWeight = $parcelWeight;
73
    }
74
75
    public function getParcelWeight(): ?int
76
    {
77
        return $this->parcelWeight;
78
    }
79
80
    /**
81
     * @throws BpostInvalidValueException
82
     */
83
    public function setProduct(string $product): void
84
    {
85
        if (!in_array($product, self::getPossibleProductValues(), true)) {
86
            throw new BpostInvalidValueException('product', $product, self::getPossibleProductValues());
87
        }
88
        $this->product = $product;
89
    }
90
91
    public function getProduct(): ?string
92
    {
93
        return $this->product;
94
    }
95
96
    public static function getPossibleProductValues(): array
97
    {
98
        return [
99
            Product::PRODUCT_NAME_BPACK_WORLD_BUSINESS,
100
            Product::PRODUCT_NAME_BPACK_WORLD_EASY_RETURN,
101
            Product::PRODUCT_NAME_BPACK_WORLD_EXPRESS_PRO,
102
            Product::PRODUCT_NAME_BPACK_EUROPE_BUSINESS,
103
            Product::PRODUCT_NAME_BPACK_AT_BPOST_INTERNATIONAL,
104
        ];
105
    }
106
107
    public function setReceiver(?Receiver $receiver): void
108
    {
109
        $this->receiver = $receiver;
110
    }
111
112
    public function getReceiver(): ?Receiver
113
    {
114
        return $this->receiver;
115
    }
116
117
    public function getParcelContents(): array
118
    {
119
        return $this->parcelContents;
120
    }
121
122
    /**
123
     * @throws BpostInvalidValueException
124
     */
125
    public function setParcelContents(array $parcelContents): self
126
    {
127
        foreach ($parcelContents as $parcelContent) {
128
            if (!$parcelContent instanceof ParcelContent) {
129
                throw new BpostInvalidValueException(
130
                    'parcelContents',
131
                    is_object($parcelContent) ? get_class($parcelContent) : gettype($parcelContent),
132
                    ['Bpost\\BpostApiClient\\Bpost\\Order\\Box\\International\\ParcelContent']
133
                );
134
            }
135
            $this->addParcelContent($parcelContent);
136
        }
137
        return $this;
138
    }
139
140
    public function addParcelContent(ParcelContent $parcelContent): void
141
    {
142
        $this->parcelContents[] = $parcelContent;
143
    }
144
145
    /**
146
     * @throws DOMException
147
     */
148
    public function toXML(DOMDocument $document, ?string $prefix = null, ?string $type = null): DOMElement
149
    {
150
        $internationalBox = $document->createElement(XmlHelper::getPrefixedTagName('internationalBox', $prefix));
151
        $innerPrefix = 'international';
152
        $international = $document->createElement(XmlHelper::getPrefixedTagName('international', $innerPrefix));
153
        $internationalBox->appendChild($international);
154
155
        if ($this->product !== null) {
156
            $international->appendChild(
157
                $document->createElement(XmlHelper::getPrefixedTagName('product', $innerPrefix), $this->product)
158
            );
159
        }
160
161
        if (!empty($this->options)) {
162
            $optionsElement = $document->createElement(XmlHelper::getPrefixedTagName('options', $innerPrefix));
163
            foreach ($this->options as $option) {
164
                $optionsElement->appendChild($option->toXML($document, 'common'));
165
            }
166
            $international->appendChild($optionsElement);
167
        }
168
169
        if ($this->receiver !== null) {
170
            $international->appendChild($this->receiver->toXML($document, $innerPrefix));
171
        }
172
173
        if ($this->parcelWeight !== null) {
174
            $international->appendChild(
175
                $document->createElement(
176
                    XmlHelper::getPrefixedTagName('parcelWeight', $innerPrefix),
177
                    (string)$this->parcelWeight
178
                )
179
            );
180
        }
181
182
        if ($this->customsInfo !== null) {
183
            $international->appendChild($this->customsInfo->toXML($document, $innerPrefix));
184
        }
185
186
        if (!empty($this->parcelContents)) {
187
            $parcelContents = $document->createElement(XmlHelper::getPrefixedTagName('parcelContents', $innerPrefix));
188
            foreach ($this->parcelContents as $parcelContent) {
189
                $parcelContents->appendChild($parcelContent->toXML($document, $innerPrefix));
190
            }
191
            $international->appendChild($parcelContents);
192
        }
193
194
        return $internationalBox;
195
    }
196
197
    /**
198
     * @throws BpostInvalidLengthException
199
     * @throws BpostInvalidValueException
200
     * @throws BpostNotImplementedException
201
     */
202
    public static function createFromXML(SimpleXMLElement $xml): International
203
    {
204
        $international = new self();
205
206
        if (isset($xml->international->product) && (string)$xml->international->product !== '') {
207
            $international->setProduct((string)$xml->international->product);
208
        }
209
210
        if (isset($xml->international->options)) {
211
            $options = $xml->international->options->children('http://schema.post.be/shm/deepintegration/v3/common');
212
            foreach ($options as $optionData) {
213
                switch ($optionData->getName()) {
0 ignored issues
show
Bug introduced by
The method getName() does not exist on null. ( Ignorable by Annotation )

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

213
                switch ($optionData->/** @scrutinizer ignore-call */ getName()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
214
                    case Messaging::MESSAGING_TYPE_INFO_DISTRIBUTED:
215
                    case Messaging::MESSAGING_TYPE_KEEP_ME_INFORMED:
216
                    case Messaging::MESSAGING_TYPE_INFO_REMINDER:
217
                    case Messaging::MESSAGING_TYPE_INFO_NEXT_DAY:
218
                        $option = Messaging::createFromXML($optionData);
0 ignored issues
show
Bug introduced by
It seems like $optionData can also be of type null; however, parameter $xml of Bpost\BpostApiClient\Bpo...saging::createFromXML() does only seem to accept SimpleXMLElement, maybe add an additional type check? ( Ignorable by Annotation )

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

218
                        $option = Messaging::createFromXML(/** @scrutinizer ignore-type */ $optionData);
Loading history...
219
                        break;
220
                    default:
221
                        $className = '\\Bpost\\BpostApiClient\\Bpost\\Order\\Box\\Option\\' . ucfirst($optionData->getName());
222
                        XmlHelper::assertMethodCreateFromXmlExists($className);
223
                        $option = $className::createFromXML($optionData);
224
                }
225
                $international->addOption($option);
226
            }
227
        }
228
229
        if (isset($xml->international->parcelWeight) && (string)$xml->international->parcelWeight !== '') {
230
            $international->setParcelWeight((int)$xml->international->parcelWeight);
231
        }
232
233
        if (isset($xml->international->receiver)) {
234
            $receiverData = $xml->international->receiver->children('http://schema.post.be/shm/deepintegration/v3/common');
235
            $international->setReceiver(Receiver::createFromXML($receiverData));
236
        }
237
238
        if (isset($xml->international->customsInfo)) {
239
            $international->setCustomsInfo(CustomsInfo::createFromXML($xml->international->customsInfo));
240
        }
241
242
        if (isset($xml->international->parcelContents)) {
243
            $parcelContents = $xml->international->parcelContents->children('international', true);
244
            foreach ($parcelContents as $parcelContentXml) {
245
                $international->addParcelContent(ParcelContent::createFromXML($parcelContentXml));
0 ignored issues
show
Bug introduced by
It seems like $parcelContentXml can also be of type null; however, parameter $xml of Bpost\BpostApiClient\Bpo...ontent::createFromXML() does only seem to accept SimpleXMLElement, maybe add an additional type check? ( Ignorable by Annotation )

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

245
                $international->addParcelContent(ParcelContent::createFromXML(/** @scrutinizer ignore-type */ $parcelContentXml));
Loading history...
246
            }
247
        }
248
249
        return $international;
250
    }
251
}