Passed
Push — master ( a9b8b9...9f3034 )
by Thomas
14:35
created

DBPhone::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
1
<?php
2
3
namespace LeKoala\PhoneNumber;
4
5
use libphonenumber\PhoneNumberFormat;
6
use libphonenumber\NumberParseException;
7
use SilverStripe\ORM\FieldType\DBVarchar;
8
use SilverStripe\Forms\FormField;
9
10
/**
11
 * Phone field type
12
 *
13
 * The internal value is stored in E164 (with country prefix and no space)
14
 *
15
 * @see https://github.com/giggsey/libphonenumber-for-php
16
 */
17
class DBPhone extends DBVarchar
18
{
19
    /**
20
     * @var array<string>
21
     */
22
    protected static $valid_formats = [
23
        'E164',
24
        'INTERNATIONAL',
25
        'NATIONAL',
26
        'RFC3966'
27
    ];
28
29
    /**
30
     * @var string
31
     */
32
    protected $country = null;
33
34
    /**
35
     * @param mixed $name
36
     * @param array<string,mixed> $options
37
     */
38
    public function __construct($name = null, $options = [])
39
    {
40
        // E164 specify it should be smaller than 15 chars
41
        parent::__construct($name, 16, $options);
42
    }
43
44
    /**
45
     * @param mixed $value
46
     * @param mixed $record
47
     * @param bool $markChanged
48
     * @return $this
49
     */
50
    public function setValue($value, $record = null, $markChanged = true)
51
    {
52
        if ($record && strpos((string)$value, '+') !== 0) {
53
            if ($record->CountryCode) {
54
                $value = $this->parseNumber($value, $record->CountryCode);
55
            }
56
        }
57
        return parent::setValue($value, $record, $markChanged);
58
    }
59
60
    /**
61
     * @return mixed
62
     */
63
    public function dataValue()
64
    {
65
        return $this->value;
66
    }
67
68
    /**
69
     * If the number is passed in an international format (e.g. +44 117 496 0123), then the region code is not needed, and can be null.
70
     * Failing that, the library will use the region code to work out the phone number based on rules loaded for that region.
71
     *
72
     * @param mixed $value
73
     * @param string $country
74
     * @return string|null|false Formatted number, null if empty but valid, or false if invalid
75
     */
76
    protected function parseNumber($value, $country = null)
77
    {
78
        // Skip empty values
79
        if (empty($value)) {
80
            return null;
81
        }
82
83
        // It's an international number, let the parser define the country
84
        if (strpos($value, '+') === 0) {
85
            $country = null;
86
        } else {
87
            // If no country and not international number, return value as is
88
            if (!$country) {
89
                return $value;
90
            }
91
            $country = strtoupper($country);
92
        }
93
        $util = PhoneHelper::getPhoneNumberUtil();
94
        try {
95
            $number = $util->parse($value, $country);
96
            $formattedValue = $util->format($number, PhoneNumberFormat::E164);
97
        } catch (NumberParseException $ex) {
98
            $formattedValue = $value;
99
        }
100
        return $formattedValue;
101
    }
102
103
    /**
104
     * @param mixed $title
105
     * @param mixed $params
106
     * @return FormField
107
     */
108
    public function scaffoldFormField($title = null, $params = null)
109
    {
110
        $field = CountryPhoneField::create($this->name, $title);
111
        return $field;
112
    }
113
114
    /**
115
     * @param int|null $format
116
     * @return string The number in requested format
117
     */
118
    public function Format($format = null)
119
    {
120
        if (!$this->value) {
121
            return '';
122
        }
123
        return PhoneHelper::formatPhoneNumber($this->value, $this->country, $format);
124
    }
125
126
    /**
127
     * Includes the country region code and start with a +
128
     * Eg: +441174960123
129
     *
130
     * @return string
131
     */
132
    public function E164()
133
    {
134
        return $this->Format(PhoneNumberFormat::E164);
135
    }
136
137
    public function Nice()
138
    {
139
        return $this->International();
140
    }
141
142
    /**
143
     * Same as E164 with spacing
144
     * Eg: +44 117 496 0123
145
     *
146
     * @return string
147
     */
148
    public function International()
149
    {
150
        return $this->Format(PhoneNumberFormat::INTERNATIONAL);
151
    }
152
153
    /**
154
     * With space and without country
155
     * Eg: 0117 496 0123
156
     *
157
     * @return string
158
     */
159
    public function National()
160
    {
161
        return $this->Format(PhoneNumberFormat::NATIONAL);
162
    }
163
164
    /**
165
     * Usable as URI
166
     * Eg: tel:+44-117-496-012
167
     *
168
     * @return string
169
     */
170
    public function Rfc3966()
171
    {
172
        return $this->Format(PhoneNumberFormat::RFC3966);
173
    }
174
175
    /**
176
     * @param ?string $country An ISO 3166-1 two letter country code (=> UPPERCASE).
177
     * @return boolean
178
     */
179
    public function isValid($country = null)
180
    {
181
        return PhoneHelper::validatePhoneNumber($this->value, $country);
182
    }
183
}
184