Completed
Push — dev-v3 ( 0f682d )
by Propa
02:36
created

Phone::unserialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 5
cp 0
crap 2
rs 9.4285
1
<?php namespace Propaganistas\LaravelPhone;
2
3
use Illuminate\Contracts\Support\Jsonable;
4
use Illuminate\Support\Arr;
5
use Illuminate\Support\Str;
6
use JsonSerializable;
7
use libphonenumber\NumberParseException;
8
use libphonenumber\PhoneNumberFormat;
9
use libphonenumber\PhoneNumberUtil;
10
use Propaganistas\LaravelPhone\Exceptions\PhoneCountryException;
11
use Propaganistas\LaravelPhone\Exceptions\PhoneFormatException;
12
use Propaganistas\LaravelPhone\Traits\ParsesCountries;
13
use Propaganistas\LaravelPhone\Traits\ParsesFormats;
14
use Propaganistas\LaravelPhone\Traits\ParsesTypes;
15
use Serializable;
16
17
class Phone implements Jsonable, JsonSerializable, Serializable
18
{
19
    use ParsesCountries,
20
        ParsesFormats,
21
        ParsesTypes;
22
23
    /**
24
     * The provided phone number.
25
     *
26
     * @var string
27
     */
28
    protected $number;
29
30
    /**
31
     * The provided phone countries.
32
     *
33
     * @var array
34
     */
35
    protected $countries = [];
36
37
    /**
38
     * @var \libphonenumber\PhoneNumberUtil
39
     */
40
    protected $lib;
41
42
    /**
43
     * Phone constructor.
44
     *
45
     * @param string $number
46
     */
47
    public function __construct($number)
48
    {
49
        $this->number = $number;
50
        $this->lib = PhoneNumberUtil::getInstance();
51
    }
52
53
    /**
54
     * Create a phone instance.
55
     *
56
     * @param string       $number
57
     * @param string|array $country
58
     * @return static
59
     */
60
    public static function make($number, $country = null)
61
    {
62
        $instance = new static($number);
63
64
        return $instance->ofCountry($country);
0 ignored issues
show
Bug introduced by
It seems like $country defined by parameter $country on line 60 can also be of type null; however, Propaganistas\LaravelPhone\Phone::ofCountry() does only seem to accept string|array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
65
    }
66
67
    /**
68
     * Set the country to which the phone number belongs to.
69
     *
70
     * @param string|array $country
71
     * @return $this
72
     */
73
    public function ofCountry($country)
74
    {
75
        $instance = clone $this;
76
        $instance->countries = $instance->parseCountries($country);
77
78
        return $instance;
79
    }
80
81
    /**
82
     * Format the phone number in international format.
83
     *
84
     * @return string
85
     */
86
    public function formatInternational()
87
    {
88
        return $this->format(PhoneNumberFormat::INTERNATIONAL);
89
    }
90
91
    /**
92
     * Format the phone number in national format.
93
     *
94
     * @return string
95
     */
96
    public function formatNational()
97
    {
98
        return $this->format(PhoneNumberFormat::NATIONAL);
99
    }
100
101
    /**
102
     * Format the phone number in E164 format.
103
     *
104
     * @return string
105
     */
106
    public function formatE164()
107
    {
108
        return $this->format(PhoneNumberFormat::E164);
109
    }
110
111
    /**
112
     * Format the phone number in RFC3966 format.
113
     *
114
     * @return string
115
     */
116
    public function formatRFC3966()
117
    {
118
        return $this->format(PhoneNumberFormat::RFC3966);
119
    }
120
121
    /**
122
     * Format the phone number in a given format.
123
     *
124
     * @param string $format
125
     * @return string
126
     */
127
    public function format($format)
128
    {
129
        if (! ($format = static::parseFormat($format))) {
130
            return $this->throwFormatException('Unknown format "' . (string) $format . '"');
131
        }
132
133
        $country = Arr::get($this->countries, 0);
134
135
        if (! $country && ! Str::startsWith($this->number, '+')) {
136
            return $this->throwFormatException('A country should be provided or the number should be in international format');
137
        }
138
139
        return $this->lib->format(
140
            $this->getPhoneNumberInstance(),
141
            $format
142
        );
143
    }
144
145
    /**
146
     * Format the phone number in a way that it can be dialled from the provided country.
147
     *
148
     * @param string $country
149
     * @return string
150
     */
151 View Code Duplication
    public function formatForCountry($country)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in 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...
152
    {
153
        if (! static::isCountryCode($country)) {
154
            return $this->throwCountryException($country);
155
        }
156
157
        return $this->lib->formatOutOfCountryCallingNumber(
158
            $this->getPhoneNumberInstance(),
159
            $country
160
        );
161
    }
162
163
    /**
164
     * Format the phone number in a way that it can be dialled from the provided country using a cellphone.
165
     *
166
     * @param string $country
167
     * @param bool   $removeFormatting
168
     * @return string
169
     */
170 View Code Duplication
    public function formatForMobileDialingInCountry($country, $removeFormatting = false)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in 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...
171
    {
172
        if (! static::isCountryCode($country)) {
173
            return $this->throwCountryException($country);
174
        }
175
176
        return $this->lib->formatNumberForMobileDialing(
177
            $this->getPhoneNumberInstance(),
178
            $country,
179
            $removeFormatting
180
        );
181
    }
182
183
    /**
184
     * Get the phone number's country.
185
     *
186
     * @return string
187
     */
188
    public function getCountry()
189
    {
190
        return $this->lib->getRegionCodeForNumber($this->getPhoneNumberInstance());
191
    }
192
193
    /**
194
     * Get the phone number's type.
195
     *
196
     * @param bool $asConstant
197
     * @return string|int
198
     */
199
    public function getType($asConstant = false)
200
    {
201
        $type = $this->lib->getNumberType($this->getPhoneNumberInstance());
202
203
        return $asConstant ? $type : array_search($type, static::$types);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $asConstant ? $type : ar...$type, static::$types); of type false|integer|string adds false to the return on line 203 which is incompatible with the return type documented by Propaganistas\LaravelPhone\Phone::getType of type integer|string. It seems like you forgot to handle an error condition.
Loading history...
204
    }
