Package   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 406
Duplicated Lines 1.23 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 5
loc 406
rs 8.439
wmc 47
lcom 1
cbo 6

27 Methods

Rating   Name   Duplication   Size   Complexity  
A setRerouteAddress() 0 5 1
A getRerouteAddress() 0 4 1
A addActivity() 0 9 2
A getActivity() 0 4 1
A setScheduledDeliveryTime() 0 5 1
A getScheduledDeliveryTime() 0 4 1
A setRescheduledDeliveryTime() 0 5 1
A getRescheduledDeliveryTime() 0 4 1
A setReturnToAddress() 0 5 1
A getReturnToAddress() 0 4 1
A setSignatureType() 0 5 1
A getSignatureType() 0 4 1
A setTrackingNumber() 0 5 1
A getTrackingNumber() 0 4 1
A addReferenceNumber() 0 9 2
A getReferenceNumbers() 0 4 1
A setWeight() 0 5 1
A setProductType() 0 5 1
A getProductType() 0 4 1
A addAccessorial() 0 9 2
A getAccessorials() 0 4 1
A setLocationAssured() 0 5 1
A getLocationAssured() 0 4 1
A isLocationAssured() 0 4 1
A isSignatureRequired() 0 4 1
A isAdultSignatureRequired() 0 4 1
F fromXml() 5 65 18

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Package 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Package, and based on these observations, apply Extract Interface, too.

1
<?php namespace SimpleUPS\Track\SmallPackage;
2
3
use \SimpleUPS\Address;
4
5
use \SimpleUPS\Weight;
6
7
use \SimpleUPS\Track\ReferenceNumber;
8
9
use \SimpleUPS\Track\SmallPackage\Activity;
10
11
/**
12
 * A package represents a box or item
13
 * @since 1.0
14
 */
