Passed
Push — master ( f32aae...1aa831 )
by Misha
02:58
created

PhoneNumber::toString()   C

Complexity

Conditions 12
Paths 20

Size

Total Lines 37
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 27
c 3
b 0
f 0
dl 0
loc 37
rs 6.9666
cc 12
nc 20
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Communibase\Entity;
4
5
use Communibase\DataBag;
6
use libphonenumber\NumberParseException;
7
use libphonenumber\PhoneNumberUtil;
8
9
/**
10
 * @author Kingsquare ([email protected])
11
 * @copyright Copyright (c) Kingsquare BV (http://www.kingsquare.nl)
12
 */
13
class PhoneNumber
14
{
15
    /**
16
     * @var DataBag
17
     */
18
    protected $dataBag;
19
20
    private static $phoneNumberUtil;
21
22
    /**
23
     * PhoneNumber constructor.
24
     *
25
     * @param array $phoneNumberData
26
     */
27
    protected function __construct(array $phoneNumberData)
28
    {
29
        $this->dataBag = DataBag::create();
30
        if (empty($phoneNumberData['type'])) {
31
            $phoneNumberData['type'] = 'private';
32
        }
33
        $this->dataBag->addEntityData('phone', $phoneNumberData);
34
        self::$phoneNumberUtil = self::$phoneNumberUtil ?? PhoneNumberUtil::getInstance();
35
    }
36
37
    /**
38
     * @return static
39
     */
40
    public static function create()
41
    {
42
        return new static([]);
43
    }
44
45
    /**
46
     * @param array $phoneNumberData
47
     *
48
     * @return static
49
     */
50
    public static function fromPhoneNumberData(array $phoneNumberData = null)
51
    {
52
        if ($phoneNumberData === null) {
53
            $phoneNumberData = [];
54
        }
55
        return new static($phoneNumberData);
56
    }
57
58
    /**
59
     * @param string $phoneNumberString
60
     *
61
     * @return static
62
     */
63
    public static function fromString($phoneNumberString)
64
    {
65
        $phoneNumber = static::create();
66
        $phoneNumber->setPhoneNumber($phoneNumberString);
67
        return $phoneNumber;
68
    }
69
70
    /**
71
     * @param string $format defaults to 'c(a)s'
72
     * The following characters are recognized in the format parameter string:
73
     * <table><tr>
74
     * <td>Character&nbsp;</td><td>Description</td>
75
     * </tr><tr>
76
     * <td>c</td><td>countryCode</td>
77
     * </tr><tr>
78
     * <td>a</td><td>areaCode</td>
79
     * </tr><tr>
80
     * <td>s</td><td>subscriberNumber</td>
81
     * </tr>
82
     */
83
    public function toString(?string $format = 'c (a) s'): string
84
    {
85
        if ($format === null) {
86
            $format = 'c (a) s';
87
        }
88
        $countryCode = $this->dataBag->get('phone.countryCode');
89
        $areaCode = $this->dataBag->get('phone.areaCode');
90
        $subscriberNumber = $this->dataBag->get('phone.subscriberNumber');
91
        if (!empty($countryCode) && \strpos($countryCode, '+') !== 0) {
92
            $countryCode = '+' . $countryCode;
93
        }
94
95
        if (empty($areaCode) && empty($subscriberNumber)) {
96
            return '';
97
        }
98
        if (empty($areaCode)) {
99
            $areaCode = ''; // remove '0' values
100
            $format = (string)\preg_replace('/\(\s?a\s?\)\s?/', '', $format);
101
        }
102
        if (!empty($countryCode) && \strpos($format, 'c') !== false) {
103
            $areaCode = \ltrim($areaCode, '0');
104
        }
105
        return trim(
106
            (string)\preg_replace_callback(
107
                '![cas]!',
108
                static function (array $matches) use ($countryCode, $areaCode, $subscriberNumber) {
109
                    switch ($matches[0]) {
110
                        case 'c':
111
                            return $countryCode;
112
                        case 'a':
113
                            return $areaCode;
114
                        case 's':
115
                            return $subscriberNumber;
116
                    }
117
                    return '';
118
                },
119
                $format
120
            )
121
        );
122
    }
123
124
    public function __toString(): string
125
    {
126
        return $this->toString();
127
    }
128
129
    public function setPhoneNumber(string $value): void
130
    {
131
        try {
132
            $phoneNumber = self::$phoneNumberUtil->parse($value, 'NL');
133
            $countryCode = (string)($phoneNumber->getCountryCode() ?? 0);
134
            $nationalNumber = $phoneNumber->getNationalNumber();
135
            $split = \preg_match('/^(1[035]|2[0346]|3[03568]|4[03568]|5[0358]|7\d)/', $nationalNumber) === 1 ? 2 : 3;
136
            if (\strpos($nationalNumber, '6') === 0) {
137
                $split = 1;
138
            }
139
            $areaCode = \substr($nationalNumber, 0, $split);
140
            $subscriberNumber = \substr($nationalNumber, $split);
141
        } catch (NumberParseException $e) {
142
            $countryCode = '';
143
            $areaCode = '';
144
            $subscriberNumber = '';
145
        }
146
        $this->dataBag->set('phone.countryCode', $countryCode);
147
        $this->dataBag->set('phone.areaCode', $areaCode);
148
        $this->dataBag->set('phone.subscriberNumber', $subscriberNumber);
149
    }
150
151
    public function getState(): ?array
152
    {
153
        if (!array_filter([$this->dataBag->get('phone.areaCode'), $this->dataBag->get('phone.subscriberNumber')])) {
154
            return null;
155
        }
156
        return $this->dataBag->getState('phone');
157
    }
158
}
159