205
206
    /**
207
     * Get the PhoneNumber instance of the current number.
208
     *
209
     * @return \libphonenumber\PhoneNumber
210
     */
211
    public function getPhoneNumberInstance()
212
    {
213
        // Let's try each provided country.
214
        foreach ($this->countries as $country) {
215
            try {
216
                return $this->lib->parse($this->number, $country);
217
            } catch (NumberParseException $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
218
            }
219
        }
220
221
        // Otherwise let's try to autodetect the country if the number is in international format.
222
        if (Str::startsWith($this->number, '+')) {
223
            try {
224
                return $this->lib->parse($this->number, null);
225
            } catch (NumberParseException $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
226
            }
227
        }
228
229
        return $this->throwCountryException($this->number);
230
    }
231
232
    /**
233
     * Throw a IndeterminablePhoneCountryException.
234
     *
235
     * @param $message
236
     * @throws \Propaganistas\LaravelPhone\Exceptions\PhoneCountryException
237
     */
238
    protected function throwCountryException($message)
239
    {
240
        throw new PhoneCountryException($message);
241
    }
242
243
    /**
244
     * Throw a PhoneFormatException.
245
     *
246
     * @param string $message
247
     * @throws \Propaganistas\LaravelPhone\Exceptions\PhoneFormatException
248
     */
249
    protected function throwFormatException($message)
250
    {
251
        throw new PhoneFormatException($message);
252
    }
253
254
    /**
255
     * Convert the phone instance to JSON.
256
     *
257
     * @param  int $options
258
     * @return string
259
     */
260
    public function toJson($options = 0)
261
    {
262
        return json_encode($this->jsonSerialize(), $options);
263
    }
264
265
    /**
266
     * Convert the phone instance into something JSON serializable.
267
     *
268
     * @return string
269
     */
270
    public function jsonSerialize()
271
    {
272
        return $this->formatE164();
273
    }
274
275
    /**
276
     * Convert the phone instance into a string representation.
277
     *
278
     * @return string
279
     */
280
    public function serialize()
281
    {
282
        return $this->formatE164();
283
    }
284
285
    /**
286
     * Reconstructs the phone instance from a string representation.
287
     *
288
     * @param string $serialized
289
     */
290
    public function unserialize($serialized)
291
    {
292
        $this->number = $serialized;
293
        $this->countries = [];
294
    }
295
296
    /**
297
     * Convert the phone instance to a formatted number.
298
     *
299
     * @return string
300
     */
301
    public function __toString()
302
    {
303
        return $this->formatE164();
304
    }
305
}