International   A
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 317
Duplicated Lines 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 42
eloc 106
dl 0
loc 317
rs 9.0399
c 3
b 1
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
B toXML() 0 56 9
A getParcelContents() 0 3 1
A setCustomsInfo() 0 3 1
A setProduct() 0 7 2
A setOptions() 0 3 1
A setParcelContents() 0 15 3
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 60 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
3
namespace Bpost\BpostApiClient\Bpost\Order\Box;
4
5
use Bpost\BpostApiClient\Bpost\Order\Box\CustomsInfo\CustomsInfo;
6
use Bpost\BpostApiClient\Bpost\Order\Box\International\ParcelContent;
7
use Bpost\BpostApiClient\Bpost\Order\Box\Option\Messaging;
8
use Bpost\BpostApiClient\Bpost\Order\Box\Option\Option;
9
use Bpost\BpostApiClient\Bpost\Order\Receiver;
10
use Bpost\BpostApiClient\Bpost\ProductConfiguration\Product;
11
use Bpost\BpostApiClient\Common\XmlHelper;
12
use Bpost\BpostApiClient\Exception\BpostLogicException\BpostInvalidLengthException;
13
use Bpost\BpostApiClient\Exception\BpostLogicException\BpostInvalidValueException;
14
use Bpost\BpostApiClient\Exception\BpostNotImplementedException;
15
use DomDocument;
16
use DomElement;
17
use DOMException;
18
use SimpleXMLElement;
19
20
/**
21
 * bPost International class
22
 *
23
 * @author    Tijs Verkoyen <[email protected]>
24
 *
25
 * @version   3.0.0
26
 *
27
 * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
28
 * @license   BSD License
29
 */