15
class Package extends \SimpleUPS\Package
16
{
17
18
    private
19
        $SIGNATURE_REQUIRED_ADULT = 'A',
20
        $SIGNATURE_REQUIRED = 'S',
21
        $LOCATION_ASSURED = 1;
22
23
    private
24
        /* @var string $trackingNumber */
25
        $trackingNumber,
26
27
        /* @var Activity[] $activity */
28
        $activity,
29
        /* @var \DateTime $scheduledDeliveryTime */
30
        $scheduledDeliveryTime,
31
32
        /* @var \DateTime $rescheduledDeliveryTime */
33
        $rescheduledDeliveryTime,
34
        /* @var \SimpleUPS\Address $rerouteAddress */
35
        $rerouteAddress,
36
37
        /* @var \SimpleUPS\Address $returnToAddress */
38
        $returnToAddress,
39
        /* @var string $signatureType */
40
        $signatureType,
41
42
        /* @var ReferenceNumber[] $referenceNumbers */
43
        $referenceNumbers,
44
        /* @var ProductType $productType */
45
        $productType,
46
47
        /* @var integer $locationAssured */
48
        $locationAssured,
49
50
        /* @var Accessorial[] $accessorials */
51
        $accessorials;
52
53
    /**
54
     * @internal
55
     *
56
     * @param \SimpleUPS\Address $rerouteAddress
57
     *
58
     * @return Package
59
     */
60
    public function setRerouteAddress(Address $rerouteAddress)
61
    {
62
        $this->rerouteAddress = $rerouteAddress;
63
        return $this;
64
    }
65
66
    /**
67
     * Reroute address when an package has been rerouted
68
     * When a requester to intercept US50/PR package at the destination center at
69
     * any time before it has been delivered,
70
     * @return \SimpleUPS\Address
71
     */
72
    public function getRerouteAddress()
73
    {
74
        return $this->rerouteAddress;
75
    }
76
77
    /**
78
     * @internal
79
     *
80
     * @param Activity $activity
81
     *
82
     * @return Package
83
     */
84
    public function addActivity(Activity $activity)
85
    {
86
        if ($this->activity === null) {
87
            $this->activity = array();
88
        }
89
90
        $this->activity[] = $activity;
91
        return $this;
92
    }
93
94
    /**
95
     * @return Activity[]
96
     */
97
    public function getActivity()
98
    {
99
        return $this->activity;
100
    }
101
102
    /**
103
     * @internal
104
     *
105
     * @param \DateTime $scheduledDeliveryTime
106
     *
107
     * @return Package
108
     */
109
    public function setScheduledDeliveryTime(\DateTime $scheduledDeliveryTime)
110
    {
111
        $this->scheduledDeliveryTime = $scheduledDeliveryTime;
112
        return $this;
113
    }
114
115
    /**
116
     * Date shipment was originally scheduled for delivery.
117
     * @return \DateTime|null
118
     */
119
    public function getScheduledDeliveryTime()
120
    {
121
        return $this->scheduledDeliveryTime;
122
    }
123
124
    /**
125
     * @internal
126
     *
127
     * @param \DateTime $rescheduledDeliveryTime
128
     *
129
     * @return Package
130
     */
131
    public function setRescheduledDeliveryTime(\DateTime $rescheduledDeliveryTime)
132
    {
133
        $this->rescheduledDeliveryTime = $rescheduledDeliveryTime;
134
        return $this;
135
    }
136
137
    /**
138
     * The delivery is rescheduled to this date
139
     * @return \DateTime|null
140
     */
141
    public function getRescheduledDeliveryTime()
142
    {
143
        return $this->rescheduledDeliveryTime;
144
    }
145
146
    /**
147
     * @internal
148
     *
149
     * @param \SimpleUPS\Address $returnToAddress
150
     *
151
     * @return Package
152
     */
153
    public function setReturnToAddress(Address $returnToAddress)
154
    {
155
        $this->returnToAddress = $returnToAddress;
156
        return $this;
157
    }
158
159
    /**
160
     * If the package is returned, the address to whom it was returned
161
     * @return \SimpleUPS\Address|null
162
     */
163
    public function getReturnToAddress()
164
    {
165
        return $this->returnToAddress;
166
    }
167
168
    /**
169
     * @internal
170
     *
171
     * @param string $signatureType
172
     *
173
     * @return Package
174
     */
175
    public function setSignatureType($signatureType)
176
    {
177
        $this->signatureType = (string)$signatureType;
178
        return $this;
179
    }
180
181
    /**
182
     * @internal
183
     * @return string
184
     */
185
    public function getSignatureType()
186
    {
187
        return $this->signatureType;
188
    }
189
190
    /**
191
     * @internal
192
     *
193
     * @param string $trackingNumber
194
     *
195
     * @return Package
196
     */
197
    public function setTrackingNumber($trackingNumber)
198
    {
199
        $this->trackingNumber = (string)$trackingNumber;
200
        return $this;
201
    }
202
203
    /**
204
     * Tracking number
205
     * @return string
206
     */
207
    public function getTrackingNumber()
208
    {
209
        return $this->trackingNumber;
210
    }
211
212
    /**
213
     * @internal
214
     *
215
     * @param ReferenceNumber $referenceNumber
216
     *
217
     * @return Package
218
     */
219
    public function addReferenceNumber(ReferenceNumber $referenceNumber)
220
    {
221
        if ($this->referenceNumbers === null) {
222
            $this->referenceNumbers = array();
223
        }
224
225
        $this->referenceNumbers[] = $referenceNumber;
226
        return $this;
227
    }
228
229
    /**
230
     * Reference numbers
231
     * @return Package[]|null
232
     */
233
    public function getReferenceNumbers()
234
    {
235
        return $this->referenceNumbers;
236
    }
237
238
    /**
239
     * @internal
240
     *
241
     * @param Weight $weight
242
     *
243
     * @return Package
244
     */
245
    public function setWeight(Weight $weight)
246
    {
247
        parent::setWeight($weight);
248
        return $this;
249
    }
250
251
    /**
252
     * @internal
253
     *
254
     * @param ProductType $productType
255
     *
256
     * @return Package
257
     */
258
    public function setProductType(ProductType $productType)
259
    {
260
        $this->productType = $productType;
261
        return $this;
262
    }
263
264
    /**
265
     * The product type of product
266
     * @return ProductType
267
     */
268
    public function getProductType()
269
    {
270
        return $this->productType;
271
    }
272
273
    /**
274
     * @internal
275
     *
276
     * @param Accessorial $accessorial
277
     *
278
     * @return Package
279
     */
280
    public function addAccessorial(Accessorial $accessorial)
281
    {
282
        if ($this->accessorials === null) {
283
            $this->accessorials = array();
284
        }
285
286
        $this->accessorials[] = $accessorial;
287
        return $this;
288
    }
289
290
    /**
291
     * @return Accessorial[]
292
     */
293
    public function getAccessorials()
294
    {
295
        return $this->accessorials;
296
    }
297
298
    /**
299
     * @internal
300
     *
301
     * @param integer $locationAssured
302
     *
303
     * @return Package
304
     */
305
    public function setLocationAssured($locationAssured)
306
    {
307
        $this->locationAssured = (int)$locationAssured;
308
        return $this;
309
    }
310
311
    /**
312
     * @internal
313
     * @return integer
314
     */
315
    public function getLocationAssured()
316
    {
317
        return $this->locationAssured;
318
    }
319
320
    /**
321
     * Indication of Location Assured Service.
322
     * @return bool
323
     */
324
    public function isLocationAssured()
325
    {
326
        return $this->getLocationAssured() == $this->LOCATION_ASSURED;
327
    }
328
329
    /**
330
     * Does package require a signature for delivery
331
     * @return bool
332
     */
333
    public function isSignatureRequired()
334
    {
335
        return $this->getSignatureType() == $this->SIGNATURE_REQUIRED;
336
    }
337
338
    /**
339
     * Does package require an adult signature for delivery
340
     * @return bool
341
     */
342
    public function isAdultSignatureRequired()
343
    {
344
        return $this->getSignatureType() == $this->SIGNATURE_REQUIRED_ADULT;
345
    }
346
347
    /**
348
     * Create an address from XML.  SimpleXMLElement passed must have immediate children like AddressLine1, City, etc.
349
     * @internal
350
     *
351
     * @param \SimpleXMLElement $xml
352
     *
353
     * @return Package
354
     */
355
    public static function fromXml(\SimpleXMLElement $xml)
356
    {
357
        $package = new Package();
358
        $package->setIsResponse();
359
360
        if (isset($xml->TrackingNumber)) {
361
            $package->setTrackingNumber($xml->TrackingNumber);
362
        }
363
364
        if (isset($xml->RescheduledDeliveryDate) && isset($xml->RescheduledDeliveryTime)) {
365
            $package->setRescheduledDeliveryTime(
366
                new \DateTime(trim($xml->RescheduledDeliveryDate . ' ' . $xml->RescheduledDeliveryTime))
367
            );
368
        }
369
370 View Code Duplication
        if (isset($xml->ScheduledDeliveryDate) && isset($xml->ScheduledDeliveryTime)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
            $package->setScheduledDeliveryTime(
372
                new \DateTime(trim($xml->ScheduledDeliveryDate . ' ' . $xml->ScheduledDeliveryTime))
373
            );
374
        }
375
376
        if (isset($xml->Reroute->Address)) {
377
            $package->setRerouteAddress(Address::fromXml($xml->Reroute->Address));
378
        }
379
380
        if (isset($xml->ReturnTo->Address)) {
381
            $package->setReturnToAddress(Address::fromXml($xml->ReturnTo->Address));
382
        }
383
384
        if (isset($xml->PackageServiceOptions->SignatureRequired->Code)) {
385
            $package->setSignatureType($xml->PackageServiceOptions->SignatureRequired->Code);
386
        }
387
388
        if (isset($xml->PackageWeight)) {
389
            $package->setWeight(Weight::fromXml($xml->PackageWeight));
390
        }
391
392
        if (isset($xml->ReferenceNumber)) {
393
            foreach ($xml->ReferenceNumber as $referenceNumber) {
394
                $package->addReferenceNumber(ReferenceNumber::fromXml($referenceNumber));
395
            }
396
        }
397
398
        if (isset($xml->Activity)) {
399
            foreach ($xml->Activity as $activity) {
400
                $package->addActivity(Activity::fromXml($activity));
401
            }
402
        }
403
404
        if (isset($xml->ShipmentWeight)) {
405
            $package->setWeight(Weight::fromXml($xml->ShipmentWeight));
406
        }
407
408
        if (isset($xml->LocationAssured)) {
409
            $package->setLocationAssured($xml->LocationAssured);
410
        }
411
412
        if (isset($xml->Accessorial)) {
413
            foreach ($xml->Accessorial as $accessorial) {
414
                $package->addAccessorial(Accessorial::fromXml($accessorial));
415
            }
416
        }
417
418
        return $package;
419
    }
420
}