PhoneNumber   F
last analyzed

Complexity

Total Complexity 76

Size/Duplication

Total Lines 603
Duplicated Lines 0 %

Test Coverage

Coverage 93.49%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 141
dl 0
loc 603
ccs 158
cts 169
cp 0.9349
rs 2.32
c 1
b 0
f 0
wmc 76

40 Methods

Rating   Name   Duplication   Size   Complexity  
A clearItalianLeadingZero() 0 4 1
A getExtension() 0 3 1
A getNumberOfLeadingZeros() 0 3 1
A getRawInput() 0 3 1
A hasItalianLeadingZero() 0 3 1
A isItalianLeadingZero() 0 3 1
A getCountryCode() 0 3 1
A setCountryCodeSource() 0 4 1
A hasCountryCode() 0 3 1
A getNationalNumber() 0 3 1
A hasExtension() 0 3 1
A setRawInput() 0 4 1
A hasNationalNumber() 0 3 1
A setPreferredDomesticCarrierCode() 0 4 1
A getCountryCodeSource() 0 3 1
A setNationalNumber() 0 4 1
A clearNationalNumber() 0 4 1
A setItalianLeadingZero() 0 4 1
A getPreferredDomesticCarrierCode() 0 3 1
A clearPreferredDomesticCarrierCode() 0 4 1
A clearRawInput() 0 4 1
A clearCountryCode() 0 4 1
A clearCountryCodeSource() 0 4 1
A hasPreferredDomesticCarrierCode() 0 3 1
A hasCountryCodeSource() 0 3 1
A hasRawInput() 0 3 1
A hasNumberOfLeadingZeros() 0 3 1
A clearExtension() 0 4 1
A setExtension() 0 4 1
A setCountryCode() 0 4 1
A setNumberOfLeadingZeros() 0 5 1
F equals() 0 20 23
C mergeFrom() 0 27 9
A clear() 0 11 1
A clearNumberOfLeadingZeros() 0 5 1
A __toString() 0 22 6
A serialize() 0 3 1
A __unserialize() 0 15 2
A __serialize() 0 11 1
A unserialize() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like PhoneNumber 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 PhoneNumber, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace libphonenumber;
4
5
class PhoneNumber implements \Serializable
6
{
7
    /**
8
     * The country calling code for this number, as defined by the International Telecommunication Union
9
     * (ITU). For example, this would be 1 for NANPA countries, and 33 for France.
10
     *
11
     * @var int|null
12
     */
13
    protected $countryCode;
14
    /**
15
     * National (significant) Number is defined in International Telecommunication Union (ITU)
16
     * Recommendation E.164. It is a language/country-neutral representation of a phone number at a
17
     * country level. For countries which have the concept of an "area code" or "national destination
18
     * code", this is included in the National (significant) Number. Although the ITU says the maximum
19
     * length should be 15, we have found longer numbers in some countries e.g. Germany.
20
     *
21
     * Note that the National (significant) Number does not contain the National(trunk) prefix.
22
     *
23
     * @var string|null
24
     */
25
    protected $nationalNumber;
26
    /**
27
     * Extension is not standardized in ITU recommendations, except for being defined as a series of
28
     * numbers with a maximum length of 40 digits. It is defined as a string here to accommodate for the
29
     * possible use of a leading zero in the extension (organizations have complete freedom to do so,
30
     * as there is no standard defined). However, only ASCII digits should be stored here.
31
     *
32
     * @var string|null
33
     */
34
    protected $extension;
35
    /**
36
     * In some countries, the national (significant) number starts with one or more "0"s without this
37
     * being a national prefix or trunk code of some kind. For example, the leading zero in the national
38
     * (significant) number of an Italian phone number indicates the number is a fixed-line number.
39
     * There have been plans to migrate fixed-line numbers to start with the digit two since December
40
     * 2000, but it has not happened yet. See http://en.wikipedia.org/wiki/%2B39 for more details.
41
     *
42
     * These fields can be safely ignored (there is no need to set them) for most countries. Some
43
     * limited number of countries behave like Italy - for these cases, if the leading zero(s) of a
44
     * number would be retained even when dialling internationally, set this flag to true, and also
45
     * set the number of leading zeros.
46
     *
47
     * Clients who use the parsing functionality of the i18n phone number libraries
48
     * will have these fields set if necessary automatically.
49
     *
50
     * @var bool|null
51
     */
52
    protected $italianLeadingZero;
53
    /**
54
     * This field is used to store the raw input string containing phone numbers before it was
55
     * canonicalized by the library. For example, it could be used to store alphanumerical numbers
56
     * such as "1-800-GOOG-411".
57
     *
58
     * @var string|null
59
     */
60
    protected $rawInput;
61
    /**
62
     * The source from which the country_code is derived. This is not set in the general parsing method,
63
     * but in the method that parses and keeps raw_input. New fields could be added upon request.
64
     *
65
     * @see CountryCodeSource
66
     *
67
     * This must be one of the CountryCodeSource constants.
68
     *
69
     * @var int|null
70
     */
71
    protected $countryCodeSource = CountryCodeSource::UNSPECIFIED;
72
    /**
73
     * The carrier selection code that is preferred when calling this phone number domestically. This
74
     * also includes codes that need to be dialed in some countries when calling from landlines to
75
     * mobiles or vice versa. For example, in Columbia, a "3" needs to be dialed before the phone number
76
     * itself when calling from a mobile phone to a domestic landline phone and vice versa.
77
     *
78
     * Note this is the "preferred" code, which means other codes may work as well.
79
     *
80
     * @var string|null
81
     */
82
    protected $preferredDomesticCarrierCode;
83
    /**
84
     * Whether this phone number has a number of leading zeros set.
85
     *
86
     * @var bool
87
     */
88
    protected $hasNumberOfLeadingZeros = false;
89
    /**
90
     * The number of leading zeros of this phone number.
91
     *
92
     * @var int
93
     */
94
    protected $numberOfLeadingZeros = 1;
95
96
    /**
97
     * Clears this phone number.
98
     *
99
     * This effectively resets this phone number to the state of a new instance.
100
     *
101
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
102
     */
103 12
    public function clear()
104
    {
105 12
        $this->clearCountryCode();
106 12
        $this->clearNationalNumber();
107 12
        $this->clearExtension();
108 12
        $this->clearItalianLeadingZero();
109 12
        $this->clearNumberOfLeadingZeros();
110 12
        $this->clearRawInput();
111 12
        $this->clearCountryCodeSource();
112 12
        $this->clearPreferredDomesticCarrierCode();
113 12
        return $this;
114
    }
115
116
    /**
117
     * Clears the country code of this phone number.
118
     *
119
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
120
     */
121 12
    public function clearCountryCode()
122
    {
123 12
        $this->countryCode = null;
124 12
        return $this;
125
    }
126
127
    /**
128
     * Clears the national number of this phone number.
129
     *
130
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
131
     */
132 12
    public function clearNationalNumber()
133
    {
134 12
        $this->nationalNumber = null;
135 12
        return $this;
136
    }
137
138
    /**
139
     * Clears the extension of this phone number.
140
     *
141
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
142
     */
143 13
    public function clearExtension()
144
    {
145 13
        $this->extension = null;
146 13
        return $this;
147
    }
148
149
    /**
150
     * Clears the italian leading zero information of this phone number.
151
     *
152
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
153
     */
154 13
    public function clearItalianLeadingZero()
155
    {
156 13
        $this->italianLeadingZero = null;
157 13
        return $this;
158
    }
159
160
    /**
161
     * Clears the number of leading zeros of this phone number.
162
     *
163
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
164
     */
165 12
    public function clearNumberOfLeadingZeros()
166
    {
167 12
        $this->hasNumberOfLeadingZeros = false;
168 12
        $this->numberOfLeadingZeros = 1;
169 12
        return $this;
170
    }
171
172
    /**
173
     * Clears the raw input of this phone number.
174
     *
175
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
176
     */
177 139
    public function clearRawInput()
178
    {
179 139
        $this->rawInput = null;
180 139
        return $this;
181
    }
182
183
    /**
184
     * Clears the country code source of this phone number.
185
     *
186
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
187
     */
188 138
    public function clearCountryCodeSource()
189
    {
190 138
        $this->countryCodeSource = CountryCodeSource::UNSPECIFIED;
191 138
        return $this;
192
    }
193
194
    /**
195
     * Clears the preferred domestic carrier code of this phone number.
196
     *
197
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
198
     */
199 138
    public function clearPreferredDomesticCarrierCode()
200
    {
201 138
        $this->preferredDomesticCarrierCode = null;
202 138
        return $this;
203
    }
204
205
    /**
206
     * Merges the information from another phone number into this phone number.
207
     *
208
     * @param PhoneNumber $other The phone number to copy.
209
     *
210
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
211
     */
212 9
    public function mergeFrom(PhoneNumber $other)
213
    {
214 9
        if ($other->hasCountryCode()) {
215 9
            $this->setCountryCode($other->getCountryCode());
216
        }
217 9
        if ($other->hasNationalNumber()) {
218 9
            $this->setNationalNumber($other->getNationalNumber());
219
        }
220 9
        if ($other->hasExtension()) {
221 1
            $this->setExtension($other->getExtension());
222
        }
223 9
        if ($other->hasItalianLeadingZero()) {
224 2
            $this->setItalianLeadingZero($other->isItalianLeadingZero());
225
        }
226 9
        if ($other->hasNumberOfLeadingZeros()) {
227 1
            $this->setNumberOfLeadingZeros($other->getNumberOfLeadingZeros());
228
        }
229 9
        if ($other->hasRawInput()) {
230
            $this->setRawInput($other->getRawInput());
231
        }
232 9
        if ($other->hasCountryCodeSource()) {
233
            $this->setCountryCodeSource($other->getCountryCodeSource());
234
        }
235 9
        if ($other->hasPreferredDomesticCarrierCode()) {
236
            $this->setPreferredDomesticCarrierCode($other->getPreferredDomesticCarrierCode());
237
        }
238 9
        return $this;
239
    }
240
241
    /**
242
     * Returns whether this phone number has a country code set.
243
     *
244
     * @return bool True if a country code is set, false otherwise.
245
     */
246 22
    public function hasCountryCode()
247
    {
248 22
        return $this->countryCode !== null;
249
    }
250
251
    /**
252
     * Returns the country code of this phone number.
253
     *
254
     * @return int|null The country code, or null if not set.
255
     */
256 3360
    public function getCountryCode()
257
    {
258 3360
        return $this->countryCode;
259
    }
260
261
    /**
262
     * Sets the country code of this phone number.
263
     *
264
     * @param int $value The country code.
265
     *
266
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
267
     */
268 3404
    public function setCountryCode($value)
269
    {
270 3404
        $this->countryCode = (int) $value;
271 3404
        return $this;
272
    }
273
274
    /**
275
     * Returns whether this phone number has a national number set.
276
     *
277
     * @return bool True if a national number is set, false otherwise.
278
     */
279 22
    public function hasNationalNumber()
280
    {
281 22
        return $this->nationalNumber !== null;
282
    }
283
284
    /**
285
     * Returns the national number of this phone number.
286
     *
287
     * @return string|null The national number, or null if not set.
288
     */
289 3172
    public function getNationalNumber()
290
    {
291 3172
        return $this->nationalNumber;
292
    }
293
294
    /**
295
     * Sets the national number of this phone number.
296
     *
297
     * @param string $value The national number.
298
     *
299
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
300
     */
301 3403
    public function setNationalNumber($value)
302
    {
303 3403
        $this->nationalNumber = (string) $value;
304 3403
        return $this;
305
    }
306
307
    /**
308
     * Returns whether this phone number has an extension set.
309
     *
310
     * @return bool True if an extension is set, false otherwise.
311
     */
312 2005
    public function hasExtension()
313
    {
314 2005
        return $this->extension !== null;
315
    }
316
317
    /**
318
     * Returns the extension of this phone number.
319
     *
320
     * @return string|null The extension, or null if not set.
321
     */
322 30
    public function getExtension()
323
    {
324 30
        return $this->extension;
325
    }
326
327
    /**
328
     * Sets the extension of this phone number.
329
     *
330
     * @param string $value The extension.
331
     *
332
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
333
     */
334 39
    public function setExtension($value)
335
    {
336 39
        $this->extension = (string) $value;
337 39
        return $this;
338
    }
339
340
    /**
341
     * Returns whether this phone number has the italian leading zero information set.
342
     *
343
     * @return bool
344
     */
345 1911
    public function hasItalianLeadingZero()
346
    {
347 1911
        return $this->italianLeadingZero !== null;
348
    }
349
350
    /**
351
     * Sets whether this phone number uses an italian leading zero.
352
     *
353
     * @param bool $value True to use italian leading zero, false otherwise.
354
     *
355
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
356
     */
357 238
    public function setItalianLeadingZero($value)
358
    {
359 238
        $this->italianLeadingZero = (bool) $value;
360 238
        return $this;
361
    }
362
363
    /**
364
     * Returns whether this phone number uses an italian leading zero.
365
     *
366
     * @return bool|null True if it uses an italian leading zero, false it it does not, null if not set.
367
     */
368 3163
    public function isItalianLeadingZero()
369
    {
370 3163
        return $this->italianLeadingZero;
371
    }
372
373
    /**
374
     * Returns whether this phone number has a number of leading zeros set.
375
     *
376
     * @return bool True if a number of leading zeros is set, false otherwise.
377
     */
378 1898
    public function hasNumberOfLeadingZeros()
379
    {
380 1898
        return $this->hasNumberOfLeadingZeros;
381
    }
382
383
    /**
384
     * Returns the number of leading zeros of this phone number.
385
     *
386
     * @return int The number of leading zeros.
387
     */
388 148
    public function getNumberOfLeadingZeros()
389
    {
390 148
        return $this->numberOfLeadingZeros;
391
    }
392
393
    /**
394
     * Sets the number of leading zeros of this phone number.
395
     *
396
     * @param int $value The number of leading zeros.
397
     *
398
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
399
     */
400 28
    public function setNumberOfLeadingZeros($value)
401
    {
402 28
        $this->hasNumberOfLeadingZeros = true;
403 28
        $this->numberOfLeadingZeros = (int) $value;
404 28
        return $this;
405
    }
406
407
    /**
408
     * Returns whether this phone number has a raw input.
409
     *
410
     * @return bool True if a raw input is set, false otherwise.
411
     */
412 24
    public function hasRawInput()
413
    {
414 24
        return $this->rawInput !== null;
415
    }
416
417
    /**
418
     * Returns the raw input of this phone number.
419
     *
420
     * @return string|null The raw input, or null if not set.
421
     */
422 39
    public function getRawInput()
423
    {
424 39
        return $this->rawInput;
425
    }
426
427
    /**
428
     * Sets the raw input of this phone number.
429
     *
430
     * @param string $value The raw input.
431
     *
432
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
433
     */
434 295
    public function setRawInput($value)
435
    {
436 295
        $this->rawInput = (string) $value;
437 295
        return $this;
438
    }
439
440
    /**
441
     * Returns whether this phone number has a country code source.
442
     *
443
     * @return bool True if a country code source is set, false otherwise.
444
     */
445 1914
    public function hasCountryCodeSource()
446
    {
447 1914
        return $this->countryCodeSource !== CountryCodeSource::UNSPECIFIED;
448
    }
449
450
    /**
451
     * Returns the country code source of this phone number.
452
     *
453
     * @return int|null A CountryCodeSource constant, or null if not set.
454
     */
455 105
    public function getCountryCodeSource()
456
    {
457 105
        return $this->countryCodeSource;
458
    }
459
460
    /**
461
     * Sets the country code source of this phone number.
462
     *
463
     * @param int $value A CountryCodeSource constant.
464
     *
465
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
466
     */
467 186
    public function setCountryCodeSource($value)
468
    {
469 186
        $this->countryCodeSource = (int) $value;
470 186
        return $this;
471
    }
472
473
    /**
474
     * Returns whether this phone number has a preferred domestic carrier code.
475
     *
476
     * @return bool True if a preferred domestic carrier code is set, false otherwise.
477
     */
478 1911
    public function hasPreferredDomesticCarrierCode()
479
    {
480 1911
        return $this->preferredDomesticCarrierCode !== null;
481
    }
482
483
    /**
484
     * Returns the preferred domestic carrier code of this phone number.
485
     *
486
     * @return string|null The preferred domestic carrier code, or null if not set.
487
     */
488 2
    public function getPreferredDomesticCarrierCode()
489
    {
490 2
        return $this->preferredDomesticCarrierCode;
491
    }
492
493
    /**
494
     * Sets the preferred domestic carrier code of this phone number.
495
     *
496
     * @param string $value The preferred domestic carrier code.
497
     *
498
     * @return PhoneNumber This PhoneNumber instance, for chaining method calls.
499
     */
500 6
    public function setPreferredDomesticCarrierCode($value)
501
    {
502 6
        $this->preferredDomesticCarrierCode = (string) $value;
503 6
        return $this;
504
    }
505
506
    /**
507
     * Returns whether this phone number is equal to another.
508
     *
509
     * @param PhoneNumber $other The phone number to compare.
510
     *
511
     * @return bool True if the phone numbers are equal, false otherwise.
512
     */
513 15
    public function equals(PhoneNumber $other)
514
    {
515 15
        $sameType = get_class($other) == get_class($this);
516 15
        $sameCountry = $this->hasCountryCode() == $other->hasCountryCode() &&
517 15
            (!$this->hasCountryCode() || $this->getCountryCode() == $other->getCountryCode());
518 15
        $sameNational = $this->hasNationalNumber() == $other->hasNationalNumber() &&
519 15
            (!$this->hasNationalNumber() || $this->getNationalNumber() == $other->getNationalNumber());
520 15
        $sameExt = $this->hasExtension() == $other->hasExtension() &&
521 15
            (!$this->hasExtension() || $this->getExtension() == $other->getExtension());
522 15
        $sameLead = $this->hasItalianLeadingZero() == $other->hasItalianLeadingZero() &&
523 15
            (!$this->hasItalianLeadingZero() || $this->isItalianLeadingZero() == $other->isItalianLeadingZero());
524 15
        $sameZeros = $this->getNumberOfLeadingZeros() == $other->getNumberOfLeadingZeros();
525 15
        $sameRaw = $this->hasRawInput() == $other->hasRawInput() &&
526 15
            (!$this->hasRawInput() || $this->getRawInput() == $other->getRawInput());
527 15
        $sameCountrySource = $this->hasCountryCodeSource() == $other->hasCountryCodeSource() &&
528 15
            (!$this->hasCountryCodeSource() || $this->getCountryCodeSource() == $other->getCountryCodeSource());
529 15
        $samePrefCar = $this->hasPreferredDomesticCarrierCode() == $other->hasPreferredDomesticCarrierCode() &&
530 14
            (!$this->hasPreferredDomesticCarrierCode() || $this->getPreferredDomesticCarrierCode(
531 15
                ) == $other->getPreferredDomesticCarrierCode());
532 15
        return $sameType && $sameCountry && $sameNational && $sameExt && $sameLead && $sameZeros && $sameRaw && $sameCountrySource && $samePrefCar;
533
    }
534
535
    /**
536
     * Returns a string representation of this phone number.
537
     * @return string
538
     */
539 1890
    public function __toString()
540
    {
541 1890
        $outputString = '';
542
543 1890
        $outputString .= 'Country Code: ' . $this->countryCode;
544 1890
        $outputString .= ' National Number: ' . $this->nationalNumber;
545 1890
        if ($this->hasItalianLeadingZero()) {
546 40
            $outputString .= ' Leading Zero(s): true';
547
        }
548 1890
        if ($this->hasNumberOfLeadingZeros()) {
549 4
            $outputString .= ' Number of leading zeros: ' . $this->numberOfLeadingZeros;
550
        }
551 1890
        if ($this->hasExtension()) {
552 1
            $outputString .= ' Extension: ' . $this->extension;
553
        }
554 1890
        if ($this->hasCountryCodeSource()) {
555
            $outputString .= ' Country Code Source: ' . $this->countryCodeSource;
556
        }
557 1890
        if ($this->hasPreferredDomesticCarrierCode()) {
558
            $outputString .= ' Preferred Domestic Carrier Code: ' . $this->preferredDomesticCarrierCode;
559
        }
560 1890
        return $outputString;
561
    }
562
563
    /**
564
     * @inheritDoc
565
     */
566
    public function serialize()
567
    {
568
        return serialize($this->__serialize());
569
    }
570
571 3
    public function __serialize()
572
    {
573
        return array(
574 3
            $this->countryCode,
575 3
            $this->nationalNumber,
576 3
            $this->extension,
577 3
            $this->italianLeadingZero,
578 3
            $this->numberOfLeadingZeros,
579 3
            $this->rawInput,
580 3
            $this->countryCodeSource,
581 3
            $this->preferredDomesticCarrierCode
582
        );
583
    }
584
585
    /**
586
     * @inheritDoc
587
     */
588
    public function unserialize($serialized)
589
    {
590
        $this->__unserialize(unserialize($serialized));
591
    }
592
593 3
    public function __unserialize($data)
594
    {
595
        list(
596 3
            $this->countryCode,
597 3
            $this->nationalNumber,
598 3
            $this->extension,
599 3
            $this->italianLeadingZero,
600 3
            $this->numberOfLeadingZeros,
601 3
            $this->rawInput,
602 3
            $this->countryCodeSource,
603 3
            $this->preferredDomesticCarrierCode
604
            ) = $data;
605
606 3
        if ($this->numberOfLeadingZeros > 1) {
607
            $this->hasNumberOfLeadingZeros = true;
608
        }
609 3
    }
610
}
611