30
class International implements IBox
31
{
32
    /**
33
     * @var string
34
     */
35
    private $product;
36
37
    /**
38
     * @var array
39
     */
40
    private $options = array();
41
42
    /**
43
     * @var Receiver
44
     */
45
    private $receiver;
46
47
    /**
48
     * @var int
49
     */
50
    private $parcelWeight;
51
52
    /**
53
     * @var CustomsInfo
54
     */
55
    private $customsInfo;
56
57
    /**
58
     * Only for shipments outside Europe.
59
     * Might include from 1 to 10 “parcelContent”.
60
     *
61
     * @var array|ParcelContent[]
62
     */
63
    private $parcelContents = array();
64
65
    /**
66
     * @param CustomsInfo $customsInfo
67
     */
68
    public function setCustomsInfo($customsInfo)
69
    {
70
        $this->customsInfo = $customsInfo;
71
    }
72
73
    /**
74
     * @return CustomsInfo
75
     */
76
    public function getCustomsInfo()
77
    {
78
        return $this->customsInfo;
79
    }
80
81
    /**
82
     * @param Option[] $options
83
     */
84
    public function setOptions($options)
85
    {
86
        $this->options = $options;
87
    }
88
89
    /**
90
     * @return Option[]
91
     */
92
    public function getOptions()
93
    {
94
        return $this->options;
95
    }
96
97
    /**
98
     * @param Option $option
99
     */
100
    public function addOption(Option $option)
101
    {
102
        $this->options[] = $option;
103
    }
104
105
    /**
106
     * @param int $parcelWeight
107
     */
108
    public function setParcelWeight($parcelWeight)
109
    {
110
        $this->parcelWeight = $parcelWeight;
111
    }
112
113
    /**
114
     * @return int
115
     */
116
    public function getParcelWeight()
117
    {
118
        return $this->parcelWeight;
119
    }
120
121
    /**
122
     * @param string $product
123
     *
124
     * @throws BpostInvalidValueException
125
     */
126
    public function setProduct($product)
127
    {
128
        if (!in_array($product, self::getPossibleProductValues())) {
129
            throw new BpostInvalidValueException('product', $product, self::getPossibleProductValues());
130
        }
131
132
        $this->product = $product;
133
    }
134
135
    /**
136
     * @return string
137
     */
138
    public function getProduct()
139
    {
140
        return $this->product;
141
    }
142
143
    /**
144
     * @return array
145
     */
146
    public static function getPossibleProductValues()
147
    {
148
        return array(
149
            Product::PRODUCT_NAME_BPACK_WORLD_BUSINESS,
150
            Product::PRODUCT_NAME_BPACK_WORLD_EASY_RETURN,
151
            Product::PRODUCT_NAME_BPACK_WORLD_EXPRESS_PRO,
152
            Product::PRODUCT_NAME_BPACK_EUROPE_BUSINESS,
153
            Product::PRODUCT_NAME_BPACK_AT_BPOST_INTERNATIONAL,
154
        );
155
    }
156
157
    /**
158
     * @param Receiver $receiver
159
     */
160
    public function setReceiver($receiver)
161
    {
162
        $this->receiver = $receiver;
163
    }
164
165
    /**
166
     * @return Receiver
167
     */
168
    public function getReceiver()
169
    {
170
        return $this->receiver;
171
    }
172
173
    /**
174
     * @return array|ParcelContent[]
175
     */
176
    public function getParcelContents()
177
    {
178
        return $this->parcelContents;
179
    }
180
181
    /**
182
     * @param array|ParcelContent[] $parcelContents
183
     *
184
     * @return self
185
     *
186
     * @throws BpostInvalidValueException
187
     */
188
    public function setParcelContents(array $parcelContents)
189
    {
190
        foreach ($parcelContents as $parcelContent) {
191
            if (!$parcelContent instanceof ParcelContent) {
192
                throw new BpostInvalidValueException(
193
                    'parcelContents',
194
                    get_class($parcelContent),
195
                    array('Bpost\BpostApiClient\Bpost\Order\Box\International\ParcelContent')
196
                );
197
            }
198
199
            $this->addParcelContent($parcelContent);
200
        }
201
202
        return $this;
203
    }
204
205
    public function addParcelContent(ParcelContent $parcelContent)
206
    {
207
        $this->parcelContents[] = $parcelContent;
208
    }
209
210
    /**
211
     * Return the object as an array for usage in the XML
212
     *
213
     * @param DomDocument $document
214
     * @param string      $prefix
215
     *
216
     * @return DOMElement
217
     *
218
     * @throws DOMException
219
     */
220
    public function toXML(DOMDocument $document, $prefix = null)
221
    {
222
        $internationalBox = $document->createElement(XmlHelper::getPrefixedTagName('internationalBox', $prefix));
223
        $prefix = 'international';
224
        $international = $document->createElement(XmlHelper::getPrefixedTagName('international', $prefix));
225
        $internationalBox->appendChild($international);
226
227
        if ($this->getProduct() !== null) {
0 ignored issues
show
introduced by
The condition $this->getProduct() !== null is always true.
Loading history...
228
            $international->appendChild(
229
                $document->createElement(XmlHelper::getPrefixedTagName('product', $prefix), $this->getProduct())
230
            );
231
        }
232
233
        $options = $this->getOptions();
234
        if (!empty($options)) {
235
            $optionsElement = $document->createElement(XmlHelper::getPrefixedTagName('options', $prefix));
236
            foreach ($options as $option) {
237
                $optionsElement->appendChild(
238
                    $option->toXML($document, 'common')
239
                );
240
            }
241
            $international->appendChild($optionsElement);
242
        }
243
244
        if ($this->getReceiver() !== null) {
245
            $international->appendChild(
246
                $this->getReceiver()->toXML($document, $prefix)
247
            );
248
        }
249
250
        if ($this->getParcelWeight() !== null) {
0 ignored issues
show
introduced by
The condition $this->getParcelWeight() !== null is always true.
Loading history...
251
            $international->appendChild(
252
                $document->createElement(
253
                    XmlHelper::getPrefixedTagName('parcelWeight', $prefix),
254
                    $this->getParcelWeight()
255
                )
256
            );
257
        }
258
259
        if ($this->getCustomsInfo() !== null) {
260
            $international->appendChild(
261
                $this->getCustomsInfo()->toXML($document, $prefix)
262
            );
263
        }
264
265
        if ($this->getParcelContents()) {
266
            $parcelContents = $document->createElement(XmlHelper::getPrefixedTagName('parcelContents', $prefix));
267
            foreach ($this->getParcelContents() as $parcelContent) {
268
                $parcelContents->appendChild(
269
                    $parcelContent->toXML($document, $prefix)
270
                );
271
            }
272
            $international->appendChild($parcelContents);
273
        }
274
275
        return $internationalBox;
276
    }
277
278
    /**
279
     * @param SimpleXMLElement $xml
280
     *
281
     * @return International
282
     *
283
     * @throws BpostInvalidLengthException
284
     * @throws BpostInvalidValueException
285
     * @throws BpostNotImplementedException
286
     */
287
    public static function createFromXML(SimpleXMLElement $xml)
288
    {
289
        $international = new International();
290
291
        if (isset($xml->international->product) && $xml->international->product != '') {
292
            $international->setProduct(
293
                (string) $xml->international->product
294
            );
295
        }
296
        if (isset($xml->international->options)) {
297
            /** @var SimpleXMLElement $optionData */
298
            $options = $xml->international->options->children('http://schema.post.be/shm/deepintegration/v3/common');
299
            foreach ($options as $optionData) {
300
                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

300
                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...
301
                    case Messaging::MESSAGING_TYPE_INFO_DISTRIBUTED:
302
                    case Messaging::MESSAGING_TYPE_KEEP_ME_INFORMED:
303
                    case Messaging::MESSAGING_TYPE_INFO_REMINDER:
304
                    case Messaging::MESSAGING_TYPE_INFO_NEXT_DAY:
305
                        $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

305
                        $option = Messaging::createFromXML(/** @scrutinizer ignore-type */ $optionData);
Loading history...
306
                        break;
307
                    default:
308
                        $className = '\Bpost\BpostApiClient\Bpost\Order\Box\Option\\' . ucfirst($optionData->getName());
309
                        XmlHelper::assertMethodCreateFromXmlExists($className);
310
                        $option = call_user_func(
311
                            array($className, 'createFromXML'),
312
                            $optionData
313
                        );
314
                }
315
316
                $international->addOption($option);
317
            }
318
        }
319
        if (isset($xml->international->parcelWeight) && $xml->international->parcelWeight != '') {
320
            $international->setParcelWeight(
321
                (int) $xml->international->parcelWeight
322
            );
323
        }
324
        if (isset($xml->international->receiver)) {
325
            $receiverData = $xml->international->receiver->children(
326
                'http://schema.post.be/shm/deepintegration/v3/common'
327
            );
328
            $international->setReceiver(
329
                Receiver::createFromXML($receiverData)
330
            );
331
        }
332
        if (isset($xml->international->customsInfo)) {
333
            $international->setCustomsInfo(
334
                CustomsInfo::createFromXML($xml->international->customsInfo)
335
            );
336
        }
337
        if (isset($xml->international->parcelContents)) {
338
            /** @var SimpleXMLElement $optionData */
339
            $parcelContents = $xml->international->parcelContents->children('international', true);
340
            foreach ($parcelContents as $parcelContentXml) {
341
                $parcelContent = 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

341
                $parcelContent = ParcelContent::createFromXML(/** @scrutinizer ignore-type */ $parcelContentXml);
Loading history...
342
                $international->addParcelContent($parcelContent);
343
            }
344
        }
345
346
        return $international;
347
    }
348
}
349